mirror of
https://github.com/intel/llvm.git
synced 2026-01-18 07:57:36 +08:00
Parsing/Sema for OMPAlignedClause.
llvm-svn: 209816
This commit is contained in:
@@ -2366,6 +2366,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
TraverseStmt(C->getAlignment());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
|
||||
@@ -764,6 +764,91 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief This represents clause 'aligned' in the '#pragma omp ...'
|
||||
/// directives.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp simd aligned(a,b : 8)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp simd' has clause 'aligned'
|
||||
/// with variables 'a', 'b' and alignment '8'.
|
||||
///
|
||||
class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
|
||||
friend class OMPClauseReader;
|
||||
/// \brief Location of ':'.
|
||||
SourceLocation ColonLoc;
|
||||
|
||||
/// \brief Sets the alignment for clause.
|
||||
void setAlignment(Expr *A) { *varlist_end() = A; }
|
||||
|
||||
/// \brief Build 'aligned' clause with given number of variables \a NumVars.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param ColonLoc Location of ':'.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
/// \param NumVars Number of variables.
|
||||
///
|
||||
OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc, SourceLocation EndLoc,
|
||||
unsigned NumVars)
|
||||
: OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
|
||||
EndLoc, NumVars),
|
||||
ColonLoc(ColonLoc) {}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
/// \param NumVars Number of variables.
|
||||
///
|
||||
explicit OMPAlignedClause(unsigned NumVars)
|
||||
: OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
|
||||
SourceLocation(), SourceLocation(),
|
||||
NumVars),
|
||||
ColonLoc(SourceLocation()) {}
|
||||
|
||||
public:
|
||||
/// \brief Creates clause with a list of variables \a VL and alignment \a A.
|
||||
///
|
||||
/// \param C AST Context.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param ColonLoc Location of ':'.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
/// \param VL List of references to the variables.
|
||||
/// \param A Alignment.
|
||||
static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> VL,
|
||||
Expr *A);
|
||||
|
||||
/// \brief Creates an empty clause with the place for \a NumVars variables.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \param NumVars Number of variables.
|
||||
///
|
||||
static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
|
||||
|
||||
/// \brief Sets the location of ':'.
|
||||
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
|
||||
/// \brief Returns the location of ':'.
|
||||
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||
|
||||
/// \brief Returns alignment.
|
||||
Expr *getAlignment() { return *varlist_end(); }
|
||||
/// \brief Returns alignment.
|
||||
const Expr *getAlignment() const { return *varlist_end(); }
|
||||
|
||||
StmtRange children() {
|
||||
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
|
||||
reinterpret_cast<Stmt **>(varlist_end() + 1));
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_aligned;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
|
||||
///
|
||||
/// \code
|
||||
|
||||
@@ -2387,6 +2387,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
TraverseStmt(C->getAlignment());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
|
||||
@@ -6954,6 +6954,12 @@ def err_omp_linear_expected_int_or_ptr : Error<
|
||||
def warn_omp_linear_step_zero : Warning<
|
||||
"zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
|
||||
InGroup<OpenMPClauses>;
|
||||
def err_omp_aligned_expected_array_or_ptr : Error<
|
||||
"argument of aligned clause should be array"
|
||||
"%select{ or pointer|, pointer, reference to array or reference to pointer}1"
|
||||
", not %0">;
|
||||
def err_omp_aligned_twice : Error<
|
||||
"a variable cannot appear in more than one aligned clause">;
|
||||
def err_omp_local_var_in_threadprivate_init : Error<
|
||||
"variable with local storage in initial value of threadprivate variable">;
|
||||
} // end of OpenMP category
|
||||
|
||||
@@ -47,6 +47,7 @@ OPENMP_CLAUSE(private, OMPPrivateClause)
|
||||
OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
|
||||
OPENMP_CLAUSE(shared, OMPSharedClause)
|
||||
OPENMP_CLAUSE(linear, OMPLinearClause)
|
||||
OPENMP_CLAUSE(aligned, OMPAlignedClause)
|
||||
OPENMP_CLAUSE(copyin, OMPCopyinClause)
|
||||
OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
|
||||
|
||||
@@ -63,6 +64,7 @@ OPENMP_PARALLEL_CLAUSE(copyin)
|
||||
// FIXME: more clauses allowed for directive 'omp simd'.
|
||||
OPENMP_SIMD_CLAUSE(private)
|
||||
OPENMP_SIMD_CLAUSE(linear)
|
||||
OPENMP_SIMD_CLAUSE(aligned)
|
||||
OPENMP_SIMD_CLAUSE(safelen)
|
||||
OPENMP_SIMD_CLAUSE(collapse)
|
||||
|
||||
|
||||
@@ -7383,6 +7383,13 @@ public:
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'aligned' clause.
|
||||
OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
|
||||
Expr *Alignment,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'copyin' clause.
|
||||
OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
|
||||
@@ -1214,6 +1214,28 @@ OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
|
||||
return new (Mem) OMPLinearClause(NumVars);
|
||||
}
|
||||
|
||||
OMPAlignedClause *
|
||||
OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
|
||||
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
|
||||
llvm::alignOf<Expr *>()) +
|
||||
sizeof(Expr *) * (VL.size() + 1));
|
||||
OMPAlignedClause *Clause = new (Mem)
|
||||
OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
|
||||
Clause->setVarRefs(VL);
|
||||
Clause->setAlignment(A);
|
||||
return Clause;
|
||||
}
|
||||
|
||||
OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
|
||||
unsigned NumVars) {
|
||||
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
|
||||
llvm::alignOf<Expr *>()) +
|
||||
sizeof(Expr *) * (NumVars + 1));
|
||||
return new (Mem) OMPAlignedClause(NumVars);
|
||||
}
|
||||
|
||||
OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
|
||||
@@ -677,6 +677,18 @@ void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
|
||||
}
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
|
||||
if (!Node->varlist_empty()) {
|
||||
OS << "aligned";
|
||||
VisitOMPClauseList(Node, '(');
|
||||
if (Node->getAlignment() != nullptr) {
|
||||
OS << ": ";
|
||||
Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
|
||||
if (!Node->varlist_empty()) {
|
||||
OS << "copyin";
|
||||
|
||||
@@ -308,6 +308,10 @@ void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
Profiler->VisitStmt(C->getStep());
|
||||
}
|
||||
void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
Profiler->VisitStmt(C->getAlignment());
|
||||
}
|
||||
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
||||
case OMPC_firstprivate:
|
||||
case OMPC_shared:
|
||||
case OMPC_linear:
|
||||
case OMPC_aligned:
|
||||
case OMPC_copyin:
|
||||
break;
|
||||
}
|
||||
@@ -125,6 +126,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
||||
case OMPC_firstprivate:
|
||||
case OMPC_shared:
|
||||
case OMPC_linear:
|
||||
case OMPC_aligned:
|
||||
case OMPC_copyin:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
|
||||
/// clause:
|
||||
/// if-clause | num_threads-clause | safelen-clause | default-clause |
|
||||
/// private-clause | firstprivate-clause | shared-clause | linear-clause |
|
||||
/// collapse-clause
|
||||
/// aligned-clause | collapse-clause
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind, bool FirstClause) {
|
||||
@@ -304,6 +304,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||
case OMPC_firstprivate:
|
||||
case OMPC_shared:
|
||||
case OMPC_linear:
|
||||
case OMPC_aligned:
|
||||
case OMPC_copyin:
|
||||
Clause = ParseOpenMPVarListClause(CKind);
|
||||
break;
|
||||
@@ -400,6 +401,8 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
|
||||
/// 'shared' '(' list ')'
|
||||
/// linear-clause:
|
||||
/// 'linear' '(' list [ ':' linear-step ] ')'
|
||||
/// aligned-clause:
|
||||
/// 'aligned' '(' list [ ':' alignment ] ')'
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
@@ -413,7 +416,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
|
||||
|
||||
SmallVector<Expr *, 5> Vars;
|
||||
bool IsComma = true;
|
||||
const bool MayHaveTail = (Kind == OMPC_linear);
|
||||
const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
|
||||
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
|
||||
Tok.isNot(tok::annot_pragma_openmp_end))) {
|
||||
ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
|
||||
@@ -435,7 +438,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
|
||||
Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind);
|
||||
}
|
||||
|
||||
// Parse ':' linear-step
|
||||
// Parse ':' linear-step (or ':' alignment).
|
||||
Expr *TailExpr = nullptr;
|
||||
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
|
||||
if (MustHaveTail) {
|
||||
|
||||
@@ -57,20 +57,23 @@ private:
|
||||
DeclRefExpr *RefExpr;
|
||||
};
|
||||
typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
|
||||
typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
|
||||
|
||||
struct SharingMapTy {
|
||||
DeclSAMapTy SharingMap;
|
||||
AlignedMapTy AlignedMap;
|
||||
DefaultDataSharingAttributes DefaultAttr;
|
||||
OpenMPDirectiveKind Directive;
|
||||
DeclarationNameInfo DirectiveName;
|
||||
Scope *CurScope;
|
||||
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
|
||||
Scope *CurScope)
|
||||
: SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
|
||||
DirectiveName(std::move(Name)), CurScope(CurScope) {}
|
||||
: SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
|
||||
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope) {
|
||||
}
|
||||
SharingMapTy()
|
||||
: SharingMap(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown),
|
||||
DirectiveName(), CurScope(nullptr) {}
|
||||
: SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
|
||||
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr) {}
|
||||
};
|
||||
|
||||
typedef SmallVector<SharingMapTy, 64> StackTy;
|
||||
@@ -99,6 +102,11 @@ public:
|
||||
Stack.pop_back();
|
||||
}
|
||||
|
||||
/// \brief If 'aligned' declaration for given variable \a D was not seen yet,
|
||||
/// add it and return NULL; otherwise return previous occurence's expression
|
||||
/// for diagnostics.
|
||||
DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
|
||||
|
||||
/// \brief Adds explicit data sharing attribute to the specified declaration.
|
||||
void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
|
||||
|
||||
@@ -242,6 +250,20 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
|
||||
return getDSA(std::next(Iter), D);
|
||||
}
|
||||
|
||||
DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
|
||||
assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
|
||||
auto It = Stack.back().AlignedMap.find(D);
|
||||
if (It == Stack.back().AlignedMap.end()) {
|
||||
assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
|
||||
Stack.back().AlignedMap[D] = NewDE;
|
||||
return nullptr;
|
||||
} else {
|
||||
assert(It->second && "Unexpected nullptr expr in the aligned map");
|
||||
return It->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
|
||||
if (A == OMPC_threadprivate) {
|
||||
Stack[0].SharingMap[D].Attributes = A;
|
||||
@@ -855,6 +877,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
||||
case OMPC_firstprivate:
|
||||
case OMPC_shared:
|
||||
case OMPC_linear:
|
||||
case OMPC_aligned:
|
||||
case OMPC_copyin:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_unknown:
|
||||
@@ -1025,6 +1048,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
|
||||
case OMPC_firstprivate:
|
||||
case OMPC_shared:
|
||||
case OMPC_linear:
|
||||
case OMPC_aligned:
|
||||
case OMPC_copyin:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_unknown:
|
||||
@@ -1128,6 +1152,10 @@ Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> VarList,
|
||||
Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
|
||||
ColonLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_aligned:
|
||||
Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
|
||||
ColonLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_copyin:
|
||||
Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
@@ -1641,6 +1669,81 @@ OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
|
||||
Vars, StepExpr);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPAlignedClause(
|
||||
ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
|
||||
|
||||
SmallVector<Expr *, 8> Vars;
|
||||
for (auto &RefExpr : VarList) {
|
||||
assert(RefExpr && "NULL expr in OpenMP aligned clause.");
|
||||
if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
|
||||
// It will be analyzed later.
|
||||
Vars.push_back(RefExpr);
|
||||
continue;
|
||||
}
|
||||
|
||||
SourceLocation ELoc = RefExpr->getExprLoc();
|
||||
// OpenMP [2.1, C/C++]
|
||||
// A list item is a variable name.
|
||||
DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
|
||||
if (!DE || !isa<VarDecl>(DE->getDecl())) {
|
||||
Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
|
||||
VarDecl *VD = cast<VarDecl>(DE->getDecl());
|
||||
|
||||
// OpenMP [2.8.1, simd construct, Restrictions]
|
||||
// The type of list items appearing in the aligned clause must be
|
||||
// array, pointer, reference to array, or reference to pointer.
|
||||
QualType QType = DE->getType()
|
||||
.getNonReferenceType()
|
||||
.getUnqualifiedType()
|
||||
.getCanonicalType();
|
||||
const Type *Ty = QType.getTypePtrOrNull();
|
||||
if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
|
||||
!Ty->isPointerType())) {
|
||||
Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
|
||||
<< QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
|
||||
bool IsDecl =
|
||||
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
|
||||
Diag(VD->getLocation(),
|
||||
IsDecl ? diag::note_previous_decl : diag::note_defined_here)
|
||||
<< VD;
|
||||
continue;
|
||||
}
|
||||
|
||||
// OpenMP [2.8.1, simd construct, Restrictions]
|
||||
// A list-item cannot appear in more than one aligned clause.
|
||||
if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
|
||||
Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
|
||||
Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
|
||||
<< getOpenMPClauseName(OMPC_aligned);
|
||||
continue;
|
||||
}
|
||||
|
||||
Vars.push_back(DE);
|
||||
}
|
||||
|
||||
// OpenMP [2.8.1, simd construct, Description]
|
||||
// The parameter of the aligned clause, alignment, must be a constant
|
||||
// positive integer expression.
|
||||
// If no optional parameter is specified, implementation-defined default
|
||||
// alignments for SIMD instructions on the target platforms are assumed.
|
||||
if (Alignment != nullptr) {
|
||||
ExprResult AlignResult =
|
||||
VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
|
||||
if (AlignResult.isInvalid())
|
||||
return nullptr;
|
||||
Alignment = AlignResult.get();
|
||||
}
|
||||
if (Vars.empty())
|
||||
return nullptr;
|
||||
|
||||
return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
|
||||
EndLoc, Vars, Alignment);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
|
||||
@@ -1419,6 +1419,19 @@ public:
|
||||
ColonLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new OpenMP 'aligned' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
|
||||
LParenLoc, ColonLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new OpenMP 'copyin' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
@@ -6506,6 +6519,25 @@ TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
|
||||
C->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
|
||||
llvm::SmallVector<Expr *, 16> Vars;
|
||||
Vars.reserve(C->varlist_size());
|
||||
for (auto *VE : C->varlists()) {
|
||||
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
|
||||
if (EVar.isInvalid())
|
||||
return nullptr;
|
||||
Vars.push_back(EVar.get());
|
||||
}
|
||||
ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
|
||||
if (Alignment.isInvalid())
|
||||
return nullptr;
|
||||
return getDerived().RebuildOMPAlignedClause(
|
||||
Vars, Alignment.get(), C->getLocStart(), C->getLParenLoc(),
|
||||
C->getColonLoc(), C->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
|
||||
|
||||
@@ -1703,6 +1703,9 @@ OMPClause *OMPClauseReader::readClause() {
|
||||
case OMPC_linear:
|
||||
C = OMPLinearClause::CreateEmpty(Context, Record[Idx++]);
|
||||
break;
|
||||
case OMPC_aligned:
|
||||
C = OMPAlignedClause::CreateEmpty(Context, Record[Idx++]);
|
||||
break;
|
||||
case OMPC_copyin:
|
||||
C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);
|
||||
break;
|
||||
@@ -1790,6 +1793,18 @@ void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
|
||||
C->setStep(Reader->Reader.ReadSubExpr());
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) {
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
unsigned NumVars = C->varlist_size();
|
||||
SmallVector<Expr *, 16> Vars;
|
||||
Vars.reserve(NumVars);
|
||||
for (unsigned i = 0; i != NumVars; ++i)
|
||||
Vars.push_back(Reader->Reader.ReadSubExpr());
|
||||
C->setVarRefs(Vars);
|
||||
C->setAlignment(Reader->Reader.ReadSubExpr());
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
unsigned NumVars = C->varlist_size();
|
||||
|
||||
@@ -1737,6 +1737,15 @@ void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
|
||||
Writer->Writer.AddStmt(C->getStep());
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
|
||||
for (auto *VE : C->varlists())
|
||||
Writer->Writer.AddStmt(VE);
|
||||
Writer->Writer.AddStmt(C->getAlignment());
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
|
||||
200
clang/test/OpenMP/simd_aligned_messages.cpp
Normal file
200
clang/test/OpenMP/simd_aligned_messages.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp=libiomp5 %s
|
||||
|
||||
struct B {
|
||||
static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
|
||||
static constexpr int bfoo() { return 8; }
|
||||
};
|
||||
namespace X {
|
||||
B x; // expected-note {{'x' defined here}}
|
||||
};
|
||||
constexpr int bfoo() { return 4; }
|
||||
|
||||
int **z;
|
||||
const int C1 = 1;
|
||||
const int C2 = 2;
|
||||
void test_aligned_colons(int *&rp)
|
||||
{
|
||||
int *B = 0;
|
||||
#pragma omp simd aligned(B:bfoo())
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
|
||||
#pragma omp simd aligned(B::ib:B:bfoo())
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
#pragma omp simd aligned(B:B::bfoo())
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
|
||||
#pragma omp simd aligned(z:B:bfoo())
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
#pragma omp simd aligned(B:B::bfoo())
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}}
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
|
||||
#pragma omp simd aligned(X::x : ::z)
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
|
||||
#pragma omp simd aligned(B,rp,::z: X::x)
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
#pragma omp simd aligned(::z)
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
// expected-error@+1 {{expected variable name}}
|
||||
#pragma omp simd aligned(B::bfoo())
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
#pragma omp simd aligned(B::ib,B:C1+C2)
|
||||
for (int i = 0; i < 10; ++i) ;
|
||||
}
|
||||
|
||||
// expected-note@+1 {{'num' defined here}}
|
||||
template<int L, class T, class N> T test_template(T* arr, N num) {
|
||||
N i;
|
||||
T sum = (T)0;
|
||||
T ind2 = - num * L;
|
||||
// Negative number is passed as L.
|
||||
// expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}}
|
||||
#pragma omp simd aligned(arr:L)
|
||||
for (i = 0; i < num; ++i) {
|
||||
T cur = arr[ind2];
|
||||
ind2 += L;
|
||||
sum += cur;
|
||||
}
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
|
||||
#pragma omp simd aligned(num:4)
|
||||
for (i = 0; i < num; ++i);
|
||||
}
|
||||
|
||||
template<int LEN> int test_warn() {
|
||||
int *ind2 = 0;
|
||||
// expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}}
|
||||
#pragma omp simd aligned(ind2:LEN)
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ind2 += LEN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct S1; // expected-note 2 {{declared here}}
|
||||
extern S1 a; // expected-note {{'a' declared here}}
|
||||
class S2 {
|
||||
mutable int a;
|
||||
public:
|
||||
S2():a(0) { }
|
||||
};
|
||||
const S2 b; // expected-note 1 {{'b' defined here}}
|
||||
const S2 ba[5];
|
||||
class S3 {
|
||||
int a;
|
||||
public:
|
||||
S3():a(0) { }
|
||||
};
|
||||
const S3 ca[5];
|
||||
class S4 {
|
||||
int a;
|
||||
S4();
|
||||
public:
|
||||
S4(int v):a(v) { }
|
||||
};
|
||||
class S5 {
|
||||
int a;
|
||||
S5():a(0) {}
|
||||
public:
|
||||
S5(int v):a(v) { }
|
||||
};
|
||||
|
||||
S3 h; // expected-note 2 {{'h' defined here}}
|
||||
#pragma omp threadprivate(h)
|
||||
|
||||
template<class I, class C> int foomain(I argc, C **argv) {
|
||||
I e(argc);
|
||||
I g(argc);
|
||||
int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
|
||||
// expected-note@+2 {{declared here}}
|
||||
// expected-note@+1 {{reference to 'i' is not a constant expression}}
|
||||
int &j = i;
|
||||
#pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned () // expected-error {{expected expression}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argc : 5)
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned(e, g)
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
|
||||
#pragma omp simd aligned(h)
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
|
||||
#pragma omp simd aligned(i)
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp parallel
|
||||
{
|
||||
int *v = 0;
|
||||
I i;
|
||||
#pragma omp simd aligned(v:16)
|
||||
for (I k = 0; k < argc; ++k) { i = k; v += 2; }
|
||||
}
|
||||
float *f;
|
||||
#pragma omp simd aligned(f)
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
int v = 0;
|
||||
// expected-note@+2 {{initializer of 'j' is not a constant expression}}
|
||||
// expected-error@+1 {{expression is not an integral constant expression}}
|
||||
#pragma omp simd aligned(f:j)
|
||||
for (I k = 0; k < argc; ++k) { ++k; v += j; }
|
||||
#pragma omp simd aligned(f)
|
||||
for (I k = 0; k < argc; ++k) ++k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// expected-note@+1 2 {{'argc' defined here}}
|
||||
int main(int argc, char **argv) {
|
||||
double darr[100];
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
|
||||
test_template<-4>(darr, 4);
|
||||
test_warn<4>(); // ok
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
|
||||
test_warn<0>();
|
||||
|
||||
int i;
|
||||
int &j = i;
|
||||
#pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned () // expected-error {{expected expression}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
|
||||
#pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
|
||||
#pragma omp simd aligned (argc)
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
// expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}}
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
|
||||
#pragma omp simd aligned (a, b)
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
#pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
// expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
|
||||
#pragma omp simd aligned(h)
|
||||
for (int k = 0; k < argc; ++k) ++k;
|
||||
int *pargc = &argc;
|
||||
foomain<int*,char>(pargc,argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ template<class T, class N> T reduct(T* arr, N num) {
|
||||
N myind;
|
||||
T sum = (T)0;
|
||||
// CHECK: T sum = (T)0;
|
||||
#pragma omp simd private(myind, g_ind), linear(ind)
|
||||
// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind)
|
||||
#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr)
|
||||
// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr)
|
||||
for (i = 0; i < num; ++i) {
|
||||
myind = ind;
|
||||
T cur = arr[myind];
|
||||
@@ -62,7 +62,7 @@ template<class T> struct S {
|
||||
template<int LEN> struct S2 {
|
||||
static void func(int n, float *a, float *b, float *c) {
|
||||
int k1 = 0, k2 = 0;
|
||||
#pragma omp simd safelen(LEN) linear(k1,k2:LEN)
|
||||
#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN)
|
||||
for(int i = 0; i < n; i++) {
|
||||
c[i] = a[i] + b[i];
|
||||
c[k1] = a[k1] + b[k1];
|
||||
@@ -77,7 +77,7 @@ template<int LEN> struct S2 {
|
||||
// CHECK: template <int LEN = 4> struct S2 {
|
||||
// CHECK-NEXT: static void func(int n, float *a, float *b, float *c) {
|
||||
// CHECK-NEXT: int k1 = 0, k2 = 0;
|
||||
// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4)
|
||||
// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4)
|
||||
// CHECK-NEXT: for (int i = 0; i < n; i++) {
|
||||
// CHECK-NEXT: c[i] = a[i] + b[i];
|
||||
// CHECK-NEXT: c[k1] = a[k1] + b[k1];
|
||||
@@ -97,10 +97,10 @@ int main (int argc, char **argv) {
|
||||
for (int i=0; i < 2; ++i)*a=2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
// CHECK-NEXT: *a = 2;
|
||||
#pragma omp simd private(argc, b) collapse(2)
|
||||
#pragma omp simd private(argc, b) collapse(2) aligned(a : 4)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
|
||||
// CHECK-NEXT: #pragma omp simd private(argc,b) collapse(2)
|
||||
// CHECK-NEXT: #pragma omp simd private(argc,b) collapse(2) aligned(a: 4)
|
||||
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
|
||||
// CHECK-NEXT: for (int j = 0; j < 10; ++j) {
|
||||
// CHECK-NEXT: foo();
|
||||
@@ -112,8 +112,8 @@ int main (int argc, char **argv) {
|
||||
// CHECK-NEXT: foo();
|
||||
const int CLEN = 4;
|
||||
// CHECK-NEXT: const int CLEN = 4;
|
||||
#pragma omp simd linear(a:CLEN) safelen(CLEN) collapse( 1 )
|
||||
// CHECK-NEXT: #pragma omp simd linear(a: CLEN) safelen(CLEN) collapse(1)
|
||||
#pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 )
|
||||
// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1)
|
||||
for (int i = 0; i < 10; ++i)foo();
|
||||
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
|
||||
// CHECK-NEXT: foo();
|
||||
|
||||
@@ -292,6 +292,83 @@ void test_linear()
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
}
|
||||
|
||||
void test_aligned()
|
||||
{
|
||||
int i;
|
||||
// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
|
||||
#pragma omp simd aligned(
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+2 {{expected expression}}
|
||||
// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
|
||||
#pragma omp simd aligned(,
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+2 {{expected expression}}
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp simd aligned(,)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp simd aligned()
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp simd aligned(int)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected variable name}}
|
||||
#pragma omp simd aligned(0)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{use of undeclared identifier 'x'}}
|
||||
#pragma omp simd aligned(x)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+2 {{use of undeclared identifier 'x'}}
|
||||
// expected-error@+1 {{use of undeclared identifier 'y'}}
|
||||
#pragma omp simd aligned(x, y)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+3 {{use of undeclared identifier 'x'}}
|
||||
// expected-error@+2 {{use of undeclared identifier 'y'}}
|
||||
// expected-error@+1 {{use of undeclared identifier 'z'}}
|
||||
#pragma omp simd aligned(x, y, z)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
|
||||
int *x, y, z[25]; // expected-note 4 {{'y' defined here}}
|
||||
#pragma omp simd aligned(x)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
#pragma omp simd aligned(z)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp simd aligned(x:)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
|
||||
#pragma omp simd aligned(x:,)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
#pragma omp simd aligned(x:1)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
#pragma omp simd aligned(x:2*2)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
|
||||
#pragma omp simd aligned(x:1,y)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
|
||||
#pragma omp simd aligned(x:1,y,z:1)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
|
||||
// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
|
||||
#pragma omp simd aligned(x, y)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
|
||||
#pragma omp simd aligned(x, y, z)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
|
||||
// expected-note@+2 {{defined as aligned}}
|
||||
// expected-error@+1 {{a variable cannot appear in more than one aligned clause}}
|
||||
#pragma omp simd aligned(x) aligned(z,x)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
|
||||
// expected-note@+3 {{defined as aligned}}
|
||||
// expected-error@+2 {{a variable cannot appear in more than one aligned clause}}
|
||||
// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}}
|
||||
#pragma omp simd aligned(x,y,z) aligned(y,z)
|
||||
for (i = 0; i < 16; ++i) ;
|
||||
}
|
||||
|
||||
void test_private()
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1963,6 +1963,10 @@ void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
Visitor->AddStmt(C->getStep());
|
||||
}
|
||||
void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
Visitor->AddStmt(C->getAlignment());
|
||||
}
|
||||
void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user