ParseOpenMP.cpp 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815
  1. //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. /// \file
  10. /// \brief This file implements parsing of all OpenMP directives and clauses.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. #include "RAIIObjectsForParser.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/AST/StmtOpenMP.h"
  16. #include "clang/Parse/ParseDiagnostic.h"
  17. #include "clang/Parse/Parser.h"
  18. #include "clang/Sema/Scope.h"
  19. #include "llvm/ADT/PointerIntPair.h"
  20. using namespace clang;
  21. //===----------------------------------------------------------------------===//
  22. // OpenMP declarative directives.
  23. //===----------------------------------------------------------------------===//
  24. namespace {
  25. enum OpenMPDirectiveKindEx {
  26. OMPD_cancellation = OMPD_unknown + 1,
  27. OMPD_data,
  28. OMPD_declare,
  29. OMPD_end,
  30. OMPD_end_declare,
  31. OMPD_enter,
  32. OMPD_exit,
  33. OMPD_point,
  34. OMPD_reduction,
  35. OMPD_target_enter,
  36. OMPD_target_exit,
  37. OMPD_update,
  38. OMPD_distribute_parallel,
  39. OMPD_teams_distribute_parallel,
  40. OMPD_target_teams_distribute_parallel
  41. };
  42. class ThreadprivateListParserHelper final {
  43. SmallVector<Expr *, 4> Identifiers;
  44. Parser *P;
  45. public:
  46. ThreadprivateListParserHelper(Parser *P) : P(P) {}
  47. void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
  48. ExprResult Res =
  49. P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo);
  50. if (Res.isUsable())
  51. Identifiers.push_back(Res.get());
  52. }
  53. llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
  54. };
  55. } // namespace
  56. // Map token string to extended OMP token kind that are
  57. // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
  58. static unsigned getOpenMPDirectiveKindEx(StringRef S) {
  59. auto DKind = getOpenMPDirectiveKind(S);
  60. if (DKind != OMPD_unknown)
  61. return DKind;
  62. return llvm::StringSwitch<unsigned>(S)
  63. .Case("cancellation", OMPD_cancellation)
  64. .Case("data", OMPD_data)
  65. .Case("declare", OMPD_declare)
  66. .Case("end", OMPD_end)
  67. .Case("enter", OMPD_enter)
  68. .Case("exit", OMPD_exit)
  69. .Case("point", OMPD_point)
  70. .Case("reduction", OMPD_reduction)
  71. .Case("update", OMPD_update)
  72. .Default(OMPD_unknown);
  73. }
  74. static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
  75. // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
  76. // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
  77. // TODO: add other combined directives in topological order.
  78. static const unsigned F[][3] = {
  79. { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
  80. { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
  81. { OMPD_declare, OMPD_simd, OMPD_declare_simd },
  82. { OMPD_declare, OMPD_target, OMPD_declare_target },
  83. { OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel },
  84. { OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for },
  85. { OMPD_distribute_parallel_for, OMPD_simd,
  86. OMPD_distribute_parallel_for_simd },
  87. { OMPD_distribute, OMPD_simd, OMPD_distribute_simd },
  88. { OMPD_end, OMPD_declare, OMPD_end_declare },
  89. { OMPD_end_declare, OMPD_target, OMPD_end_declare_target },
  90. { OMPD_target, OMPD_data, OMPD_target_data },
  91. { OMPD_target, OMPD_enter, OMPD_target_enter },
  92. { OMPD_target, OMPD_exit, OMPD_target_exit },
  93. { OMPD_target, OMPD_update, OMPD_target_update },
  94. { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
  95. { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
  96. { OMPD_for, OMPD_simd, OMPD_for_simd },
  97. { OMPD_parallel, OMPD_for, OMPD_parallel_for },
  98. { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
  99. { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
  100. { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
  101. { OMPD_target, OMPD_parallel, OMPD_target_parallel },
  102. { OMPD_target, OMPD_simd, OMPD_target_simd },
  103. { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for },
  104. { OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd },
  105. { OMPD_teams, OMPD_distribute, OMPD_teams_distribute },
  106. { OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd },
  107. { OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel },
  108. { OMPD_teams_distribute_parallel, OMPD_for, OMPD_teams_distribute_parallel_for },
  109. { OMPD_teams_distribute_parallel_for, OMPD_simd, OMPD_teams_distribute_parallel_for_simd },
  110. { OMPD_target, OMPD_teams, OMPD_target_teams },
  111. { OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute },
  112. { OMPD_target_teams_distribute, OMPD_parallel, OMPD_target_teams_distribute_parallel },
  113. { OMPD_target_teams_distribute_parallel, OMPD_for, OMPD_target_teams_distribute_parallel_for }
  114. };
  115. enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
  116. auto Tok = P.getCurToken();
  117. unsigned DKind =
  118. Tok.isAnnotation()
  119. ? static_cast<unsigned>(OMPD_unknown)
  120. : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
  121. if (DKind == OMPD_unknown)
  122. return OMPD_unknown;
  123. for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
  124. if (DKind != F[i][0])
  125. continue;
  126. Tok = P.getPreprocessor().LookAhead(0);
  127. unsigned SDKind =
  128. Tok.isAnnotation()
  129. ? static_cast<unsigned>(OMPD_unknown)
  130. : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
  131. if (SDKind == OMPD_unknown)
  132. continue;
  133. if (SDKind == F[i][1]) {
  134. P.ConsumeToken();
  135. DKind = F[i][2];
  136. }
  137. }
  138. return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
  139. : OMPD_unknown;
  140. }
  141. static DeclarationName parseOpenMPReductionId(Parser &P) {
  142. Token Tok = P.getCurToken();
  143. Sema &Actions = P.getActions();
  144. OverloadedOperatorKind OOK = OO_None;
  145. // Allow to use 'operator' keyword for C++ operators
  146. bool WithOperator = false;
  147. if (Tok.is(tok::kw_operator)) {
  148. P.ConsumeToken();
  149. Tok = P.getCurToken();
  150. WithOperator = true;
  151. }
  152. switch (Tok.getKind()) {
  153. case tok::plus: // '+'
  154. OOK = OO_Plus;
  155. break;
  156. case tok::minus: // '-'
  157. OOK = OO_Minus;
  158. break;
  159. case tok::star: // '*'
  160. OOK = OO_Star;
  161. break;
  162. case tok::amp: // '&'
  163. OOK = OO_Amp;
  164. break;
  165. case tok::pipe: // '|'
  166. OOK = OO_Pipe;
  167. break;
  168. case tok::caret: // '^'
  169. OOK = OO_Caret;
  170. break;
  171. case tok::ampamp: // '&&'
  172. OOK = OO_AmpAmp;
  173. break;
  174. case tok::pipepipe: // '||'
  175. OOK = OO_PipePipe;
  176. break;
  177. case tok::identifier: // identifier
  178. if (!WithOperator)
  179. break;
  180. default:
  181. P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
  182. P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  183. Parser::StopBeforeMatch);
  184. return DeclarationName();
  185. }
  186. P.ConsumeToken();
  187. auto &DeclNames = Actions.getASTContext().DeclarationNames;
  188. return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
  189. : DeclNames.getCXXOperatorName(OOK);
  190. }
  191. /// \brief Parse 'omp declare reduction' construct.
  192. ///
  193. /// declare-reduction-directive:
  194. /// annot_pragma_openmp 'declare' 'reduction'
  195. /// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
  196. /// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
  197. /// annot_pragma_openmp_end
  198. /// <reduction_id> is either a base language identifier or one of the following
  199. /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
  200. ///
  201. Parser::DeclGroupPtrTy
  202. Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
  203. // Parse '('.
  204. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  205. if (T.expectAndConsume(diag::err_expected_lparen_after,
  206. getOpenMPDirectiveName(OMPD_declare_reduction))) {
  207. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  208. return DeclGroupPtrTy();
  209. }
  210. DeclarationName Name = parseOpenMPReductionId(*this);
  211. if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
  212. return DeclGroupPtrTy();
  213. // Consume ':'.
  214. bool IsCorrect = !ExpectAndConsume(tok::colon);
  215. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  216. return DeclGroupPtrTy();
  217. IsCorrect = IsCorrect && !Name.isEmpty();
  218. if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
  219. Diag(Tok.getLocation(), diag::err_expected_type);
  220. IsCorrect = false;
  221. }
  222. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  223. return DeclGroupPtrTy();
  224. SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
  225. // Parse list of types until ':' token.
  226. do {
  227. ColonProtectionRAIIObject ColonRAII(*this);
  228. SourceRange Range;
  229. TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
  230. if (TR.isUsable()) {
  231. auto ReductionType =
  232. Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
  233. if (!ReductionType.isNull()) {
  234. ReductionTypes.push_back(
  235. std::make_pair(ReductionType, Range.getBegin()));
  236. }
  237. } else {
  238. SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
  239. StopBeforeMatch);
  240. }
  241. if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
  242. break;
  243. // Consume ','.
  244. if (ExpectAndConsume(tok::comma)) {
  245. IsCorrect = false;
  246. if (Tok.is(tok::annot_pragma_openmp_end)) {
  247. Diag(Tok.getLocation(), diag::err_expected_type);
  248. return DeclGroupPtrTy();
  249. }
  250. }
  251. } while (Tok.isNot(tok::annot_pragma_openmp_end));
  252. if (ReductionTypes.empty()) {
  253. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  254. return DeclGroupPtrTy();
  255. }
  256. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  257. return DeclGroupPtrTy();
  258. // Consume ':'.
  259. if (ExpectAndConsume(tok::colon))
  260. IsCorrect = false;
  261. if (Tok.is(tok::annot_pragma_openmp_end)) {
  262. Diag(Tok.getLocation(), diag::err_expected_expression);
  263. return DeclGroupPtrTy();
  264. }
  265. DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
  266. getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
  267. // Parse <combiner> expression and then parse initializer if any for each
  268. // correct type.
  269. unsigned I = 0, E = ReductionTypes.size();
  270. for (auto *D : DRD.get()) {
  271. TentativeParsingAction TPA(*this);
  272. ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
  273. Scope::OpenMPDirectiveScope);
  274. // Parse <combiner> expression.
  275. Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
  276. ExprResult CombinerResult =
  277. Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
  278. D->getLocation(), /*DiscardedValue=*/true);
  279. Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
  280. if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
  281. Tok.isNot(tok::annot_pragma_openmp_end)) {
  282. TPA.Commit();
  283. IsCorrect = false;
  284. break;
  285. }
  286. IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
  287. ExprResult InitializerResult;
  288. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  289. // Parse <initializer> expression.
  290. if (Tok.is(tok::identifier) &&
  291. Tok.getIdentifierInfo()->isStr("initializer"))
  292. ConsumeToken();
  293. else {
  294. Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
  295. TPA.Commit();
  296. IsCorrect = false;
  297. break;
  298. }
  299. // Parse '('.
  300. BalancedDelimiterTracker T(*this, tok::l_paren,
  301. tok::annot_pragma_openmp_end);
  302. IsCorrect =
  303. !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
  304. IsCorrect;
  305. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  306. ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
  307. Scope::OpenMPDirectiveScope);
  308. // Parse expression.
  309. Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D);
  310. InitializerResult = Actions.ActOnFinishFullExpr(
  311. ParseAssignmentExpression().get(), D->getLocation(),
  312. /*DiscardedValue=*/true);
  313. Actions.ActOnOpenMPDeclareReductionInitializerEnd(
  314. D, InitializerResult.get());
  315. if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
  316. Tok.isNot(tok::annot_pragma_openmp_end)) {
  317. TPA.Commit();
  318. IsCorrect = false;
  319. break;
  320. }
  321. IsCorrect =
  322. !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
  323. }
  324. }
  325. ++I;
  326. // Revert parsing if not the last type, otherwise accept it, we're done with
  327. // parsing.
  328. if (I != E)
  329. TPA.Revert();
  330. else
  331. TPA.Commit();
  332. }
  333. return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
  334. IsCorrect);
  335. }
  336. namespace {
  337. /// RAII that recreates function context for correct parsing of clauses of
  338. /// 'declare simd' construct.
  339. /// OpenMP, 2.8.2 declare simd Construct
  340. /// The expressions appearing in the clauses of this directive are evaluated in
  341. /// the scope of the arguments of the function declaration or definition.
  342. class FNContextRAII final {
  343. Parser &P;
  344. Sema::CXXThisScopeRAII *ThisScope;
  345. Parser::ParseScope *TempScope;
  346. Parser::ParseScope *FnScope;
  347. bool HasTemplateScope = false;
  348. bool HasFunScope = false;
  349. FNContextRAII() = delete;
  350. FNContextRAII(const FNContextRAII &) = delete;
  351. FNContextRAII &operator=(const FNContextRAII &) = delete;
  352. public:
  353. FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
  354. Decl *D = *Ptr.get().begin();
  355. NamedDecl *ND = dyn_cast<NamedDecl>(D);
  356. RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
  357. Sema &Actions = P.getActions();
  358. // Allow 'this' within late-parsed attributes.
  359. ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0,
  360. ND && ND->isCXXInstanceMember());
  361. // If the Decl is templatized, add template parameters to scope.
  362. HasTemplateScope = D->isTemplateDecl();
  363. TempScope =
  364. new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
  365. if (HasTemplateScope)
  366. Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
  367. // If the Decl is on a function, add function parameters to the scope.
  368. HasFunScope = D->isFunctionOrFunctionTemplate();
  369. FnScope = new Parser::ParseScope(&P, Scope::FnScope | Scope::DeclScope,
  370. HasFunScope);
  371. if (HasFunScope)
  372. Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
  373. }
  374. ~FNContextRAII() {
  375. if (HasFunScope) {
  376. P.getActions().ActOnExitFunctionContext();
  377. FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
  378. }
  379. if (HasTemplateScope)
  380. TempScope->Exit();
  381. delete FnScope;
  382. delete TempScope;
  383. delete ThisScope;
  384. }
  385. };
  386. } // namespace
  387. /// Parses clauses for 'declare simd' directive.
  388. /// clause:
  389. /// 'inbranch' | 'notinbranch'
  390. /// 'simdlen' '(' <expr> ')'
  391. /// { 'uniform' '(' <argument_list> ')' }
  392. /// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
  393. /// { 'linear '(' <argument_list> [ ':' <step> ] ')' }
  394. static bool parseDeclareSimdClauses(
  395. Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
  396. SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
  397. SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
  398. SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
  399. SourceRange BSRange;
  400. const Token &Tok = P.getCurToken();
  401. bool IsError = false;
  402. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  403. if (Tok.isNot(tok::identifier))
  404. break;
  405. OMPDeclareSimdDeclAttr::BranchStateTy Out;
  406. IdentifierInfo *II = Tok.getIdentifierInfo();
  407. StringRef ClauseName = II->getName();
  408. // Parse 'inranch|notinbranch' clauses.
  409. if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
  410. if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
  411. P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
  412. << ClauseName
  413. << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
  414. IsError = true;
  415. }
  416. BS = Out;
  417. BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
  418. P.ConsumeToken();
  419. } else if (ClauseName.equals("simdlen")) {
  420. if (SimdLen.isUsable()) {
  421. P.Diag(Tok, diag::err_omp_more_one_clause)
  422. << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
  423. IsError = true;
  424. }
  425. P.ConsumeToken();
  426. SourceLocation RLoc;
  427. SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
  428. if (SimdLen.isInvalid())
  429. IsError = true;
  430. } else {
  431. OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
  432. if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
  433. CKind == OMPC_linear) {
  434. Parser::OpenMPVarListDataTy Data;
  435. auto *Vars = &Uniforms;
  436. if (CKind == OMPC_aligned)
  437. Vars = &Aligneds;
  438. else if (CKind == OMPC_linear)
  439. Vars = &Linears;
  440. P.ConsumeToken();
  441. if (P.ParseOpenMPVarList(OMPD_declare_simd,
  442. getOpenMPClauseKind(ClauseName), *Vars, Data))
  443. IsError = true;
  444. if (CKind == OMPC_aligned)
  445. Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
  446. else if (CKind == OMPC_linear) {
  447. if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
  448. Data.DepLinMapLoc))
  449. Data.LinKind = OMPC_LINEAR_val;
  450. LinModifiers.append(Linears.size() - LinModifiers.size(),
  451. Data.LinKind);
  452. Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
  453. }
  454. } else
  455. // TODO: add parsing of other clauses.
  456. break;
  457. }
  458. // Skip ',' if any.
  459. if (Tok.is(tok::comma))
  460. P.ConsumeToken();
  461. }
  462. return IsError;
  463. }
  464. /// Parse clauses for '#pragma omp declare simd'.
  465. Parser::DeclGroupPtrTy
  466. Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
  467. CachedTokens &Toks, SourceLocation Loc) {
  468. PP.EnterToken(Tok);
  469. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
  470. // Consume the previously pushed token.
  471. ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
  472. FNContextRAII FnContext(*this, Ptr);
  473. OMPDeclareSimdDeclAttr::BranchStateTy BS =
  474. OMPDeclareSimdDeclAttr::BS_Undefined;
  475. ExprResult Simdlen;
  476. SmallVector<Expr *, 4> Uniforms;
  477. SmallVector<Expr *, 4> Aligneds;
  478. SmallVector<Expr *, 4> Alignments;
  479. SmallVector<Expr *, 4> Linears;
  480. SmallVector<unsigned, 4> LinModifiers;
  481. SmallVector<Expr *, 4> Steps;
  482. bool IsError =
  483. parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
  484. Alignments, Linears, LinModifiers, Steps);
  485. // Need to check for extra tokens.
  486. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  487. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  488. << getOpenMPDirectiveName(OMPD_declare_simd);
  489. while (Tok.isNot(tok::annot_pragma_openmp_end))
  490. ConsumeAnyToken();
  491. }
  492. // Skip the last annot_pragma_openmp_end.
  493. SourceLocation EndLoc = ConsumeToken();
  494. if (!IsError) {
  495. return Actions.ActOnOpenMPDeclareSimdDirective(
  496. Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
  497. LinModifiers, Steps, SourceRange(Loc, EndLoc));
  498. }
  499. return Ptr;
  500. }
  501. /// \brief Parsing of declarative OpenMP directives.
  502. ///
  503. /// threadprivate-directive:
  504. /// annot_pragma_openmp 'threadprivate' simple-variable-list
  505. /// annot_pragma_openmp_end
  506. ///
  507. /// declare-reduction-directive:
  508. /// annot_pragma_openmp 'declare' 'reduction' [...]
  509. /// annot_pragma_openmp_end
  510. ///
  511. /// declare-simd-directive:
  512. /// annot_pragma_openmp 'declare simd' {<clause> [,]}
  513. /// annot_pragma_openmp_end
  514. /// <function declaration/definition>
  515. ///
  516. Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
  517. AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
  518. DeclSpec::TST TagType, Decl *Tag) {
  519. assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  520. ParenBraceBracketBalancer BalancerRAIIObj(*this);
  521. SourceLocation Loc = ConsumeToken();
  522. auto DKind = ParseOpenMPDirectiveKind(*this);
  523. switch (DKind) {
  524. case OMPD_threadprivate: {
  525. ConsumeToken();
  526. ThreadprivateListParserHelper Helper(this);
  527. if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) {
  528. // The last seen token is annot_pragma_openmp_end - need to check for
  529. // extra tokens.
  530. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  531. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  532. << getOpenMPDirectiveName(OMPD_threadprivate);
  533. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  534. }
  535. // Skip the last annot_pragma_openmp_end.
  536. ConsumeToken();
  537. return Actions.ActOnOpenMPThreadprivateDirective(Loc,
  538. Helper.getIdentifiers());
  539. }
  540. break;
  541. }
  542. case OMPD_declare_reduction:
  543. ConsumeToken();
  544. if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
  545. // The last seen token is annot_pragma_openmp_end - need to check for
  546. // extra tokens.
  547. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  548. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  549. << getOpenMPDirectiveName(OMPD_declare_reduction);
  550. while (Tok.isNot(tok::annot_pragma_openmp_end))
  551. ConsumeAnyToken();
  552. }
  553. // Skip the last annot_pragma_openmp_end.
  554. ConsumeToken();
  555. return Res;
  556. }
  557. break;
  558. case OMPD_declare_simd: {
  559. // The syntax is:
  560. // { #pragma omp declare simd }
  561. // <function-declaration-or-definition>
  562. //
  563. ConsumeToken();
  564. CachedTokens Toks;
  565. while(Tok.isNot(tok::annot_pragma_openmp_end)) {
  566. Toks.push_back(Tok);
  567. ConsumeAnyToken();
  568. }
  569. Toks.push_back(Tok);
  570. ConsumeAnyToken();
  571. DeclGroupPtrTy Ptr;
  572. if (Tok.is(tok::annot_pragma_openmp))
  573. Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
  574. else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
  575. // Here we expect to see some function declaration.
  576. if (AS == AS_none) {
  577. assert(TagType == DeclSpec::TST_unspecified);
  578. MaybeParseCXX11Attributes(Attrs);
  579. ParsingDeclSpec PDS(*this);
  580. Ptr = ParseExternalDeclaration(Attrs, &PDS);
  581. } else {
  582. Ptr =
  583. ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
  584. }
  585. }
  586. if (!Ptr) {
  587. Diag(Loc, diag::err_omp_decl_in_declare_simd);
  588. return DeclGroupPtrTy();
  589. }
  590. return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
  591. }
  592. case OMPD_declare_target: {
  593. SourceLocation DTLoc = ConsumeAnyToken();
  594. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  595. // OpenMP 4.5 syntax with list of entities.
  596. llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls;
  597. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  598. OMPDeclareTargetDeclAttr::MapTypeTy MT =
  599. OMPDeclareTargetDeclAttr::MT_To;
  600. if (Tok.is(tok::identifier)) {
  601. IdentifierInfo *II = Tok.getIdentifierInfo();
  602. StringRef ClauseName = II->getName();
  603. // Parse 'to|link' clauses.
  604. if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
  605. MT)) {
  606. Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
  607. << ClauseName;
  608. break;
  609. }
  610. ConsumeToken();
  611. }
  612. auto Callback = [this, MT, &SameDirectiveDecls](
  613. CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
  614. Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
  615. SameDirectiveDecls);
  616. };
  617. if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true))
  618. break;
  619. // Consume optional ','.
  620. if (Tok.is(tok::comma))
  621. ConsumeToken();
  622. }
  623. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  624. ConsumeAnyToken();
  625. return DeclGroupPtrTy();
  626. }
  627. // Skip the last annot_pragma_openmp_end.
  628. ConsumeAnyToken();
  629. if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
  630. return DeclGroupPtrTy();
  631. DKind = ParseOpenMPDirectiveKind(*this);
  632. while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
  633. Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) {
  634. ParsedAttributesWithRange attrs(AttrFactory);
  635. MaybeParseCXX11Attributes(attrs);
  636. ParseExternalDeclaration(attrs);
  637. if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
  638. TentativeParsingAction TPA(*this);
  639. ConsumeToken();
  640. DKind = ParseOpenMPDirectiveKind(*this);
  641. if (DKind != OMPD_end_declare_target)
  642. TPA.Revert();
  643. else
  644. TPA.Commit();
  645. }
  646. }
  647. if (DKind == OMPD_end_declare_target) {
  648. ConsumeAnyToken();
  649. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  650. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  651. << getOpenMPDirectiveName(OMPD_end_declare_target);
  652. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  653. }
  654. // Skip the last annot_pragma_openmp_end.
  655. ConsumeAnyToken();
  656. } else {
  657. Diag(Tok, diag::err_expected_end_declare_target);
  658. Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
  659. }
  660. Actions.ActOnFinishOpenMPDeclareTargetDirective();
  661. return DeclGroupPtrTy();
  662. }
  663. case OMPD_unknown:
  664. Diag(Tok, diag::err_omp_unknown_directive);
  665. break;
  666. case OMPD_parallel:
  667. case OMPD_simd:
  668. case OMPD_task:
  669. case OMPD_taskyield:
  670. case OMPD_barrier:
  671. case OMPD_taskwait:
  672. case OMPD_taskgroup:
  673. case OMPD_flush:
  674. case OMPD_for:
  675. case OMPD_for_simd:
  676. case OMPD_sections:
  677. case OMPD_section:
  678. case OMPD_single:
  679. case OMPD_master:
  680. case OMPD_ordered:
  681. case OMPD_critical:
  682. case OMPD_parallel_for:
  683. case OMPD_parallel_for_simd:
  684. case OMPD_parallel_sections:
  685. case OMPD_atomic:
  686. case OMPD_target:
  687. case OMPD_teams:
  688. case OMPD_cancellation_point:
  689. case OMPD_cancel:
  690. case OMPD_target_data:
  691. case OMPD_target_enter_data:
  692. case OMPD_target_exit_data:
  693. case OMPD_target_parallel:
  694. case OMPD_target_parallel_for:
  695. case OMPD_taskloop:
  696. case OMPD_taskloop_simd:
  697. case OMPD_distribute:
  698. case OMPD_end_declare_target:
  699. case OMPD_target_update:
  700. case OMPD_distribute_parallel_for:
  701. case OMPD_distribute_parallel_for_simd:
  702. case OMPD_distribute_simd:
  703. case OMPD_target_parallel_for_simd:
  704. case OMPD_target_simd:
  705. case OMPD_teams_distribute:
  706. case OMPD_teams_distribute_simd:
  707. case OMPD_teams_distribute_parallel_for_simd:
  708. case OMPD_teams_distribute_parallel_for:
  709. case OMPD_target_teams:
  710. case OMPD_target_teams_distribute:
  711. case OMPD_target_teams_distribute_parallel_for:
  712. Diag(Tok, diag::err_omp_unexpected_directive)
  713. << getOpenMPDirectiveName(DKind);
  714. break;
  715. }
  716. while (Tok.isNot(tok::annot_pragma_openmp_end))
  717. ConsumeAnyToken();
  718. ConsumeAnyToken();
  719. return nullptr;
  720. }
  721. /// \brief Parsing of declarative or executable OpenMP directives.
  722. ///
  723. /// threadprivate-directive:
  724. /// annot_pragma_openmp 'threadprivate' simple-variable-list
  725. /// annot_pragma_openmp_end
  726. ///
  727. /// declare-reduction-directive:
  728. /// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
  729. /// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
  730. /// ('omp_priv' '=' <expression>|<function_call>) ')']
  731. /// annot_pragma_openmp_end
  732. ///
  733. /// executable-directive:
  734. /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
  735. /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
  736. /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
  737. /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
  738. /// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
  739. /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
  740. /// 'distribute' | 'target enter data' | 'target exit data' |
  741. /// 'target parallel' | 'target parallel for' |
  742. /// 'target update' | 'distribute parallel for' |
  743. /// 'distribute paralle for simd' | 'distribute simd' |
  744. /// 'target parallel for simd' | 'target simd' |
  745. /// 'teams distribute' | 'teams distribute simd' |
  746. /// 'teams distribute parallel for simd' |
  747. /// 'teams distribute parallel for' | 'target teams' |
  748. /// 'target teams distribute' |
  749. /// 'target teams distribute parallel for' {clause}
  750. /// annot_pragma_openmp_end
  751. ///
  752. StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
  753. AllowedContsructsKind Allowed) {
  754. assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  755. ParenBraceBracketBalancer BalancerRAIIObj(*this);
  756. SmallVector<OMPClause *, 5> Clauses;
  757. SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
  758. FirstClauses(OMPC_unknown + 1);
  759. unsigned ScopeFlags =
  760. Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
  761. SourceLocation Loc = ConsumeToken(), EndLoc;
  762. auto DKind = ParseOpenMPDirectiveKind(*this);
  763. OpenMPDirectiveKind CancelRegion = OMPD_unknown;
  764. // Name of critical directive.
  765. DeclarationNameInfo DirName;
  766. StmtResult Directive = StmtError();
  767. bool HasAssociatedStatement = true;
  768. bool FlushHasClause = false;
  769. switch (DKind) {
  770. case OMPD_threadprivate: {
  771. if (Allowed != ACK_Any) {
  772. Diag(Tok, diag::err_omp_immediate_directive)
  773. << getOpenMPDirectiveName(DKind) << 0;
  774. }
  775. ConsumeToken();
  776. ThreadprivateListParserHelper Helper(this);
  777. if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) {
  778. // The last seen token is annot_pragma_openmp_end - need to check for
  779. // extra tokens.
  780. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  781. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  782. << getOpenMPDirectiveName(OMPD_threadprivate);
  783. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  784. }
  785. DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
  786. Loc, Helper.getIdentifiers());
  787. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  788. }
  789. SkipUntil(tok::annot_pragma_openmp_end);
  790. break;
  791. }
  792. case OMPD_declare_reduction:
  793. ConsumeToken();
  794. if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
  795. // The last seen token is annot_pragma_openmp_end - need to check for
  796. // extra tokens.
  797. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  798. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  799. << getOpenMPDirectiveName(OMPD_declare_reduction);
  800. while (Tok.isNot(tok::annot_pragma_openmp_end))
  801. ConsumeAnyToken();
  802. }
  803. ConsumeAnyToken();
  804. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  805. } else
  806. SkipUntil(tok::annot_pragma_openmp_end);
  807. break;
  808. case OMPD_flush:
  809. if (PP.LookAhead(0).is(tok::l_paren)) {
  810. FlushHasClause = true;
  811. // Push copy of the current token back to stream to properly parse
  812. // pseudo-clause OMPFlushClause.
  813. PP.EnterToken(Tok);
  814. }
  815. case OMPD_taskyield:
  816. case OMPD_barrier:
  817. case OMPD_taskwait:
  818. case OMPD_cancellation_point:
  819. case OMPD_cancel:
  820. case OMPD_target_enter_data:
  821. case OMPD_target_exit_data:
  822. case OMPD_target_update:
  823. if (Allowed == ACK_StatementsOpenMPNonStandalone) {
  824. Diag(Tok, diag::err_omp_immediate_directive)
  825. << getOpenMPDirectiveName(DKind) << 0;
  826. }
  827. HasAssociatedStatement = false;
  828. // Fall through for further analysis.
  829. case OMPD_parallel:
  830. case OMPD_simd:
  831. case OMPD_for:
  832. case OMPD_for_simd:
  833. case OMPD_sections:
  834. case OMPD_single:
  835. case OMPD_section:
  836. case OMPD_master:
  837. case OMPD_critical:
  838. case OMPD_parallel_for:
  839. case OMPD_parallel_for_simd:
  840. case OMPD_parallel_sections:
  841. case OMPD_task:
  842. case OMPD_ordered:
  843. case OMPD_atomic:
  844. case OMPD_target:
  845. case OMPD_teams:
  846. case OMPD_taskgroup:
  847. case OMPD_target_data:
  848. case OMPD_target_parallel:
  849. case OMPD_target_parallel_for:
  850. case OMPD_taskloop:
  851. case OMPD_taskloop_simd:
  852. case OMPD_distribute:
  853. case OMPD_distribute_parallel_for:
  854. case OMPD_distribute_parallel_for_simd:
  855. case OMPD_distribute_simd:
  856. case OMPD_target_parallel_for_simd:
  857. case OMPD_target_simd:
  858. case OMPD_teams_distribute:
  859. case OMPD_teams_distribute_simd:
  860. case OMPD_teams_distribute_parallel_for_simd:
  861. case OMPD_teams_distribute_parallel_for:
  862. case OMPD_target_teams:
  863. case OMPD_target_teams_distribute:
  864. case OMPD_target_teams_distribute_parallel_for: {
  865. ConsumeToken();
  866. // Parse directive name of the 'critical' directive if any.
  867. if (DKind == OMPD_critical) {
  868. BalancedDelimiterTracker T(*this, tok::l_paren,
  869. tok::annot_pragma_openmp_end);
  870. if (!T.consumeOpen()) {
  871. if (Tok.isAnyIdentifier()) {
  872. DirName =
  873. DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
  874. ConsumeAnyToken();
  875. } else {
  876. Diag(Tok, diag::err_omp_expected_identifier_for_critical);
  877. }
  878. T.consumeClose();
  879. }
  880. } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
  881. CancelRegion = ParseOpenMPDirectiveKind(*this);
  882. if (Tok.isNot(tok::annot_pragma_openmp_end))
  883. ConsumeToken();
  884. }
  885. if (isOpenMPLoopDirective(DKind))
  886. ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
  887. if (isOpenMPSimdDirective(DKind))
  888. ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
  889. ParseScope OMPDirectiveScope(this, ScopeFlags);
  890. Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
  891. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  892. OpenMPClauseKind CKind =
  893. Tok.isAnnotation()
  894. ? OMPC_unknown
  895. : FlushHasClause ? OMPC_flush
  896. : getOpenMPClauseKind(PP.getSpelling(Tok));
  897. Actions.StartOpenMPClause(CKind);
  898. FlushHasClause = false;
  899. OMPClause *Clause =
  900. ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
  901. FirstClauses[CKind].setInt(true);
  902. if (Clause) {
  903. FirstClauses[CKind].setPointer(Clause);
  904. Clauses.push_back(Clause);
  905. }
  906. // Skip ',' if any.
  907. if (Tok.is(tok::comma))
  908. ConsumeToken();
  909. Actions.EndOpenMPClause();
  910. }
  911. // End location of the directive.
  912. EndLoc = Tok.getLocation();
  913. // Consume final annot_pragma_openmp_end.
  914. ConsumeToken();
  915. // OpenMP [2.13.8, ordered Construct, Syntax]
  916. // If the depend clause is specified, the ordered construct is a stand-alone
  917. // directive.
  918. if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
  919. if (Allowed == ACK_StatementsOpenMPNonStandalone) {
  920. Diag(Loc, diag::err_omp_immediate_directive)
  921. << getOpenMPDirectiveName(DKind) << 1
  922. << getOpenMPClauseName(OMPC_depend);
  923. }
  924. HasAssociatedStatement = false;
  925. }
  926. StmtResult AssociatedStmt;
  927. if (HasAssociatedStatement) {
  928. // The body is a block scope like in Lambdas and Blocks.
  929. Sema::CompoundScopeRAII CompoundScope(Actions);
  930. Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
  931. Actions.ActOnStartOfCompoundStmt();
  932. // Parse statement
  933. AssociatedStmt = ParseStatement();
  934. Actions.ActOnFinishOfCompoundStmt();
  935. AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
  936. }
  937. Directive = Actions.ActOnOpenMPExecutableDirective(
  938. DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
  939. EndLoc);
  940. // Exit scope.
  941. Actions.EndOpenMPDSABlock(Directive.get());
  942. OMPDirectiveScope.Exit();
  943. break;
  944. }
  945. case OMPD_declare_simd:
  946. case OMPD_declare_target:
  947. case OMPD_end_declare_target:
  948. Diag(Tok, diag::err_omp_unexpected_directive)
  949. << getOpenMPDirectiveName(DKind);
  950. SkipUntil(tok::annot_pragma_openmp_end);
  951. break;
  952. case OMPD_unknown:
  953. Diag(Tok, diag::err_omp_unknown_directive);
  954. SkipUntil(tok::annot_pragma_openmp_end);
  955. break;
  956. }
  957. return Directive;
  958. }
  959. // Parses simple list:
  960. // simple-variable-list:
  961. // '(' id-expression {, id-expression} ')'
  962. //
  963. bool Parser::ParseOpenMPSimpleVarList(
  964. OpenMPDirectiveKind Kind,
  965. const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
  966. Callback,
  967. bool AllowScopeSpecifier) {
  968. // Parse '('.
  969. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  970. if (T.expectAndConsume(diag::err_expected_lparen_after,
  971. getOpenMPDirectiveName(Kind)))
  972. return true;
  973. bool IsCorrect = true;
  974. bool NoIdentIsFound = true;
  975. // Read tokens while ')' or annot_pragma_openmp_end is not found.
  976. while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
  977. CXXScopeSpec SS;
  978. SourceLocation TemplateKWLoc;
  979. UnqualifiedId Name;
  980. // Read var name.
  981. Token PrevTok = Tok;
  982. NoIdentIsFound = false;
  983. if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
  984. ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
  985. IsCorrect = false;
  986. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  987. StopBeforeMatch);
  988. } else if (ParseUnqualifiedId(SS, false, false, false, nullptr,
  989. TemplateKWLoc, Name)) {
  990. IsCorrect = false;
  991. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  992. StopBeforeMatch);
  993. } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
  994. Tok.isNot(tok::annot_pragma_openmp_end)) {
  995. IsCorrect = false;
  996. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  997. StopBeforeMatch);
  998. Diag(PrevTok.getLocation(), diag::err_expected)
  999. << tok::identifier
  1000. << SourceRange(PrevTok.getLocation(), PrevTokLocation);
  1001. } else {
  1002. Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
  1003. }
  1004. // Consume ','.
  1005. if (Tok.is(tok::comma)) {
  1006. ConsumeToken();
  1007. }
  1008. }
  1009. if (NoIdentIsFound) {
  1010. Diag(Tok, diag::err_expected) << tok::identifier;
  1011. IsCorrect = false;
  1012. }
  1013. // Parse ')'.
  1014. IsCorrect = !T.consumeClose() && IsCorrect;
  1015. return !IsCorrect;
  1016. }
  1017. /// \brief Parsing of OpenMP clauses.
  1018. ///
  1019. /// clause:
  1020. /// if-clause | final-clause | num_threads-clause | safelen-clause |
  1021. /// default-clause | private-clause | firstprivate-clause | shared-clause
  1022. /// | linear-clause | aligned-clause | collapse-clause |
  1023. /// lastprivate-clause | reduction-clause | proc_bind-clause |
  1024. /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
  1025. /// mergeable-clause | flush-clause | read-clause | write-clause |
  1026. /// update-clause | capture-clause | seq_cst-clause | device-clause |
  1027. /// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
  1028. /// thread_limit-clause | priority-clause | grainsize-clause |
  1029. /// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
  1030. /// from-clause | is_device_ptr-clause
  1031. ///
  1032. OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
  1033. OpenMPClauseKind CKind, bool FirstClause) {
  1034. OMPClause *Clause = nullptr;
  1035. bool ErrorFound = false;
  1036. // Check if clause is allowed for the given directive.
  1037. if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
  1038. Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
  1039. << getOpenMPDirectiveName(DKind);
  1040. ErrorFound = true;
  1041. }
  1042. switch (CKind) {
  1043. case OMPC_final:
  1044. case OMPC_num_threads:
  1045. case OMPC_safelen:
  1046. case OMPC_simdlen:
  1047. case OMPC_collapse:
  1048. case OMPC_ordered:
  1049. case OMPC_device:
  1050. case OMPC_num_teams:
  1051. case OMPC_thread_limit:
  1052. case OMPC_priority:
  1053. case OMPC_grainsize:
  1054. case OMPC_num_tasks:
  1055. case OMPC_hint:
  1056. // OpenMP [2.5, Restrictions]
  1057. // At most one num_threads clause can appear on the directive.
  1058. // OpenMP [2.8.1, simd construct, Restrictions]
  1059. // Only one safelen clause can appear on a simd directive.
  1060. // Only one simdlen clause can appear on a simd directive.
  1061. // Only one collapse clause can appear on a simd directive.
  1062. // OpenMP [2.9.1, target data construct, Restrictions]
  1063. // At most one device clause can appear on the directive.
  1064. // OpenMP [2.11.1, task Construct, Restrictions]
  1065. // At most one if clause can appear on the directive.
  1066. // At most one final clause can appear on the directive.
  1067. // OpenMP [teams Construct, Restrictions]
  1068. // At most one num_teams clause can appear on the directive.
  1069. // At most one thread_limit clause can appear on the directive.
  1070. // OpenMP [2.9.1, task Construct, Restrictions]
  1071. // At most one priority clause can appear on the directive.
  1072. // OpenMP [2.9.2, taskloop Construct, Restrictions]
  1073. // At most one grainsize clause can appear on the directive.
  1074. // OpenMP [2.9.2, taskloop Construct, Restrictions]
  1075. // At most one num_tasks clause can appear on the directive.
  1076. if (!FirstClause) {
  1077. Diag(Tok, diag::err_omp_more_one_clause)
  1078. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1079. ErrorFound = true;
  1080. }
  1081. if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
  1082. Clause = ParseOpenMPClause(CKind);
  1083. else
  1084. Clause = ParseOpenMPSingleExprClause(CKind);
  1085. break;
  1086. case OMPC_default:
  1087. case OMPC_proc_bind:
  1088. // OpenMP [2.14.3.1, Restrictions]
  1089. // Only a single default clause may be specified on a parallel, task or
  1090. // teams directive.
  1091. // OpenMP [2.5, parallel Construct, Restrictions]
  1092. // At most one proc_bind clause can appear on the directive.
  1093. if (!FirstClause) {
  1094. Diag(Tok, diag::err_omp_more_one_clause)
  1095. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1096. ErrorFound = true;
  1097. }
  1098. Clause = ParseOpenMPSimpleClause(CKind);
  1099. break;
  1100. case OMPC_schedule:
  1101. case OMPC_dist_schedule:
  1102. case OMPC_defaultmap:
  1103. // OpenMP [2.7.1, Restrictions, p. 3]
  1104. // Only one schedule clause can appear on a loop directive.
  1105. // OpenMP [2.10.4, Restrictions, p. 106]
  1106. // At most one defaultmap clause can appear on the directive.
  1107. if (!FirstClause) {
  1108. Diag(Tok, diag::err_omp_more_one_clause)
  1109. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1110. ErrorFound = true;
  1111. }
  1112. case OMPC_if:
  1113. Clause = ParseOpenMPSingleExprWithArgClause(CKind);
  1114. break;
  1115. case OMPC_nowait:
  1116. case OMPC_untied:
  1117. case OMPC_mergeable:
  1118. case OMPC_read:
  1119. case OMPC_write:
  1120. case OMPC_update:
  1121. case OMPC_capture:
  1122. case OMPC_seq_cst:
  1123. case OMPC_threads:
  1124. case OMPC_simd:
  1125. case OMPC_nogroup:
  1126. // OpenMP [2.7.1, Restrictions, p. 9]
  1127. // Only one ordered clause can appear on a loop directive.
  1128. // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
  1129. // Only one nowait clause can appear on a for directive.
  1130. if (!FirstClause) {
  1131. Diag(Tok, diag::err_omp_more_one_clause)
  1132. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1133. ErrorFound = true;
  1134. }
  1135. Clause = ParseOpenMPClause(CKind);
  1136. break;
  1137. case OMPC_private:
  1138. case OMPC_firstprivate:
  1139. case OMPC_lastprivate:
  1140. case OMPC_shared:
  1141. case OMPC_reduction:
  1142. case OMPC_linear:
  1143. case OMPC_aligned:
  1144. case OMPC_copyin:
  1145. case OMPC_copyprivate:
  1146. case OMPC_flush:
  1147. case OMPC_depend:
  1148. case OMPC_map:
  1149. case OMPC_to:
  1150. case OMPC_from:
  1151. case OMPC_use_device_ptr:
  1152. case OMPC_is_device_ptr:
  1153. Clause = ParseOpenMPVarListClause(DKind, CKind);
  1154. break;
  1155. case OMPC_unknown:
  1156. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  1157. << getOpenMPDirectiveName(DKind);
  1158. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  1159. break;
  1160. case OMPC_threadprivate:
  1161. case OMPC_uniform:
  1162. Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
  1163. << getOpenMPDirectiveName(DKind);
  1164. SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
  1165. break;
  1166. }
  1167. return ErrorFound ? nullptr : Clause;
  1168. }
  1169. /// Parses simple expression in parens for single-expression clauses of OpenMP
  1170. /// constructs.
  1171. /// \param RLoc Returned location of right paren.
  1172. ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
  1173. SourceLocation &RLoc) {
  1174. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1175. if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
  1176. return ExprError();
  1177. SourceLocation ELoc = Tok.getLocation();
  1178. ExprResult LHS(ParseCastExpression(
  1179. /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
  1180. ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
  1181. Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
  1182. // Parse ')'.
  1183. T.consumeClose();
  1184. RLoc = T.getCloseLocation();
  1185. return Val;
  1186. }
  1187. /// \brief Parsing of OpenMP clauses with single expressions like 'final',
  1188. /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
  1189. /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
  1190. ///
  1191. /// final-clause:
  1192. /// 'final' '(' expression ')'
  1193. ///
  1194. /// num_threads-clause:
  1195. /// 'num_threads' '(' expression ')'
  1196. ///
  1197. /// safelen-clause:
  1198. /// 'safelen' '(' expression ')'
  1199. ///
  1200. /// simdlen-clause:
  1201. /// 'simdlen' '(' expression ')'
  1202. ///
  1203. /// collapse-clause:
  1204. /// 'collapse' '(' expression ')'
  1205. ///
  1206. /// priority-clause:
  1207. /// 'priority' '(' expression ')'
  1208. ///
  1209. /// grainsize-clause:
  1210. /// 'grainsize' '(' expression ')'
  1211. ///
  1212. /// num_tasks-clause:
  1213. /// 'num_tasks' '(' expression ')'
  1214. ///
  1215. /// hint-clause:
  1216. /// 'hint' '(' expression ')'
  1217. ///
  1218. OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
  1219. SourceLocation Loc = ConsumeToken();
  1220. SourceLocation LLoc = Tok.getLocation();
  1221. SourceLocation RLoc;
  1222. ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
  1223. if (Val.isInvalid())
  1224. return nullptr;
  1225. return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
  1226. }
  1227. /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
  1228. ///
  1229. /// default-clause:
  1230. /// 'default' '(' 'none' | 'shared' ')
  1231. ///
  1232. /// proc_bind-clause:
  1233. /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
  1234. ///
  1235. OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
  1236. SourceLocation Loc = Tok.getLocation();
  1237. SourceLocation LOpen = ConsumeToken();
  1238. // Parse '('.
  1239. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1240. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1241. getOpenMPClauseName(Kind)))
  1242. return nullptr;
  1243. unsigned Type = getOpenMPSimpleClauseType(
  1244. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1245. SourceLocation TypeLoc = Tok.getLocation();
  1246. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1247. Tok.isNot(tok::annot_pragma_openmp_end))
  1248. ConsumeAnyToken();
  1249. // Parse ')'.
  1250. T.consumeClose();
  1251. return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
  1252. Tok.getLocation());
  1253. }
  1254. /// \brief Parsing of OpenMP clauses like 'ordered'.
  1255. ///
  1256. /// ordered-clause:
  1257. /// 'ordered'
  1258. ///
  1259. /// nowait-clause:
  1260. /// 'nowait'
  1261. ///
  1262. /// untied-clause:
  1263. /// 'untied'
  1264. ///
  1265. /// mergeable-clause:
  1266. /// 'mergeable'
  1267. ///
  1268. /// read-clause:
  1269. /// 'read'
  1270. ///
  1271. /// threads-clause:
  1272. /// 'threads'
  1273. ///
  1274. /// simd-clause:
  1275. /// 'simd'
  1276. ///
  1277. /// nogroup-clause:
  1278. /// 'nogroup'
  1279. ///
  1280. OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
  1281. SourceLocation Loc = Tok.getLocation();
  1282. ConsumeAnyToken();
  1283. return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
  1284. }
  1285. /// \brief Parsing of OpenMP clauses with single expressions and some additional
  1286. /// argument like 'schedule' or 'dist_schedule'.
  1287. ///
  1288. /// schedule-clause:
  1289. /// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
  1290. /// ')'
  1291. ///
  1292. /// if-clause:
  1293. /// 'if' '(' [ directive-name-modifier ':' ] expression ')'
  1294. ///
  1295. /// defaultmap:
  1296. /// 'defaultmap' '(' modifier ':' kind ')'
  1297. ///
  1298. OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
  1299. SourceLocation Loc = ConsumeToken();
  1300. SourceLocation DelimLoc;
  1301. // Parse '('.
  1302. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1303. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1304. getOpenMPClauseName(Kind)))
  1305. return nullptr;
  1306. ExprResult Val;
  1307. SmallVector<unsigned, 4> Arg;
  1308. SmallVector<SourceLocation, 4> KLoc;
  1309. if (Kind == OMPC_schedule) {
  1310. enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
  1311. Arg.resize(NumberOfElements);
  1312. KLoc.resize(NumberOfElements);
  1313. Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
  1314. Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
  1315. Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
  1316. auto KindModifier = getOpenMPSimpleClauseType(
  1317. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1318. if (KindModifier > OMPC_SCHEDULE_unknown) {
  1319. // Parse 'modifier'
  1320. Arg[Modifier1] = KindModifier;
  1321. KLoc[Modifier1] = Tok.getLocation();
  1322. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1323. Tok.isNot(tok::annot_pragma_openmp_end))
  1324. ConsumeAnyToken();
  1325. if (Tok.is(tok::comma)) {
  1326. // Parse ',' 'modifier'
  1327. ConsumeAnyToken();
  1328. KindModifier = getOpenMPSimpleClauseType(
  1329. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1330. Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
  1331. ? KindModifier
  1332. : (unsigned)OMPC_SCHEDULE_unknown;
  1333. KLoc[Modifier2] = Tok.getLocation();
  1334. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1335. Tok.isNot(tok::annot_pragma_openmp_end))
  1336. ConsumeAnyToken();
  1337. }
  1338. // Parse ':'
  1339. if (Tok.is(tok::colon))
  1340. ConsumeAnyToken();
  1341. else
  1342. Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
  1343. KindModifier = getOpenMPSimpleClauseType(
  1344. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1345. }
  1346. Arg[ScheduleKind] = KindModifier;
  1347. KLoc[ScheduleKind] = Tok.getLocation();
  1348. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1349. Tok.isNot(tok::annot_pragma_openmp_end))
  1350. ConsumeAnyToken();
  1351. if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
  1352. Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
  1353. Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
  1354. Tok.is(tok::comma))
  1355. DelimLoc = ConsumeAnyToken();
  1356. } else if (Kind == OMPC_dist_schedule) {
  1357. Arg.push_back(getOpenMPSimpleClauseType(
  1358. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
  1359. KLoc.push_back(Tok.getLocation());
  1360. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1361. Tok.isNot(tok::annot_pragma_openmp_end))
  1362. ConsumeAnyToken();
  1363. if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
  1364. DelimLoc = ConsumeAnyToken();
  1365. } else if (Kind == OMPC_defaultmap) {
  1366. // Get a defaultmap modifier
  1367. Arg.push_back(getOpenMPSimpleClauseType(
  1368. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
  1369. KLoc.push_back(Tok.getLocation());
  1370. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1371. Tok.isNot(tok::annot_pragma_openmp_end))
  1372. ConsumeAnyToken();
  1373. // Parse ':'
  1374. if (Tok.is(tok::colon))
  1375. ConsumeAnyToken();
  1376. else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
  1377. Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
  1378. // Get a defaultmap kind
  1379. Arg.push_back(getOpenMPSimpleClauseType(
  1380. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
  1381. KLoc.push_back(Tok.getLocation());
  1382. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1383. Tok.isNot(tok::annot_pragma_openmp_end))
  1384. ConsumeAnyToken();
  1385. } else {
  1386. assert(Kind == OMPC_if);
  1387. KLoc.push_back(Tok.getLocation());
  1388. TentativeParsingAction TPA(*this);
  1389. Arg.push_back(ParseOpenMPDirectiveKind(*this));
  1390. if (Arg.back() != OMPD_unknown) {
  1391. ConsumeToken();
  1392. if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
  1393. TPA.Commit();
  1394. DelimLoc = ConsumeToken();
  1395. } else {
  1396. TPA.Revert();
  1397. Arg.back() = OMPD_unknown;
  1398. }
  1399. } else
  1400. TPA.Revert();
  1401. }
  1402. bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
  1403. (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
  1404. Kind == OMPC_if;
  1405. if (NeedAnExpression) {
  1406. SourceLocation ELoc = Tok.getLocation();
  1407. ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
  1408. Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
  1409. Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
  1410. }
  1411. // Parse ')'.
  1412. T.consumeClose();
  1413. if (NeedAnExpression && Val.isInvalid())
  1414. return nullptr;
  1415. return Actions.ActOnOpenMPSingleExprWithArgClause(
  1416. Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
  1417. T.getCloseLocation());
  1418. }
  1419. static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
  1420. UnqualifiedId &ReductionId) {
  1421. SourceLocation TemplateKWLoc;
  1422. if (ReductionIdScopeSpec.isEmpty()) {
  1423. auto OOK = OO_None;
  1424. switch (P.getCurToken().getKind()) {
  1425. case tok::plus:
  1426. OOK = OO_Plus;
  1427. break;
  1428. case tok::minus:
  1429. OOK = OO_Minus;
  1430. break;
  1431. case tok::star:
  1432. OOK = OO_Star;
  1433. break;
  1434. case tok::amp:
  1435. OOK = OO_Amp;
  1436. break;
  1437. case tok::pipe:
  1438. OOK = OO_Pipe;
  1439. break;
  1440. case tok::caret:
  1441. OOK = OO_Caret;
  1442. break;
  1443. case tok::ampamp:
  1444. OOK = OO_AmpAmp;
  1445. break;
  1446. case tok::pipepipe:
  1447. OOK = OO_PipePipe;
  1448. break;
  1449. default:
  1450. break;
  1451. }
  1452. if (OOK != OO_None) {
  1453. SourceLocation OpLoc = P.ConsumeToken();
  1454. SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
  1455. ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
  1456. return false;
  1457. }
  1458. }
  1459. return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
  1460. /*AllowDestructorName*/ false,
  1461. /*AllowConstructorName*/ false, nullptr,
  1462. TemplateKWLoc, ReductionId);
  1463. }
  1464. /// Parses clauses with list.
  1465. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
  1466. OpenMPClauseKind Kind,
  1467. SmallVectorImpl<Expr *> &Vars,
  1468. OpenMPVarListDataTy &Data) {
  1469. UnqualifiedId UnqualifiedReductionId;
  1470. bool InvalidReductionId = false;
  1471. bool MapTypeModifierSpecified = false;
  1472. // Parse '('.
  1473. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1474. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1475. getOpenMPClauseName(Kind)))
  1476. return true;
  1477. bool NeedRParenForLinear = false;
  1478. BalancedDelimiterTracker LinearT(*this, tok::l_paren,
  1479. tok::annot_pragma_openmp_end);
  1480. // Handle reduction-identifier for reduction clause.
  1481. if (Kind == OMPC_reduction) {
  1482. ColonProtectionRAIIObject ColonRAII(*this);
  1483. if (getLangOpts().CPlusPlus)
  1484. ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec,
  1485. /*ObjectType=*/nullptr,
  1486. /*EnteringContext=*/false);
  1487. InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec,
  1488. UnqualifiedReductionId);
  1489. if (InvalidReductionId) {
  1490. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  1491. StopBeforeMatch);
  1492. }
  1493. if (Tok.is(tok::colon))
  1494. Data.ColonLoc = ConsumeToken();
  1495. else
  1496. Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
  1497. if (!InvalidReductionId)
  1498. Data.ReductionId =
  1499. Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
  1500. } else if (Kind == OMPC_depend) {
  1501. // Handle dependency type for depend clause.
  1502. ColonProtectionRAIIObject ColonRAII(*this);
  1503. Data.DepKind =
  1504. static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
  1505. Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
  1506. Data.DepLinMapLoc = Tok.getLocation();
  1507. if (Data.DepKind == OMPC_DEPEND_unknown) {
  1508. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  1509. StopBeforeMatch);
  1510. } else {
  1511. ConsumeToken();
  1512. // Special processing for depend(source) clause.
  1513. if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
  1514. // Parse ')'.
  1515. T.consumeClose();
  1516. return false;
  1517. }
  1518. }
  1519. if (Tok.is(tok::colon))
  1520. Data.ColonLoc = ConsumeToken();
  1521. else {
  1522. Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
  1523. : diag::warn_pragma_expected_colon)
  1524. << "dependency type";
  1525. }
  1526. } else if (Kind == OMPC_linear) {
  1527. // Try to parse modifier if any.
  1528. if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
  1529. Data.LinKind = static_cast<OpenMPLinearClauseKind>(
  1530. getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
  1531. Data.DepLinMapLoc = ConsumeToken();
  1532. LinearT.consumeOpen();
  1533. NeedRParenForLinear = true;
  1534. }
  1535. } else if (Kind == OMPC_map) {
  1536. // Handle map type for map clause.
  1537. ColonProtectionRAIIObject ColonRAII(*this);
  1538. /// The map clause modifier token can be either a identifier or the C++
  1539. /// delete keyword.
  1540. auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool {
  1541. return Tok.isOneOf(tok::identifier, tok::kw_delete);
  1542. };
  1543. // The first identifier may be a list item, a map-type or a
  1544. // map-type-modifier. The map modifier can also be delete which has the same
  1545. // spelling of the C++ delete keyword.
  1546. Data.MapType =
  1547. IsMapClauseModifierToken(Tok)
  1548. ? static_cast<OpenMPMapClauseKind>(
  1549. getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
  1550. : OMPC_MAP_unknown;
  1551. Data.DepLinMapLoc = Tok.getLocation();
  1552. bool ColonExpected = false;
  1553. if (IsMapClauseModifierToken(Tok)) {
  1554. if (PP.LookAhead(0).is(tok::colon)) {
  1555. if (Data.MapType == OMPC_MAP_unknown)
  1556. Diag(Tok, diag::err_omp_unknown_map_type);
  1557. else if (Data.MapType == OMPC_MAP_always)
  1558. Diag(Tok, diag::err_omp_map_type_missing);
  1559. ConsumeToken();
  1560. } else if (PP.LookAhead(0).is(tok::comma)) {
  1561. if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
  1562. PP.LookAhead(2).is(tok::colon)) {
  1563. Data.MapTypeModifier = Data.MapType;
  1564. if (Data.MapTypeModifier != OMPC_MAP_always) {
  1565. Diag(Tok, diag::err_omp_unknown_map_type_modifier);
  1566. Data.MapTypeModifier = OMPC_MAP_unknown;
  1567. } else
  1568. MapTypeModifierSpecified = true;
  1569. ConsumeToken();
  1570. ConsumeToken();
  1571. Data.MapType =
  1572. IsMapClauseModifierToken(Tok)
  1573. ? static_cast<OpenMPMapClauseKind>(
  1574. getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
  1575. : OMPC_MAP_unknown;
  1576. if (Data.MapType == OMPC_MAP_unknown ||
  1577. Data.MapType == OMPC_MAP_always)
  1578. Diag(Tok, diag::err_omp_unknown_map_type);
  1579. ConsumeToken();
  1580. } else {
  1581. Data.MapType = OMPC_MAP_tofrom;
  1582. Data.IsMapTypeImplicit = true;
  1583. }
  1584. } else {
  1585. Data.MapType = OMPC_MAP_tofrom;
  1586. Data.IsMapTypeImplicit = true;
  1587. }
  1588. } else {
  1589. Data.MapType = OMPC_MAP_tofrom;
  1590. Data.IsMapTypeImplicit = true;
  1591. }
  1592. if (Tok.is(tok::colon))
  1593. Data.ColonLoc = ConsumeToken();
  1594. else if (ColonExpected)
  1595. Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
  1596. }
  1597. bool IsComma =
  1598. (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
  1599. (Kind == OMPC_reduction && !InvalidReductionId) ||
  1600. (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
  1601. (!MapTypeModifierSpecified ||
  1602. Data.MapTypeModifier == OMPC_MAP_always)) ||
  1603. (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
  1604. const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
  1605. while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
  1606. Tok.isNot(tok::annot_pragma_openmp_end))) {
  1607. ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
  1608. // Parse variable
  1609. ExprResult VarExpr =
  1610. Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
  1611. if (VarExpr.isUsable())
  1612. Vars.push_back(VarExpr.get());
  1613. else {
  1614. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  1615. StopBeforeMatch);
  1616. }
  1617. // Skip ',' if any
  1618. IsComma = Tok.is(tok::comma);
  1619. if (IsComma)
  1620. ConsumeToken();
  1621. else if (Tok.isNot(tok::r_paren) &&
  1622. Tok.isNot(tok::annot_pragma_openmp_end) &&
  1623. (!MayHaveTail || Tok.isNot(tok::colon)))
  1624. Diag(Tok, diag::err_omp_expected_punc)
  1625. << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
  1626. : getOpenMPClauseName(Kind))
  1627. << (Kind == OMPC_flush);
  1628. }
  1629. // Parse ')' for linear clause with modifier.
  1630. if (NeedRParenForLinear)
  1631. LinearT.consumeClose();
  1632. // Parse ':' linear-step (or ':' alignment).
  1633. const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
  1634. if (MustHaveTail) {
  1635. Data.ColonLoc = Tok.getLocation();
  1636. SourceLocation ELoc = ConsumeToken();
  1637. ExprResult Tail = ParseAssignmentExpression();
  1638. Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
  1639. if (Tail.isUsable())
  1640. Data.TailExpr = Tail.get();
  1641. else
  1642. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  1643. StopBeforeMatch);
  1644. }
  1645. // Parse ')'.
  1646. T.consumeClose();
  1647. if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
  1648. Vars.empty()) ||
  1649. (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
  1650. (MustHaveTail && !Data.TailExpr) || InvalidReductionId)
  1651. return true;
  1652. return false;
  1653. }
  1654. /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
  1655. /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
  1656. ///
  1657. /// private-clause:
  1658. /// 'private' '(' list ')'
  1659. /// firstprivate-clause:
  1660. /// 'firstprivate' '(' list ')'
  1661. /// lastprivate-clause:
  1662. /// 'lastprivate' '(' list ')'
  1663. /// shared-clause:
  1664. /// 'shared' '(' list ')'
  1665. /// linear-clause:
  1666. /// 'linear' '(' linear-list [ ':' linear-step ] ')'
  1667. /// aligned-clause:
  1668. /// 'aligned' '(' list [ ':' alignment ] ')'
  1669. /// reduction-clause:
  1670. /// 'reduction' '(' reduction-identifier ':' list ')'
  1671. /// copyprivate-clause:
  1672. /// 'copyprivate' '(' list ')'
  1673. /// flush-clause:
  1674. /// 'flush' '(' list ')'
  1675. /// depend-clause:
  1676. /// 'depend' '(' in | out | inout : list | source ')'
  1677. /// map-clause:
  1678. /// 'map' '(' [ [ always , ]
  1679. /// to | from | tofrom | alloc | release | delete ':' ] list ')';
  1680. /// to-clause:
  1681. /// 'to' '(' list ')'
  1682. /// from-clause:
  1683. /// 'from' '(' list ')'
  1684. /// use_device_ptr-clause:
  1685. /// 'use_device_ptr' '(' list ')'
  1686. /// is_device_ptr-clause:
  1687. /// 'is_device_ptr' '(' list ')'
  1688. ///
  1689. /// For 'linear' clause linear-list may have the following forms:
  1690. /// list
  1691. /// modifier(list)
  1692. /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
  1693. OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
  1694. OpenMPClauseKind Kind) {
  1695. SourceLocation Loc = Tok.getLocation();
  1696. SourceLocation LOpen = ConsumeToken();
  1697. SmallVector<Expr *, 4> Vars;
  1698. OpenMPVarListDataTy Data;
  1699. if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
  1700. return nullptr;
  1701. return Actions.ActOnOpenMPVarListClause(
  1702. Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(),
  1703. Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind,
  1704. Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit,
  1705. Data.DepLinMapLoc);
  1706. }