Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 78f73c0..603dd56 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1,4 +1,4 @@
-//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ----------===//
+//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,13 +12,14 @@
///
//===----------------------------------------------------------------------===//
-#include "clang/Basic/OpenMPKinds.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/OpenMPKinds.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
@@ -34,9 +35,9 @@
namespace {
/// \brief Default data sharing attributes, which can be applied to directive.
enum DefaultDataSharingAttributes {
- DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
- DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
- DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'.
+ DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
+ DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
+ DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'.
};
/// \brief Stack for tracking declarations used in OpenMP directives and
@@ -47,8 +48,9 @@
OpenMPDirectiveKind DKind;
OpenMPClauseKind CKind;
DeclRefExpr *RefExpr;
- DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(0) { }
+ DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr) {}
};
+
private:
struct DSAInfo {
OpenMPClauseKind Attributes;
@@ -62,15 +64,13 @@
OpenMPDirectiveKind Directive;
DeclarationNameInfo DirectiveName;
Scope *CurScope;
- SharingMapTy(OpenMPDirectiveKind DKind,
- const DeclarationNameInfo &Name,
+ SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope)
- : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
- DirectiveName(Name), CurScope(CurScope) { }
+ : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
+ DirectiveName(std::move(Name)), CurScope(CurScope) {}
SharingMapTy()
- : SharingMap(), DefaultAttr(DSA_unspecified),
- Directive(OMPD_unknown), DirectiveName(),
- CurScope(0) { }
+ : SharingMap(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown),
+ DirectiveName(), CurScope(nullptr) {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -85,8 +85,9 @@
/// \brief Checks if the variable is a local for OpenMP region.
bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
+
public:
- explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) { }
+ explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) {}
void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
Scope *CurScope) {
@@ -134,7 +135,7 @@
Scope *getCurScope() const { return Stack.back().CurScope; }
Scope *getCurScope() { return Stack.back().CurScope; }
};
-} // end anonymous namespace.
+} // namespace
DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
VarDecl *D) {
@@ -166,8 +167,7 @@
// inside the construct are private.
if (DVar.DKind != OMPD_parallel) {
if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
- (D->getStorageClass() == SC_Auto ||
- D->getStorageClass() == SC_None)) {
+ (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
DVar.CKind = OMPC_private;
return DVar;
}
@@ -212,23 +212,25 @@
for (StackTy::reverse_iterator I = std::next(Iter),
EE = std::prev(Stack.rend());
I != EE; ++I) {
- // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
+ // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
+ // Referenced
// in a Construct, implicitly determined, p.6]
// In a task construct, if no default clause is present, a variable
// whose data-sharing attribute is not determined by the rules above is
// firstprivate.
DVarTemp = getDSA(I, D);
if (DVarTemp.CKind != OMPC_shared) {
- DVar.RefExpr = 0;
+ DVar.RefExpr = nullptr;
DVar.DKind = OMPD_task;
DVar.CKind = OMPC_firstprivate;
return DVar;
}
- if (I->Directive == OMPD_parallel) break;
+ if (I->Directive == OMPD_parallel)
+ break;
}
DVar.DKind = OMPD_task;
DVar.CKind =
- (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
+ (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
return DVar;
}
}
@@ -251,17 +253,16 @@
}
}
-bool
-DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
+bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
if (Stack.size() > 2) {
reverse_iterator I = Iter, E = Stack.rend() - 1;
- Scope *TopScope = 0;
- while (I != E &&
- I->Directive != OMPD_parallel) {
+ Scope *TopScope = nullptr;
+ while (I != E && I->Directive != OMPD_parallel) {
++I;
}
- if (I == E) return false;
- TopScope = I->CurScope ? I->CurScope->getParent() : 0;
+ if (I == E)
+ return false;
+ TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
Scope *CurScope = getCurScope();
while (CurScope != TopScope && !CurScope->isDeclScope(D)) {
CurScope = CurScope->getParent();
@@ -294,17 +295,18 @@
OpenMPDirectiveKind Kind = getCurrentDirective();
if (Kind != OMPD_parallel) {
if (isOpenMPLocal(D, std::next(Stack.rbegin())) && D->isLocalVarDecl() &&
- (D->getStorageClass() == SC_Auto ||
- D->getStorageClass() == SC_None))
+ (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
DVar.CKind = OMPC_private;
return DVar;
+ }
}
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
// in a Construct, C/C++, predetermined, p.4]
// Static data memebers are shared.
if (D->isStaticDataMember()) {
- // Variables with const-qualified type having no mutable member may be listed
+ // Variables with const-qualified type having no mutable member may be
+ // listed
// in a firstprivate clause, even if they are static data members.
DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
@@ -324,8 +326,8 @@
// in a Construct, C/C++, predetermined, p.6]
// Variables with const qualified type having no mutable member are
// shared.
- CXXRecordDecl *RD = Actions.getLangOpts().CPlusPlus ?
- Type->getAsCXXRecordDecl() : 0;
+ CXXRecordDecl *RD =
+ Actions.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
if (IsConstant &&
!(Actions.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
// Variables with const-qualified type having no mutable member may be
@@ -366,7 +368,8 @@
for (StackTy::reverse_iterator I = std::next(Stack.rbegin()),
E = std::prev(Stack.rend());
I != E; ++I) {
- if (DKind != OMPD_unknown && DKind != I->Directive) continue;
+ if (DKind != OMPD_unknown && DKind != I->Directive)
+ continue;
DSAVarData DVar = getDSA(I, D);
if (DVar.CKind == CKind)
return DVar;
@@ -380,9 +383,7 @@
#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
-void Sema::DestroyDataSharingAttributesStack() {
- delete DSAStack;
-}
+void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
const DeclarationNameInfo &DirName,
@@ -402,8 +403,9 @@
class VarDeclFilterCCC : public CorrectionCandidateCallback {
private:
Sema &Actions;
+
public:
- VarDeclFilterCCC(Sema &S) : Actions(S) { }
+ VarDeclFilterCCC(Sema &S) : Actions(S) {}
bool ValidateCandidate(const TypoCorrection &Candidate) override {
NamedDecl *ND = Candidate.getCorrectionDecl();
if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
@@ -414,7 +416,7 @@
return false;
}
};
-}
+} // namespace
ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
CXXScopeSpec &ScopeSpec,
@@ -428,12 +430,14 @@
VarDecl *VD;
if (!Lookup.isSingleResult()) {
VarDeclFilterCCC Validator(*this);
- if (TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope,
- 0, Validator)) {
+ if (TypoCorrection Corrected =
+ CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, Validator,
+ CTK_ErrorRecovery)) {
diagnoseTypo(Corrected,
- PDiag(Lookup.empty()? diag::err_undeclared_var_use_suggest
- : diag::err_omp_expected_var_arg_suggest)
- << Id.getName());
+ PDiag(Lookup.empty()
+ ? diag::err_undeclared_var_use_suggest
+ : diag::err_omp_expected_var_arg_suggest)
+ << Id.getName());
VD = Corrected.getCorrectionDeclAs<VarDecl>();
} else {
Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
@@ -443,8 +447,7 @@
}
} else {
if (!(VD = Lookup.getAsSingle<VarDecl>())) {
- Diag(Id.getLoc(), diag::err_omp_expected_var_arg)
- << Id.getName();
+ Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
return ExprError();
}
@@ -455,12 +458,12 @@
// Variables must be file-scope, namespace-scope, or static block-scope.
if (!VD->hasGlobalStorage()) {
Diag(Id.getLoc(), diag::err_omp_global_var_arg)
- << getOpenMPDirectiveName(OMPD_threadprivate)
- << !VD->isStaticLocal();
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
- IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD;
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
return ExprError();
}
@@ -472,11 +475,12 @@
if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
!getCurLexicalContext()->isTranslationUnit()) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
return ExprError();
}
// OpenMP [2.9.2, Restrictions, C/C++, p.3]
@@ -486,11 +490,12 @@
if (CanonicalVD->isStaticDataMember() &&
!CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
return ExprError();
}
// OpenMP [2.9.2, Restrictions, C/C++, p.4]
@@ -501,11 +506,12 @@
(!getCurLexicalContext()->isFileContext() ||
!getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
return ExprError();
}
// OpenMP [2.9.2, Restrictions, C/C++, p.6]
@@ -514,11 +520,12 @@
if (CanonicalVD->isStaticLocal() && CurScope &&
!isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
return ExprError();
}
@@ -527,7 +534,7 @@
// of the variables in its list.
if (VD->isUsed()) {
Diag(Id.getLoc(), diag::err_omp_var_used)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
return ExprError();
}
@@ -536,9 +543,9 @@
return DE;
}
-Sema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective(
- SourceLocation Loc,
- ArrayRef<Expr *> VarList) {
+Sema::DeclGroupPtrTy
+Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
+ ArrayRef<Expr *> VarList) {
if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
CurContext->addDecl(D);
return DeclGroupPtrTy::make(DeclGroupRef(D));
@@ -546,14 +553,11 @@
return DeclGroupPtrTy();
}
-OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
- SourceLocation Loc,
- ArrayRef<Expr *> VarList) {
+OMPThreadPrivateDecl *
+Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
SmallVector<Expr *, 8> Vars;
- for (ArrayRef<Expr *>::iterator I = VarList.begin(),
- E = VarList.end();
- I != E; ++I) {
- DeclRefExpr *DE = cast<DeclRefExpr>(*I);
+ for (auto &RefExpr : VarList) {
+ DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
VarDecl *VD = cast<VarDecl>(DE->getDecl());
SourceLocation ILoc = DE->getExprLoc();
@@ -568,29 +572,30 @@
// A threadprivate variable must not have a reference type.
if (VD->getType()->isReferenceType()) {
Diag(ILoc, diag::err_omp_ref_type_arg)
- << getOpenMPDirectiveName(OMPD_threadprivate)
- << VD->getType();
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
continue;
}
// Check if this is a TLS variable.
if (VD->getTLSKind()) {
Diag(ILoc, diag::err_omp_var_thread_local) << VD;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
continue;
}
- Vars.push_back(*I);
+ Vars.push_back(RefExpr);
DSAStack->addDSA(VD, DE, OMPC_threadprivate);
}
- OMPThreadPrivateDecl *D = 0;
+ OMPThreadPrivateDecl *D = nullptr;
if (!Vars.empty()) {
D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
Vars);
@@ -606,11 +611,13 @@
bool ErrorFound;
CapturedStmt *CS;
llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
+
public:
void VisitDeclRefExpr(DeclRefExpr *E) {
- if(VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
+ if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
// Skip internally declared variables.
- if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) return;
+ if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
+ return;
SourceLocation ELoc = E->getExprLoc();
@@ -646,28 +653,55 @@
}
}
void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
- for (ArrayRef<OMPClause *>::iterator I = S->clauses().begin(),
- E = S->clauses().end();
- I != E; ++I)
- if (OMPClause *C = *I)
+ for (auto C : S->clauses())
+ if (C)
for (StmtRange R = C->children(); R; ++R)
if (Stmt *Child = *R)
Visit(Child);
}
void VisitStmt(Stmt *S) {
- for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();
- I != E; ++I)
+ for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I != E;
+ ++I)
if (Stmt *Child = *I)
if (!isa<OMPExecutableDirective>(Child))
Visit(Child);
- }
+ }
bool isErrorFound() { return ErrorFound; }
ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS)
- : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) { }
+ : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) {}
};
+} // namespace
+
+void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,
+ Scope *CurScope) {
+ switch (DKind) {
+ case OMPD_parallel: {
+ QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+ QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
+ Sema::CapturedParamNameType Params[3] = {
+ std::make_pair(".global_tid.", KmpInt32PtrTy),
+ std::make_pair(".bound_tid.", KmpInt32PtrTy),
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);
+ break;
+ }
+ case OMPD_simd: {
+ Sema::CapturedParamNameType Params[1] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);
+ break;
+ }
+ case OMPD_threadprivate:
+ case OMPD_task:
+ llvm_unreachable("OpenMP Directive is not allowed");
+ case OMPD_unknown:
+ llvm_unreachable("Unknown OpenMP directive");
+ }
}
StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
@@ -690,35 +724,34 @@
bool ErrorFound = false;
if (!DSAChecker.getImplicitFirstprivate().empty()) {
- if (OMPClause *Implicit =
- ActOnOpenMPFirstprivateClause(DSAChecker.getImplicitFirstprivate(),
- SourceLocation(), SourceLocation(),
- SourceLocation())) {
+ if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
+ DSAChecker.getImplicitFirstprivate(), SourceLocation(),
+ SourceLocation(), SourceLocation())) {
ClausesWithImplicit.push_back(Implicit);
ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
- DSAChecker.getImplicitFirstprivate().size();
+ DSAChecker.getImplicitFirstprivate().size();
} else
ErrorFound = true;
}
switch (Kind) {
case OMPD_parallel:
- Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt,
- StartLoc, EndLoc);
+ Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc);
break;
case OMPD_simd:
- Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt,
- StartLoc, EndLoc);
+ Res =
+ ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
break;
case OMPD_threadprivate:
case OMPD_task:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
- case NUM_OPENMP_DIRECTIVES:
llvm_unreachable("Unknown OpenMP directive");
}
- if (ErrorFound) return StmtError();
+ if (ErrorFound)
+ return StmtError();
return Res;
}
@@ -726,15 +759,23 @@
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+ CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+ // 1.2.2 OpenMP Language Terminology
+ // Structured block - An executable statement with a single entry at the
+ // top and a single exit at the bottom.
+ // The point of exit cannot be a branch out of the structured block.
+ // longjmp() and throw() must not violate the entry/exit criteria.
+ CS->getCapturedDecl()->setNothrow();
+
getCurFunction()->setHasBranchProtectedScope();
- return Owned(OMPParallelDirective::Create(Context, StartLoc, EndLoc,
- Clauses, AStmt));
+ return Owned(
+ OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt));
}
StmtResult Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt,
- SourceLocation StartLoc,
+ Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc) {
Stmt *CStmt = AStmt;
while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(CStmt))
@@ -744,23 +785,22 @@
ForStmt *For = dyn_cast<ForStmt>(CStmt);
if (!For) {
Diag(CStmt->getLocStart(), diag::err_omp_not_for)
- << getOpenMPDirectiveName(OMPD_simd);
+ << getOpenMPDirectiveName(OMPD_simd);
return StmtError();
}
// FIXME: Checking loop canonical form, collapsing etc.
getCurFunction()->setHasBranchProtectedScope();
- return Owned(OMPSimdDirective::Create(Context, StartLoc, EndLoc,
- Clauses, AStmt));
+ return Owned(
+ OMPSimdDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt));
}
-OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
- Expr *Expr,
+OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
- OMPClause *Res = 0;
+ OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_if:
Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc);
@@ -771,21 +811,24 @@
case OMPC_safelen:
Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_collapse:
+ Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_default:
+ case OMPC_proc_bind:
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_linear:
case OMPC_copyin:
case OMPC_threadprivate:
case OMPC_unknown:
- case NUM_OPENMP_CLAUSES:
llvm_unreachable("Clause is not allowed.");
}
return Res;
}
-OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition,
- SourceLocation StartLoc,
+OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
Expr *ValExpr = Condition;
@@ -793,10 +836,9 @@
!Condition->isInstantiationDependent() &&
!Condition->containsUnexpandedParameterPack()) {
ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
- Condition->getExprLoc(),
- Condition);
+ Condition->getExprLoc(), Condition);
if (Val.isInvalid())
- return 0;
+ return nullptr;
ValExpr = Val.take();
}
@@ -812,36 +854,36 @@
class IntConvertDiagnoser : public ICEConvertDiagnoser {
public:
IntConvertDiagnoser()
- : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false,
- false, true) {}
+ : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
QualType T) override {
return S.Diag(Loc, diag::err_omp_not_integral) << T;
}
- SemaDiagnosticBuilder diagnoseIncomplete(
- Sema &S, SourceLocation Loc, QualType T) override {
+ SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
+ QualType T) override {
return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
}
- SemaDiagnosticBuilder diagnoseExplicitConv(
- Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
+ SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) override {
return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
}
- SemaDiagnosticBuilder noteExplicitConv(
- Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
+ SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
+ QualType ConvTy) override {
return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
- << ConvTy->isEnumeralType() << ConvTy;
+ << ConvTy->isEnumeralType() << ConvTy;
}
- SemaDiagnosticBuilder diagnoseAmbiguous(
- Sema &S, SourceLocation Loc, QualType T) override {
+ SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+ QualType T) override {
return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
}
- SemaDiagnosticBuilder noteAmbiguous(
- Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
+ SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
+ QualType ConvTy) override {
return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
- << ConvTy->isEnumeralType() << ConvTy;
+ << ConvTy->isEnumeralType() << ConvTy;
}
- SemaDiagnosticBuilder diagnoseConversion(
- Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
+ SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
+ QualType) override {
llvm_unreachable("conversion functions are permitted");
}
} ConvertDiagnoser;
@@ -860,23 +902,23 @@
ExprResult Val =
PerformImplicitIntegerConversion(NumThreadsLoc, NumThreads);
if (Val.isInvalid())
- return 0;
+ return nullptr;
ValExpr = Val.take();
// OpenMP [2.5, Restrictions]
// The num_threads expression must evaluate to a positive integer value.
llvm::APSInt Result;
- if (ValExpr->isIntegerConstantExpr(Result, Context) &&
- Result.isSigned() && !Result.isStrictlyPositive()) {
+ if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() &&
+ !Result.isStrictlyPositive()) {
Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause)
<< "num_threads" << NumThreads->getSourceRange();
- return 0;
+ return nullptr;
}
}
- return new (Context) OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc,
- EndLoc);
+ return new (Context)
+ OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
}
ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
@@ -906,34 +948,51 @@
// positive integer expression.
ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
if (Safelen.isInvalid())
- return 0;
+ return nullptr;
return new (Context)
OMPSafelenClause(Safelen.take(), StartLoc, LParenLoc, EndLoc);
}
-OMPClause *Sema::ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
- unsigned Argument,
- SourceLocation ArgumentLoc,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- OMPClause *Res = 0;
+OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ // OpenMP [2.8.1, simd construct, Description]
+ // The parameter of the collapse clause must be a constant
+ // positive integer expression.
+ ExprResult NumForLoops =
+ VerifyPositiveIntegerConstantInClause(Num, OMPC_collapse);
+ if (NumForLoops.isInvalid())
+ return nullptr;
+ return new (Context)
+ OMPCollapseClause(NumForLoops.take(), StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPSimpleClause(
+ OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
+ OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_default:
Res =
- ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
- ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
+ ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ break;
+ case OMPC_proc_bind:
+ Res = ActOnOpenMPProcBindClause(
+ static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
+ LParenLoc, EndLoc);
break;
case OMPC_if:
case OMPC_num_threads:
case OMPC_safelen:
+ case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_linear:
case OMPC_copyin:
case OMPC_threadprivate:
case OMPC_unknown:
- case NUM_OPENMP_CLAUSES:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -946,19 +1005,18 @@
SourceLocation EndLoc) {
if (Kind == OMPC_DEFAULT_unknown) {
std::string Values;
- static_assert(NUM_OPENMP_DEFAULT_KINDS > 1,
- "NUM_OPENMP_DEFAULT_KINDS not greater than 1");
+ static_assert(OMPC_DEFAULT_unknown > 0,
+ "OMPC_DEFAULT_unknown not greater than 0");
std::string Sep(", ");
- for (unsigned i = OMPC_DEFAULT_unknown + 1;
- i < NUM_OPENMP_DEFAULT_KINDS; ++i) {
+ for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) {
Values += "'";
Values += getOpenMPSimpleClauseTypeName(OMPC_default, i);
Values += "'";
switch (i) {
- case NUM_OPENMP_DEFAULT_KINDS - 2:
+ case OMPC_DEFAULT_unknown - 2:
Values += " or ";
break;
- case NUM_OPENMP_DEFAULT_KINDS - 1:
+ case OMPC_DEFAULT_unknown - 1:
break;
default:
Values += Sep;
@@ -966,8 +1024,8 @@
}
}
Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
- << Values << getOpenMPClauseName(OMPC_default);
- return 0;
+ << Values << getOpenMPClauseName(OMPC_default);
+ return nullptr;
}
switch (Kind) {
case OMPC_DEFAULT_none:
@@ -977,20 +1035,50 @@
DSAStack->setDefaultDSAShared();
break;
case OMPC_DEFAULT_unknown:
- case NUM_OPENMP_DEFAULT_KINDS:
llvm_unreachable("Clause kind is not allowed.");
break;
}
- return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc,
- EndLoc);
+ return new (Context)
+ OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
}
-OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
- ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- OMPClause *Res = 0;
+OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_PROC_BIND_unknown) {
+ std::string Values;
+ std::string Sep(", ");
+ for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) {
+ Values += "'";
+ Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i);
+ Values += "'";
+ switch (i) {
+ case OMPC_PROC_BIND_unknown - 2:
+ Values += " or ";
+ break;
+ case OMPC_PROC_BIND_unknown - 1:
+ break;
+ default:
+ Values += Sep;
+ break;
+ }
+ }
+ Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+ << Values << getOpenMPClauseName(OMPC_proc_bind);
+ return nullptr;
+ }
+ return new (Context)
+ OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *
+Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> VarList,
+ Expr *TailExpr, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc) {
+ OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_private:
Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
@@ -1001,16 +1089,21 @@
case OMPC_shared:
Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_linear:
+ Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
+ ColonLoc, EndLoc);
+ break;
case OMPC_copyin:
Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_if:
case OMPC_num_threads:
case OMPC_safelen:
+ case OMPC_collapse:
case OMPC_default:
+ case OMPC_proc_bind:
case OMPC_threadprivate:
case OMPC_unknown:
- case NUM_OPENMP_CLAUSES:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -1021,25 +1114,23 @@
SourceLocation LParenLoc,
SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
- for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
- I != E; ++I) {
- assert(*I && "NULL expr in OpenMP private clause.");
- if (isa<DependentScopeDeclRefExpr>(*I)) {
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP private clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
// It will be analyzed later.
- Vars.push_back(*I);
+ Vars.push_back(RefExpr);
continue;
}
- SourceLocation ELoc = (*I)->getExprLoc();
+ SourceLocation ELoc = RefExpr->getExprLoc();
// OpenMP [2.1, C/C++]
// A list item is a variable name.
// OpenMP [2.9.3.3, Restrictions, p.1]
// A variable that is part of another variable (as an array or
// structure element) cannot appear in a private clause.
- DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
+ DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
if (!DE || !isa<VarDecl>(DE->getDecl())) {
- Diag(ELoc, diag::err_omp_expected_var_name)
- << (*I)->getSourceRange();
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
continue;
}
Decl *D = DE->getDecl();
@@ -1061,11 +1152,12 @@
}
if (Type->isReferenceType()) {
Diag(ELoc, diag::err_omp_clause_ref_type_arg)
- << getOpenMPClauseName(OMPC_private) << Type;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPClauseName(OMPC_private) << Type;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
continue;
}
@@ -1074,26 +1166,27 @@
// clause requires an accesible, unambiguous default constructor for the
// class type.
while (Type.getNonReferenceType()->isArrayType()) {
- Type = cast<ArrayType>(
- Type.getNonReferenceType().getTypePtr())->getElementType();
+ Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
+ ->getElementType();
}
- CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
- Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
+ CXXRecordDecl *RD = getLangOpts().CPlusPlus
+ ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+ : nullptr;
if (RD) {
CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
PartialDiagnostic PD =
- PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
- if (!CD ||
- CheckConstructorAccess(ELoc, CD,
- InitializedEntity::InitializeTemporary(Type),
- CD->getAccess(), PD) == AR_inaccessible ||
+ PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+ if (!CD || CheckConstructorAccess(
+ ELoc, CD, InitializedEntity::InitializeTemporary(Type),
+ CD->getAccess(), PD) == AR_inaccessible ||
CD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
- << getOpenMPClauseName(OMPC_private) << 0;
+ << getOpenMPClauseName(OMPC_private) << 0;
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
continue;
}
@@ -1105,11 +1198,12 @@
if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
DD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
- << getOpenMPClauseName(OMPC_private) << 4;
+ << getOpenMPClauseName(OMPC_private) << 4;
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
continue;
}
@@ -1127,15 +1221,14 @@
// the variable's predetermined data-sharing attributes.
DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
- Diag(ELoc, diag::err_omp_wrong_dsa)
- << getOpenMPClauseName(DVar.CKind)
- << getOpenMPClauseName(OMPC_private);
+ Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_private);
if (DVar.RefExpr) {
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ << getOpenMPClauseName(DVar.CKind);
} else {
Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ << getOpenMPClauseName(DVar.CKind);
}
continue;
}
@@ -1144,7 +1237,8 @@
Vars.push_back(DE);
}
- if (Vars.empty()) return 0;
+ if (Vars.empty())
+ return nullptr;
return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
@@ -1154,25 +1248,23 @@
SourceLocation LParenLoc,
SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
- for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
- I != E; ++I) {
- assert(*I && "NULL expr in OpenMP firstprivate clause.");
- if (isa<DependentScopeDeclRefExpr>(*I)) {
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
// It will be analyzed later.
- Vars.push_back(*I);
+ Vars.push_back(RefExpr);
continue;
}
- SourceLocation ELoc = (*I)->getExprLoc();
+ SourceLocation ELoc = RefExpr->getExprLoc();
// OpenMP [2.1, C/C++]
// A list item is a variable name.
// OpenMP [2.9.3.3, Restrictions, p.1]
// A variable that is part of another variable (as an array or
// structure element) cannot appear in a private clause.
- DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
+ DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
if (!DE || !isa<VarDecl>(DE->getDecl())) {
- Diag(ELoc, diag::err_omp_expected_var_name)
- << (*I)->getSourceRange();
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
continue;
}
Decl *D = DE->getDecl();
@@ -1194,11 +1286,12 @@
}
if (Type->isReferenceType()) {
Diag(ELoc, diag::err_omp_clause_ref_type_arg)
- << getOpenMPClauseName(OMPC_firstprivate) << Type;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ << getOpenMPClauseName(OMPC_firstprivate) << Type;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
continue;
}
@@ -1207,23 +1300,24 @@
// clause requires an accesible, unambiguous copy constructor for the
// class type.
Type = Context.getBaseElementType(Type);
- CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
- Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
+ CXXRecordDecl *RD = getLangOpts().CPlusPlus
+ ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+ : nullptr;
if (RD) {
CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
PartialDiagnostic PD =
- PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
- if (!CD ||
- CheckConstructorAccess(ELoc, CD,
- InitializedEntity::InitializeTemporary(Type),
- CD->getAccess(), PD) == AR_inaccessible ||
+ PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+ if (!CD || CheckConstructorAccess(
+ ELoc, CD, InitializedEntity::InitializeTemporary(Type),
+ CD->getAccess(), PD) == AR_inaccessible ||
CD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
- << getOpenMPClauseName(OMPC_firstprivate) << 1;
+ << getOpenMPClauseName(OMPC_firstprivate) << 1;
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
continue;
}
@@ -1235,11 +1329,12 @@
if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
DD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
- << getOpenMPClauseName(OMPC_firstprivate) << 4;
+ << getOpenMPClauseName(OMPC_firstprivate) << 4;
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
continue;
}
@@ -1263,10 +1358,10 @@
if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
DVar.RefExpr) {
Diag(ELoc, diag::err_omp_wrong_dsa)
- << getOpenMPClauseName(DVar.CKind)
- << getOpenMPClauseName(OMPC_firstprivate);
+ << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_firstprivate);
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ << getOpenMPClauseName(DVar.CKind);
continue;
}
@@ -1284,10 +1379,10 @@
if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
Diag(ELoc, diag::err_omp_wrong_dsa)
- << getOpenMPClauseName(DVar.CKind)
- << getOpenMPClauseName(OMPC_firstprivate);
+ << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_firstprivate);
Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ << getOpenMPClauseName(DVar.CKind);
continue;
}
@@ -1314,7 +1409,8 @@
Vars.push_back(DE);
}
- if (Vars.empty()) return 0;
+ if (Vars.empty())
+ return nullptr;
return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Vars);
@@ -1325,26 +1421,24 @@
SourceLocation LParenLoc,
SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
- for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
- I != E; ++I) {
- assert(*I && "NULL expr in OpenMP shared clause.");
- if (isa<DependentScopeDeclRefExpr>(*I)) {
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP shared clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
// It will be analyzed later.
- Vars.push_back(*I);
+ Vars.push_back(RefExpr);
continue;
}
- SourceLocation ELoc = (*I)->getExprLoc();
+ SourceLocation ELoc = RefExpr->getExprLoc();
// OpenMP [2.1, C/C++]
// A list item is a variable name.
// OpenMP [2.14.3.2, Restrictions, p.1]
// A variable that is part of another variable (as an array or structure
// element) cannot appear in a shared unless it is a static data member
// of a C++ class.
- DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
if (!DE || !isa<VarDecl>(DE->getDecl())) {
- Diag(ELoc, diag::err_omp_expected_var_name)
- << (*I)->getSourceRange();
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
continue;
}
Decl *D = DE->getDecl();
@@ -1365,12 +1459,12 @@
// variable in a data-sharing attribute clause is allowed and overrides
// the variable's predetermined data-sharing attributes.
DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
- if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && DVar.RefExpr) {
- Diag(ELoc, diag::err_omp_wrong_dsa)
- << getOpenMPClauseName(DVar.CKind)
- << getOpenMPClauseName(OMPC_shared);
+ if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
+ DVar.RefExpr) {
+ Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_shared);
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ << getOpenMPClauseName(DVar.CKind);
continue;
}
@@ -1378,34 +1472,161 @@
Vars.push_back(DE);
}
- if (Vars.empty()) return 0;
+ if (Vars.empty())
+ return nullptr;
return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
+OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc) {
+ SmallVector<Expr *, 8> Vars;
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP linear clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ // OpenMP [2.14.3.7, linear clause]
+ // A list item that appears in a linear clause is subject to the private
+ // clause semantics described in Section 2.14.3.3 on page 159 except as
+ // noted. In addition, the value of the new list item on each iteration
+ // of the associated loop(s) corresponds to the value of the original
+ // list item before entering the construct plus the logical number of
+ // the iteration times linear-step.
+
+ SourceLocation ELoc = RefExpr->getExprLoc();
+ // OpenMP [2.1, C/C++]
+ // A list item is a variable name.
+ // OpenMP [2.14.3.3, Restrictions, p.1]
+ // A variable that is part of another variable (as an array or
+ // structure element) cannot appear in a private clause.
+ 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.14.3.7, linear clause]
+ // A list-item cannot appear in more than one linear clause.
+ // A list-item that appears in a linear clause cannot appear in any
+ // other data-sharing attribute clause.
+ DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+ if (DVar.RefExpr) {
+ Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_linear);
+ Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
+ << getOpenMPClauseName(DVar.CKind);
+ continue;
+ }
+
+ QualType QType = VD->getType();
+ if (QType->isDependentType() || QType->isInstantiationDependentType()) {
+ // It will be analyzed later.
+ Vars.push_back(DE);
+ continue;
+ }
+
+ // A variable must not have an incomplete type or a reference type.
+ if (RequireCompleteType(ELoc, QType,
+ diag::err_omp_linear_incomplete_type)) {
+ continue;
+ }
+ if (QType->isReferenceType()) {
+ Diag(ELoc, diag::err_omp_clause_ref_type_arg)
+ << getOpenMPClauseName(OMPC_linear) << QType;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+
+ // A list item must not be const-qualified.
+ if (QType.isConstant(Context)) {
+ Diag(ELoc, diag::err_omp_const_variable)
+ << getOpenMPClauseName(OMPC_linear);
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+
+ // A list item must be of integral or pointer type.
+ QType = QType.getUnqualifiedType().getCanonicalType();
+ const Type *Ty = QType.getTypePtrOrNull();
+ if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+ !Ty->isPointerType())) {
+ Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+
+ DSAStack->addDSA(VD, DE, OMPC_linear);
+ Vars.push_back(DE);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ Expr *StepExpr = Step;
+ if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
+ !Step->isInstantiationDependent() &&
+ !Step->containsUnexpandedParameterPack()) {
+ SourceLocation StepLoc = Step->getLocStart();
+ ExprResult Val = PerformImplicitIntegerConversion(StepLoc, Step);
+ if (Val.isInvalid())
+ return nullptr;
+ StepExpr = Val.take();
+
+ // Warn about zero linear step (it would be probably better specified as
+ // making corresponding variables 'const').
+ llvm::APSInt Result;
+ if (StepExpr->isIntegerConstantExpr(Result, Context) &&
+ !Result.isNegative() && !Result.isStrictlyPositive())
+ Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
+ << (Vars.size() > 1);
+ }
+
+ return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc,
+ Vars, StepExpr);
+}
+
OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
- for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
- I != E; ++I) {
- assert(*I && "NULL expr in OpenMP copyin clause.");
- if (isa<DependentScopeDeclRefExpr>(*I)) {
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP copyin clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
// It will be analyzed later.
- Vars.push_back(*I);
+ Vars.push_back(RefExpr);
continue;
}
- SourceLocation ELoc = (*I)->getExprLoc();
+ SourceLocation ELoc = RefExpr->getExprLoc();
// OpenMP [2.1, C/C++]
// A list item is a variable name.
// OpenMP [2.14.4.1, Restrictions, p.1]
// A list item that appears in a copyin clause must be threadprivate.
- DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
if (!DE || !isa<VarDecl>(DE->getDecl())) {
- Diag(ELoc, diag::err_omp_expected_var_name)
- << (*I)->getSourceRange();
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
continue;
}
@@ -1423,8 +1644,8 @@
// A list item that appears in a copyin clause must be threadprivate.
if (!DSAStack->isThreadPrivate(VD)) {
Diag(ELoc, diag::err_omp_required_access)
- << getOpenMPClauseName(OMPC_copyin)
- << getOpenMPDirectiveName(OMPD_threadprivate);
+ << getOpenMPClauseName(OMPC_copyin)
+ << getOpenMPDirectiveName(OMPD_threadprivate);
continue;
}
@@ -1433,20 +1654,20 @@
// copyin clause requires an accesible, unambiguous copy assignment
// operator for the class type.
Type = Context.getBaseElementType(Type);
- CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
- Type->getAsCXXRecordDecl() : 0;
+ CXXRecordDecl *RD =
+ getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
if (RD) {
CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
- if (!MD ||
- CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+ if (!MD || CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
MD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
- << getOpenMPClauseName(OMPC_copyin) << 2;
+ << getOpenMPClauseName(OMPC_copyin) << 2;
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
VarDecl::DeclarationOnly;
- Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
- diag::note_defined_here) << VD;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
continue;
}
@@ -1458,7 +1679,8 @@
Vars.push_back(DE);
}
- if (Vars.empty()) return 0;
+ if (Vars.empty())
+ return nullptr;
return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}