21 #include "llvm/ADT/PointerIntPair.h"
23 using namespace clang;
35 OMPD_cancellation_point},
37 {OMPD_for, OMPD_simd, OMPD_for_simd},
38 {OMPD_parallel, OMPD_for, OMPD_parallel_for},
39 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
40 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
41 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd}};
48 bool TokenMatched =
false;
49 for (
unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
55 TokenMatched = DKind == F[i][0] && DKind !=
OMPD_unknown;
72 TokenMatched = SDKind == F[i][1] && SDKind !=
OMPD_unknown;
90 assert(Tok.
is(tok::annot_pragma_openmp) &&
"Not an OpenMP directive!");
98 case OMPD_threadprivate:
100 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers,
true)) {
103 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
104 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
114 Diag(Tok, diag::err_omp_unknown_directive);
132 case OMPD_parallel_for:
133 case OMPD_parallel_for_simd:
134 case OMPD_parallel_sections:
138 case OMPD_cancellation_point:
140 case OMPD_target_data:
142 case OMPD_taskloop_simd:
143 case OMPD_distribute:
144 Diag(Tok, diag::err_omp_unexpected_directive)
168 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
169 AllowedContsructsKind Allowed) {
170 assert(Tok.
is(tok::annot_pragma_openmp) &&
"Not an OpenMP directive!");
176 unsigned ScopeFlags =
184 bool HasAssociatedStatement =
true;
185 bool FlushHasClause =
false;
188 case OMPD_threadprivate:
189 if (Allowed != ACK_Any) {
190 Diag(Tok, diag::err_omp_immediate_directive)
194 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers,
false)) {
197 if (Tok.
isNot(tok::annot_pragma_openmp_end)) {
198 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
210 FlushHasClause =
true;
218 case OMPD_cancellation_point:
220 if (Allowed == ACK_StatementsOpenMPNonStandalone) {
221 Diag(Tok, diag::err_omp_immediate_directive)
224 HasAssociatedStatement =
false;
235 case OMPD_parallel_for:
236 case OMPD_parallel_for_simd:
237 case OMPD_parallel_sections:
244 case OMPD_target_data:
246 case OMPD_taskloop_simd:
247 case OMPD_distribute: {
250 if (DKind == OMPD_critical) {
252 tok::annot_pragma_openmp_end);
253 if (!T.consumeOpen()) {
259 Diag(Tok, diag::err_omp_expected_identifier_for_critical);
263 }
else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
265 if (Tok.
isNot(tok::annot_pragma_openmp_end))
273 ParseScope OMPDirectiveScope(
this, ScopeFlags);
276 while (Tok.
isNot(tok::annot_pragma_openmp_end)) {
280 : FlushHasClause ? OMPC_flush
283 FlushHasClause =
false;
285 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
286 FirstClauses[CKind].setInt(
true);
288 FirstClauses[CKind].setPointer(Clause);
289 Clauses.push_back(Clause);
293 if (Tok.
is(tok::comma))
305 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
306 if (Allowed == ACK_StatementsOpenMPNonStandalone) {
307 Diag(Loc, diag::err_omp_immediate_directive)
311 HasAssociatedStatement =
false;
315 if (HasAssociatedStatement) {
321 AssociatedStmt = ParseStatement();
326 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
331 OMPDirectiveScope.Exit();
335 Diag(Tok, diag::err_omp_unknown_directive);
350 bool AllowScopeSpecifier) {
354 if (T.expectAndConsume(diag::err_expected_lparen_after,
357 bool IsCorrect =
true;
358 bool NoIdentIsFound =
true;
361 while (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::annot_pragma_openmp_end)) {
367 NoIdentIsFound =
false;
369 if (AllowScopeSpecifier &&
getLangOpts().CPlusPlus &&
370 ParseOptionalCXXScopeSpecifier(SS,
ParsedType(),
false)) {
372 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
375 TemplateKWLoc, Name)) {
377 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
379 }
else if (Tok.
isNot(tok::comma) && Tok.
isNot(tok::r_paren) &&
380 Tok.
isNot(tok::annot_pragma_openmp_end)) {
382 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
392 VarList.push_back(Res.
get());
395 if (Tok.
is(tok::comma)) {
400 if (NoIdentIsFound) {
401 Diag(Tok, diag::err_expected) << tok::identifier;
406 IsCorrect = !T.consumeClose() && IsCorrect;
408 return !IsCorrect && VarList.empty();
428 bool ErrorFound =
false;
438 case OMPC_num_threads:
445 case OMPC_thread_limit:
471 Diag(Tok, diag::err_omp_more_one_clause)
477 Clause = ParseOpenMPClause(CKind);
479 Clause = ParseOpenMPSingleExprClause(CKind);
489 Diag(Tok, diag::err_omp_more_one_clause)
494 Clause = ParseOpenMPSimpleClause(CKind);
500 Diag(Tok, diag::err_omp_more_one_clause)
506 Clause = ParseOpenMPSingleExprWithArgClause(CKind);
524 Diag(Tok, diag::err_omp_more_one_clause)
529 Clause = ParseOpenMPClause(CKind);
532 case OMPC_firstprivate:
533 case OMPC_lastprivate:
539 case OMPC_copyprivate:
543 Clause = ParseOpenMPVarListClause(DKind, CKind);
546 Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
556 return ErrorFound ?
nullptr : Clause;
594 if (T.expectAndConsume(diag::err_expected_lparen_after,
610 Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
626 if (T.expectAndConsume(diag::err_expected_lparen_after,
633 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
634 Tok.
isNot(tok::annot_pragma_openmp_end))
693 if (T.expectAndConsume(diag::err_expected_lparen_after,
700 if (Kind == OMPC_schedule) {
701 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
702 Arg.resize(NumberOfElements);
703 KLoc.resize(NumberOfElements);
711 Arg[Modifier1] = KindModifier;
713 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
714 Tok.
isNot(tok::annot_pragma_openmp_end))
716 if (Tok.
is(tok::comma)) {
725 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
726 Tok.
isNot(tok::annot_pragma_openmp_end))
730 if (Tok.
is(tok::colon))
733 Diag(Tok, diag::warn_pragma_expected_colon) <<
"schedule modifier";
737 Arg[ScheduleKind] = KindModifier;
739 if (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::comma) &&
740 Tok.
isNot(tok::annot_pragma_openmp_end))
742 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
743 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
744 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
746 DelimLoc = ConsumeAnyToken();
748 assert(Kind == OMPC_if);
753 if (Tok.
is(tok::colon))
756 Diag(Tok, diag::warn_pragma_expected_colon)
757 <<
"directive name modifier";
761 bool NeedAnExpression =
762 (Kind == OMPC_schedule && DelimLoc.
isValid()) || Kind == OMPC_if;
763 if (NeedAnExpression) {
777 Kind, Arg, Val.
get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
778 T.getCloseLocation());
784 if (ReductionIdScopeSpec.
isEmpty()) {
824 TemplateKWLoc, ReductionId);
866 bool InvalidReductionId =
false;
873 bool MapTypeModifierSpecified =
false;
874 bool UnexpectedId =
false;
879 if (T.expectAndConsume(diag::err_expected_lparen_after,
883 bool NeedRParenForLinear =
false;
885 tok::annot_pragma_openmp_end);
887 if (Kind == OMPC_reduction) {
890 ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec,
ParsedType(),
false);
894 if (InvalidReductionId) {
895 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
898 if (Tok.
is(tok::colon)) {
901 Diag(Tok, diag::warn_pragma_expected_colon) <<
"reduction identifier";
903 }
else if (Kind == OMPC_depend) {
911 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
916 if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) {
923 LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
926 if (Tok.
is(tok::colon)) {
929 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
930 : diag::warn_pragma_expected_colon)
931 <<
"dependency type";
933 }
else if (Kind == OMPC_linear) {
935 if (Tok.
is(tok::identifier) && PP.
LookAhead(0).
is(tok::l_paren)) {
939 LinearT.consumeOpen();
940 NeedRParenForLinear =
true;
942 }
else if (Kind == OMPC_map) {
951 bool ColonExpected =
false;
953 if (Tok.
is(tok::identifier)) {
958 Diag(Tok, diag::err_omp_unknown_map_type);
959 }
else if (MapType == OMPC_MAP_always) {
960 Diag(Tok, diag::err_omp_map_type_missing);
969 if (MapTypeModifier != OMPC_MAP_always) {
970 Diag(Tok, diag::err_omp_unknown_map_type_modifier);
973 MapTypeModifierSpecified =
true;
982 Diag(Tok, diag::err_omp_unknown_map_type);
986 MapType = OMPC_MAP_tofrom;
989 MapType = OMPC_MAP_tofrom;
995 if (Tok.
is(tok::colon)) {
997 }
else if (ColonExpected) {
998 Diag(Tok, diag::warn_pragma_expected_colon) <<
"map type";
1004 ((Kind != OMPC_reduction) && (Kind != OMPC_depend) &&
1005 (Kind != OMPC_map)) ||
1006 ((Kind == OMPC_reduction) && !InvalidReductionId) ||
1008 (!MapTypeModifierSpecified ||
1009 (MapTypeModifierSpecified && MapTypeModifier == OMPC_MAP_always))) ||
1011 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
1012 while (IsComma || (Tok.
isNot(tok::r_paren) && Tok.
isNot(tok::colon) &&
1013 Tok.
isNot(tok::annot_pragma_openmp_end))) {
1019 Vars.push_back(VarExpr.
get());
1021 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1025 IsComma = Tok.
is(tok::comma);
1028 else if (Tok.
isNot(tok::r_paren) &&
1029 Tok.
isNot(tok::annot_pragma_openmp_end) &&
1030 (!MayHaveTail || Tok.
isNot(tok::colon)))
1031 Diag(Tok, diag::err_omp_expected_punc)
1034 << (Kind == OMPC_flush);
1038 if (NeedRParenForLinear)
1039 LinearT.consumeClose();
1042 Expr *TailExpr =
nullptr;
1043 const bool MustHaveTail = MayHaveTail && Tok.
is(tok::colon);
1050 TailExpr = Tail.
get();
1052 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1059 (Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
1061 InvalidReductionId) {
1066 Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.
getLocation(),
1067 ReductionIdScopeSpec,
1070 DepKind, LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
Defines the clang::ASTContext interface.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
Scope * getCurScope() const
Retrieve the parser's current scope.
const Token & getCurToken() const
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
const LangOptions & getLangOpts() const
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc)
The base class of the type hierarchy.
This indicates that the scope corresponds to a function, which means that labels are set here...
bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind)
static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P)
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
Wrapper for void* pointer.
Parser - This implements a parser for the C family of languages.
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing...
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isEmpty() const
No scope specifier.
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
Base wrapper for a particular "section" of type source info.
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
Token - This structure provides full information about a lexed token.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
void EndOpenMPClause()
End analysis of clauses.
VerifyDiagnosticConsumer::Directive Directive
A location where the result (returned value) of evaluating a statement should be stored.
Represents a C++ unqualified-id that has been parsed.
OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str)
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
Represents a C++ nested-name-specifier or a global scope specifier.
tok::TokenKind getKind() const
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
A RAII object to enter scope of a compound statement.
void ActOnFinishOfCompoundStmt()
Expr - This represents one expression.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
This is the scope of OpenMP executable directive.
OpenMPClauseKind
OpenMP clauses.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isNot(tok::TokenKind K) const
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
ExprResult ActOnFinishFullExpr(Expr *Expr)
bool isValid() const
Determine whether this unqualified-id refers to a valid name.
void ActOnStartOfCompoundStmt()
Encodes a location in the source.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isValid() const
Return true if this is a valid SourceLocation object.
OpenMPDirectiveKind
OpenMP directives.
Scope * getCurScope() const
This is a basic class for representing single OpenMP clause.
Preprocessor & getPreprocessor() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, SourceLocation &TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
This is the scope of some OpenMP simd directive.
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Not an overloaded operator.
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
This file defines OpenMP AST classes for executable directives and clauses.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str)
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
This is a scope that can contain a declaration.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult{return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
This is the scope of some OpenMP loop directive.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
A trivial tuple used to represent a source range.
Directive - Abstract class representing a parsed verify directive.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
SourceLocation ColonLoc
Location of ':'.
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Stop skipping at specified token, but don't skip the token itself.
IdentifierInfo * getIdentifierInfo() const