r255625 - [OPENMP 4.5] Parsing/sema for 'hint' clause of 'critical' directive.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 15 00:19:25 PST 2015
Author: abataev
Date: Tue Dec 15 02:19:24 2015
New Revision: 255625
URL: http://llvm.org/viewvc/llvm-project?rev=255625&view=rev
Log:
[OPENMP 4.5] Parsing/sema for 'hint' clause of 'critical' directive.
OpenMP 4.5 adds 'hint' clause to critical directive. Patch adds parsing/semantic analysis for this clause.
Modified:
cfe/trunk/include/clang/AST/OpenMPClause.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/AST/StmtOpenMP.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/OpenMPKinds.def
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/StmtOpenMP.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/StmtProfile.cpp
cfe/trunk/lib/Basic/OpenMPKinds.cpp
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
cfe/trunk/lib/Parse/ParseOpenMP.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/test/OpenMP/critical_ast_print.cpp
cfe/trunk/test/OpenMP/critical_messages.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Tue Dec 15 02:19:24 2015
@@ -3028,6 +3028,59 @@ public:
child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
};
+/// \brief This represents 'hint' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp critical (name) hint(6)
+/// \endcode
+/// In this example directive '#pragma omp critical' has name 'name' and clause
+/// 'hint' with argument '6'.
+///
+class OMPHintClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Hint expression of the 'hint' clause.
+ Stmt *Hint;
+
+ /// \brief Set hint expression.
+ ///
+ void setHint(Expr *H) { Hint = H; }
+
+public:
+ /// \brief Build 'hint' clause with expression \a Hint.
+ ///
+ /// \param Hint Hint expression.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Hint(Hint) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPHintClause()
+ : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Hint(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns number of threads.
+ Expr *getHint() const { return cast_or_null<Expr>(Hint); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_hint;
+ }
+
+ child_range children() { return child_range(&Hint, &Hint + 1); }
+};
+
} // end namespace clang
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Dec 15 02:19:24 2015
@@ -2772,6 +2772,12 @@ bool RecursiveASTVisitor<Derived>::Visit
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) {
+ TRY_TO(TraverseStmt(C->getHint()));
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Tue Dec 15 02:19:24 2015
@@ -1153,18 +1153,22 @@ class OMPCriticalDirective : public OMPE
/// \param Name Name of the directive.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
///
OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
- SourceLocation EndLoc)
+ SourceLocation EndLoc, unsigned NumClauses)
: OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
- StartLoc, EndLoc, 0, 1),
+ StartLoc, EndLoc, NumClauses, 1),
DirName(Name) {}
/// \brief Build an empty directive.
///
- explicit OMPCriticalDirective()
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPCriticalDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
- SourceLocation(), SourceLocation(), 0, 1),
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1),
DirName() {}
/// \brief Set name of the directive.
@@ -1180,17 +1184,21 @@ public:
/// \param Name Name of the directive.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
///
static OMPCriticalDirective *
Create(const ASTContext &C, const DeclarationNameInfo &Name,
- SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
/// \brief Creates an empty directive.
///
/// \param C AST context.
+ /// \param NumClauses Number of clauses.
///
- static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+ static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
/// \brief Return name of the directive.
///
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Dec 15 02:19:24 2015
@@ -7932,6 +7932,14 @@ def err_omp_grainsize_num_tasks_mutually
"'%0' and '%1' clause are mutually exclusive and may not appear on the same directive">;
def note_omp_previous_grainsize_num_tasks : Note<
"'%0' clause is specified here">;
+def err_omp_hint_clause_no_name : Error<
+ "the name of the construct must be specified in presence of 'hint' clause">;
+def err_omp_critical_with_hint : Error<
+ "constructs with the same name must have a 'hint' clause with the same value">;
+def note_omp_critical_hint_here : Note<
+ "%select{|previous }0'hint' clause with value '%1'">;
+def note_omp_critical_no_hint : Note<
+ "%select{|previous }0directive with no 'hint' clause specified">;
def err_omp_firstprivate_distribute_private_teams : Error<
"private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">;
def err_omp_firstprivate_and_lastprivate_in_distribute : Error<
Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Dec 15 02:19:24 2015
@@ -75,6 +75,9 @@
#ifndef OPENMP_TASKLOOP_SIMD_CLAUSE
# define OPENMP_TASKLOOP_SIMD_CLAUSE(Name)
#endif
+#ifndef OPENMP_CRITICAL_CLAUSE
+# define OPENMP_CRITICAL_CLAUSE(Name)
+#endif
#ifndef OPENMP_DISTRIBUTE_CLAUSE
#define OPENMP_DISTRIBUTE_CLAUSE(Name)
#endif
@@ -168,6 +171,7 @@ OPENMP_CLAUSE(priority, OMPPriorityClaus
OPENMP_CLAUSE(grainsize, OMPGrainsizeClause)
OPENMP_CLAUSE(nogroup, OMPNogroupClause)
OPENMP_CLAUSE(num_tasks, OMPNumTasksClause)
+OPENMP_CLAUSE(hint, OMPHintClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -393,6 +397,9 @@ OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize)
OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup)
OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks)
+// Clauses allowed for OpenMP directive 'critical'.
+OPENMP_CRITICAL_CLAUSE(hint)
+
// Clauses allowed for OpenMP directive 'distribute'
OPENMP_DISTRIBUTE_CLAUSE(private)
OPENMP_DISTRIBUTE_CLAUSE(firstprivate)
@@ -409,6 +416,7 @@ OPENMP_DISTRIBUTE_CLAUSE(collapse)
#undef OPENMP_DIRECTIVE
#undef OPENMP_DIRECTIVE_EXT
#undef OPENMP_CLAUSE
+#undef OPENMP_CRITICAL_CLAUSE
#undef OPENMP_ORDERED_CLAUSE
#undef OPENMP_CANCEL_CLAUSE
#undef OPENMP_SINGLE_CLAUSE
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Dec 15 02:19:24 2015
@@ -7875,6 +7875,7 @@ public:
/// \brief Called on well-formed '\#pragma omp critical' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+ ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed '\#pragma omp parallel for' after parsing
@@ -8018,6 +8019,10 @@ public:
OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'hint' clause.
+ OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
unsigned Argument,
Modified: cfe/trunk/lib/AST/StmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtOpenMP.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtOpenMP.cpp (original)
+++ cfe/trunk/lib/AST/StmtOpenMP.cpp Tue Dec 15 02:19:24 2015
@@ -312,22 +312,27 @@ OMPMasterDirective *OMPMasterDirective::
OMPCriticalDirective *OMPCriticalDirective::Create(
const ASTContext &C, const DeclarationNameInfo &Name,
- SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) {
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
OMPCriticalDirective *Dir =
- new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc);
+ new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
return Dir;
}
OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
EmptyShell) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPCriticalDirective();
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPCriticalDirective(NumClauses);
}
OMPParallelForDirective *OMPParallelForDirective::Create(
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Dec 15 02:19:24 2015
@@ -743,6 +743,12 @@ void OMPClausePrinter::VisitOMPNumTasksC
OS << ")";
}
+void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
+ OS << "hint(";
+ Node->getHint()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
template<typename T>
void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
for (typename T::varlist_iterator I = Node->varlist_begin(),
@@ -964,6 +970,7 @@ void StmtPrinter::VisitOMPCriticalDirect
Node->getDirectiveName().printName(OS);
OS << ")";
}
+ OS << " ";
PrintOMPExecutableDirective(Node);
}
Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Dec 15 02:19:24 2015
@@ -472,6 +472,9 @@ void OMPClauseProfiler::VisitOMPGrainsiz
void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
Profiler->VisitStmt(C->getNumTasks());
}
+void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
+ Profiler->VisitStmt(C->getHint());
+}
}
void
Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Dec 15 02:19:24 2015
@@ -141,6 +141,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
case OMPC_grainsize:
case OMPC_nogroup:
case OMPC_num_tasks:
+ case OMPC_hint:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -245,6 +246,7 @@ const char *clang::getOpenMPSimpleClause
case OMPC_grainsize:
case OMPC_nogroup:
case OMPC_num_tasks:
+ case OMPC_hint:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -438,6 +440,16 @@ bool clang::isAllowedClauseForDirective(
break;
}
break;
+ case OMPD_critical:
+ switch (CKind) {
+#define OPENMP_CRITICAL_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_distribute:
switch (CKind) {
#define OPENMP_DISTRIBUTE_CLAUSE(Name) \
@@ -452,7 +464,6 @@ bool clang::isAllowedClauseForDirective(
case OMPD_threadprivate:
case OMPD_section:
case OMPD_master:
- case OMPD_critical:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Dec 15 02:19:24 2015
@@ -2489,6 +2489,7 @@ static void EmitOMPAtomicExpr(CodeGenFun
case OMPC_grainsize:
case OMPC_nogroup:
case OMPC_num_tasks:
+ case OMPC_hint:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Dec 15 02:19:24 2015
@@ -404,7 +404,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op
/// update-clause | capture-clause | seq_cst-clause | device-clause |
/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
/// thread_limit-clause | priority-clause | grainsize-clause |
-/// nogroup-clause | num_tasks-clause
+/// nogroup-clause | num_tasks-clause | hint-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
@@ -430,6 +430,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
case OMPC_priority:
case OMPC_grainsize:
case OMPC_num_tasks:
+ case OMPC_hint:
// OpenMP [2.5, Restrictions]
// At most one num_threads clause can appear on the directive.
// OpenMP [2.8.1, simd construct, Restrictions]
@@ -541,7 +542,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
/// \brief Parsing of OpenMP clauses with single expressions like 'final',
/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
-/// 'thread_limit', 'simdlen', 'priority', 'grainsize' or 'num_tasks'.
+/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
///
/// final-clause:
/// 'final' '(' expression ')'
@@ -567,6 +568,9 @@ OMPClause *Parser::ParseOpenMPClause(Ope
/// num_tasks-clause:
/// 'num_tasks' '(' expression ')'
///
+/// hint-clause:
+/// 'hint' '(' expression ')'
+///
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
SourceLocation Loc = ConsumeToken();
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Dec 15 02:19:24 2015
@@ -91,6 +91,8 @@ private:
typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy;
typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy;
+ typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
+ CriticalsWithHintsTy;
struct SharingMapTy {
DeclSAMapTy SharingMap;
@@ -133,6 +135,7 @@ private:
OpenMPClauseKind ClauseKindMode;
Sema &SemaRef;
bool ForceCapturing;
+ CriticalsWithHintsTy Criticals;
typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
@@ -163,6 +166,16 @@ public:
Stack.pop_back();
}
+ void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
+ Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
+ }
+ const std::pair<OMPCriticalDirective *, llvm::APSInt>
+ getCriticalWithHint(const DeclarationNameInfo &Name) const {
+ auto I = Criticals.find(Name.getAsString());
+ if (I != Criticals.end())
+ return I->second;
+ return std::make_pair(nullptr, llvm::APSInt());
+ }
/// \brief If 'aligned' declaration for given variable \a D was not seen yet,
/// add it and return NULL; otherwise return previous occurrence's expression
/// for diagnostics.
@@ -2521,9 +2534,8 @@ StmtResult Sema::ActOnOpenMPExecutableDi
Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
break;
case OMPD_critical:
- assert(ClausesWithImplicit.empty() &&
- "No clauses are allowed for 'omp critical' directive");
- Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc);
+ Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
+ StartLoc, EndLoc);
break;
case OMPD_parallel_for:
Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
@@ -4301,19 +4313,62 @@ StmtResult Sema::ActOnOpenMPMasterDirect
return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
}
-StmtResult
-Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
- Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc) {
+StmtResult Sema::ActOnOpenMPCriticalDirective(
+ const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
if (!AStmt)
return StmtError();
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
+ bool ErrorFound = false;
+ llvm::APSInt Hint;
+ SourceLocation HintLoc;
+ bool DependentHint = false;
+ for (auto *C : Clauses) {
+ if (C->getClauseKind() == OMPC_hint) {
+ if (!DirName.getName()) {
+ Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
+ ErrorFound = true;
+ }
+ Expr *E = cast<OMPHintClause>(C)->getHint();
+ if (E->isTypeDependent() || E->isValueDependent() ||
+ E->isInstantiationDependent())
+ DependentHint = true;
+ else {
+ Hint = E->EvaluateKnownConstInt(Context);
+ HintLoc = C->getLocStart();
+ }
+ }
+ }
+ if (ErrorFound)
+ return StmtError();
+ auto Pair = DSAStack->getCriticalWithHint(DirName);
+ if (Pair.first && DirName.getName() && !DependentHint) {
+ if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
+ Diag(StartLoc, diag::err_omp_critical_with_hint);
+ if (HintLoc.isValid()) {
+ Diag(HintLoc, diag::note_omp_critical_hint_here)
+ << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
+ } else
+ Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
+ if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
+ Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
+ << 1
+ << C->getHint()->EvaluateKnownConstInt(Context).toString(
+ /*Radix=*/10, /*Signed=*/false);
+ } else
+ Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
+ }
+ }
+
getCurFunction()->setHasBranchProtectedScope();
- return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
- AStmt);
+ auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
+ Clauses, AStmt);
+ if (!Pair.first && DirName.getName() && !DependentHint)
+ DSAStack->addCriticalWithHint(Dir, Hint);
+ return Dir;
}
StmtResult Sema::ActOnOpenMPParallelForDirective(
@@ -5507,6 +5562,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
case OMPC_num_tasks:
Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_hint:
+ Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_default:
case OMPC_proc_bind:
@@ -5814,6 +5872,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
case OMPC_grainsize:
case OMPC_nogroup:
case OMPC_num_tasks:
+ case OMPC_hint:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -5950,6 +6009,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi
case OMPC_grainsize:
case OMPC_nogroup:
case OMPC_num_tasks:
+ case OMPC_hint:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -6090,6 +6150,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM
case OMPC_priority:
case OMPC_grainsize:
case OMPC_num_tasks:
+ case OMPC_hint:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -6230,6 +6291,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
case OMPC_grainsize:
case OMPC_nogroup:
case OMPC_num_tasks:
+ case OMPC_hint:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -8228,3 +8290,16 @@ OMPClause *Sema::ActOnOpenMPNumTasksClau
return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ // OpenMP [2.13.2, critical construct, Description]
+ // ... where hint-expression is an integer constant expression that evaluates
+ // to a valid lock hint.
+ ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
+ if (HintExpr.isInvalid())
+ return nullptr;
+ return new (Context)
+ OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
+}
+
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Dec 15 02:19:24 2015
@@ -1722,6 +1722,16 @@ public:
EndLoc);
}
+ /// \brief Build a new OpenMP 'hint' clause.
+ ///
+ /// By default, performs semantic analysis to build the new statement.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);
+ }
+
/// \brief Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -7843,6 +7853,15 @@ TreeTransform<Derived>::TransformOMPNumT
E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
+ ExprResult E = getDerived().TransformExpr(C->getHint());
+ if (E.isInvalid())
+ return nullptr;
+ return getDerived().RebuildOMPHintClause(E.get(), C->getLocStart(),
+ C->getLParenLoc(), C->getLocEnd());
+}
+
//===----------------------------------------------------------------------===//
// Expression transformation
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Dec 15 02:19:24 2015
@@ -1868,6 +1868,9 @@ OMPClause *OMPClauseReader::readClause()
case OMPC_num_tasks:
C = new (Context) OMPNumTasksClause();
break;
+ case OMPC_hint:
+ C = new (Context) OMPHintClause();
+ break;
}
Visit(C);
C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
@@ -2219,6 +2222,11 @@ void OMPClauseReader::VisitOMPNumTasksCl
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
}
+void OMPClauseReader::VisitOMPHintClause(OMPHintClause *C) {
+ C->setHint(Reader->Reader.ReadSubExpr());
+ C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
//===----------------------------------------------------------------------===//
// OpenMP Directives.
//===----------------------------------------------------------------------===//
@@ -2328,6 +2336,8 @@ void ASTStmtReader::VisitOMPMasterDirect
void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
VisitStmt(D);
+ // The NumClauses field was read in ReadStmtFromStream.
+ ++Idx;
VisitOMPExecutableDirective(D);
ReadDeclarationNameInfo(D->DirName, Record, Idx);
}
@@ -2991,7 +3001,8 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
break;
case STMT_OMP_CRITICAL_DIRECTIVE:
- S = OMPCriticalDirective::CreateEmpty(Context, Empty);
+ S = OMPCriticalDirective::CreateEmpty(
+ Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
case STMT_OMP_PARALLEL_FOR_DIRECTIVE: {
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Dec 15 02:19:24 2015
@@ -2028,6 +2028,11 @@ void OMPClauseWriter::VisitOMPNumTasksCl
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
}
+void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) {
+ Writer->Writer.AddStmt(C->getHint());
+ Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+}
+
//===----------------------------------------------------------------------===//
// OpenMP Directives.
//===----------------------------------------------------------------------===//
@@ -2134,6 +2139,7 @@ void ASTStmtWriter::VisitOMPMasterDirect
void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
VisitStmt(D);
+ Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
Writer.AddDeclarationNameInfo(D->getDirectiveName(), Record);
Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
Modified: cfe/trunk/test/OpenMP/critical_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/critical_ast_print.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/critical_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/critical_ast_print.cpp Tue Dec 15 02:19:24 2015
@@ -8,6 +8,26 @@
void foo() {}
+// CHECK: template <typename T, int N> int tmain(T argc, char **argv)
+template <typename T, int N>
+int tmain (T argc, char **argv) {
+ T b = argc, c, d, e, f, g;
+ static int a;
+// CHECK: static int a;
+#pragma omp critical
+ a=2;
+// CHECK-NEXT: #pragma omp critical
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: ++a;
+ ++a;
+#pragma omp critical (the_name) hint(N)
+ foo();
+// CHECK-NEXT: #pragma omp critical (the_name) hint(N)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: return N;
+ return N;
+}
+
int main (int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
@@ -18,12 +38,12 @@ int main (int argc, char **argv) {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: ++a;
++a;
-#pragma omp critical (the_name)
+#pragma omp critical (the_name1) hint(23)
foo();
-// CHECK-NEXT: #pragma omp critical (the_name)
+// CHECK-NEXT: #pragma omp critical (the_name1) hint(23)
// CHECK-NEXT: foo();
-// CHECK-NEXT: return 0;
- return 0;
+// CHECK-NEXT: return tmain<int, 4>(a, argv);
+ return tmain<int, 4>(a, argv);
}
#endif
Modified: cfe/trunk/test/OpenMP/critical_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/critical_messages.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/critical_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/critical_messages.cpp Tue Dec 15 02:19:24 2015
@@ -2,20 +2,21 @@
int foo();
-int main() {
+template<typename T, int N>
+int tmain(int argc, char **argv) { // expected-note {{declared here}}
#pragma omp critical
;
#pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}}
#pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}}
#pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp critical (name // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp critical (name2 // expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp critical (name1)
foo();
{
#pragma omp critical
} // expected-error {{expected statement}}
- #pragma omp critical (name) // expected-note {{previous 'critical' region starts here}}
+ #pragma omp critical (name2) // expected-note {{previous 'critical' region starts here}}
#pragma omp critical
for (int i = 0; i < 10; ++i) {
foo();
@@ -23,11 +24,11 @@ int main() {
#pragma omp for
for (int j = 0; j < 10; j++) {
foo();
- #pragma omp critical(name) // expected-error {{cannot nest 'critical' regions having the same name 'name'}}
+ #pragma omp critical(name2) // expected-error {{cannot nest 'critical' regions having the same name 'name2'}}
foo();
}
}
- #pragma omp critical (name)
+ #pragma omp critical (name2)
#pragma omp critical
for (int i = 0; i < 10; ++i) {
foo();
@@ -38,7 +39,7 @@ int main() {
foo();
}
}
- #pragma omp critical (name)
+ #pragma omp critical (name2)
#pragma omp critical
for (int i = 0; i < 10; ++i) {
foo();
@@ -50,9 +51,86 @@ int main() {
}
}
+ #pragma omp critical (name2) hint // expected-error {{expected '(' after 'hint'}}
+ foo();
+ #pragma omp critical (name2) hint( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp critical (name2) hint(+ // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp critical (name2) hint(argc) // expected-error {{expression is not an integral constant expression}} expected-note {{read of non-const variable 'argc' is not allowed in a constant expression}}
+ foo();
+ #pragma omp critical (name) hint(N) // expected-error {{argument to 'hint' clause must be a strictly positive integer value}} expected-error {{constructs with the same name must have a 'hint' clause with the same value}} expected-note {{'hint' clause with value '4'}}
+ foo();
+ #pragma omp critical hint(N) // expected-error {{the name of the construct must be specified in presence of 'hint' clause}}
+ foo();
return 0;
}
+int main(int argc, char **argv) { // expected-note {{declared here}}
+ #pragma omp critical
+ ;
+ #pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}}
+ #pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}}
+ #pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp critical (name2 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp critical (name1)
+ foo();
+ {
+ #pragma omp critical
+ } // expected-error {{expected statement}}
+ #pragma omp critical (name2) // expected-note {{previous 'critical' region starts here}}
+ #pragma omp critical
+ for (int i = 0; i < 10; ++i) {
+ foo();
+ #pragma omp parallel
+ #pragma omp for
+ for (int j = 0; j < 10; j++) {
+ foo();
+ #pragma omp critical(name2) // expected-error {{cannot nest 'critical' regions having the same name 'name2'}}
+ foo();
+ }
+ }
+ #pragma omp critical (name2)
+ #pragma omp critical
+ for (int i = 0; i < 10; ++i) {
+ foo();
+ #pragma omp parallel
+ #pragma omp for
+ for (int j = 0; j < 10; j++) {
+ #pragma omp critical
+ foo();
+ }
+ }
+ #pragma omp critical (name2)
+ #pragma omp critical
+ for (int i = 0; i < 10; ++i) {
+ foo();
+ #pragma omp parallel
+ #pragma omp for
+ for (int j = 0; j < 10; j++) {
+ #pragma omp critical (nam)
+ foo();
+ }
+ }
+
+ #pragma omp critical (name2) hint // expected-error {{expected '(' after 'hint'}}
+ foo();
+ #pragma omp critical (name2) hint( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp critical (name2) hint(+ // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp critical (name2) hint(argc) // expected-error {{expression is not an integral constant expression}} expected-note {{read of non-const variable 'argc' is not allowed in a constant expression}}
+ foo();
+ #pragma omp critical (name) hint(23) // expected-note {{previous 'hint' clause with value '23'}}
+ foo();
+ #pragma omp critical hint(-5) // expected-error {{argument to 'hint' clause must be a strictly positive integer value}}
+ foo();
+ #pragma omp critical hint(1) // expected-error {{the name of the construct must be specified in presence of 'hint' clause}}
+ foo();
+ return tmain<int, 4>(argc, argv) + tmain<float, -5>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<float, -5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
int foo() {
L1:
foo();
@@ -69,4 +147,4 @@ int foo() {
}
return 0;
-}
+ }
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=255625&r1=255624&r2=255625&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Dec 15 02:19:24 2015
@@ -2100,6 +2100,10 @@ void OMPClauseEnqueue::VisitOMPNumTasksC
Visitor->AddStmt(C->getNumTasks());
}
+void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
+ Visitor->AddStmt(C->getHint());
+}
+
template<typename T>
void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
for (const auto *I : Node->varlists()) {
More information about the cfe-commits
mailing list