ParseOpenMP.cpp 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376
  1. //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /// \file
  9. /// This file implements parsing of all OpenMP directives and clauses.
  10. ///
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/AST/ASTContext.h"
  13. #include "clang/AST/StmtOpenMP.h"
  14. #include "clang/Parse/ParseDiagnostic.h"
  15. #include "clang/Parse/Parser.h"
  16. #include "clang/Parse/RAIIObjectsForParser.h"
  17. #include "clang/Sema/Scope.h"
  18. #include "llvm/ADT/PointerIntPair.h"
  19. using namespace clang;
  20. //===----------------------------------------------------------------------===//
  21. // OpenMP declarative directives.
  22. //===----------------------------------------------------------------------===//
  23. namespace {
  24. enum OpenMPDirectiveKindEx {
  25. OMPD_cancellation = OMPD_unknown + 1,
  26. OMPD_data,
  27. OMPD_declare,
  28. OMPD_end,
  29. OMPD_end_declare,
  30. OMPD_enter,
  31. OMPD_exit,
  32. OMPD_point,
  33. OMPD_reduction,
  34. OMPD_target_enter,
  35. OMPD_target_exit,
  36. OMPD_update,
  37. OMPD_distribute_parallel,
  38. OMPD_teams_distribute_parallel,
  39. OMPD_target_teams_distribute_parallel,
  40. OMPD_mapper,
  41. };
  42. class DeclDirectiveListParserHelper final {
  43. SmallVector<Expr *, 4> Identifiers;
  44. Parser *P;
  45. OpenMPDirectiveKind Kind;
  46. public:
  47. DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
  48. : P(P), Kind(Kind) {}
  49. void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
  50. ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
  51. P->getCurScope(), SS, NameInfo, Kind);
  52. if (Res.isUsable())
  53. Identifiers.push_back(Res.get());
  54. }
  55. llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
  56. };
  57. } // namespace
  58. // Map token string to extended OMP token kind that are
  59. // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
  60. static unsigned getOpenMPDirectiveKindEx(StringRef S) {
  61. auto DKind = getOpenMPDirectiveKind(S);
  62. if (DKind != OMPD_unknown)
  63. return DKind;
  64. return llvm::StringSwitch<unsigned>(S)
  65. .Case("cancellation", OMPD_cancellation)
  66. .Case("data", OMPD_data)
  67. .Case("declare", OMPD_declare)
  68. .Case("end", OMPD_end)
  69. .Case("enter", OMPD_enter)
  70. .Case("exit", OMPD_exit)
  71. .Case("point", OMPD_point)
  72. .Case("reduction", OMPD_reduction)
  73. .Case("update", OMPD_update)
  74. .Case("mapper", OMPD_mapper)
  75. .Default(OMPD_unknown);
  76. }
  77. static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
  78. // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
  79. // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
  80. // TODO: add other combined directives in topological order.
  81. static const unsigned F[][3] = {
  82. {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
  83. {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
  84. {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
  85. {OMPD_declare, OMPD_simd, OMPD_declare_simd},
  86. {OMPD_declare, OMPD_target, OMPD_declare_target},
  87. {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
  88. {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
  89. {OMPD_distribute_parallel_for, OMPD_simd,
  90. OMPD_distribute_parallel_for_simd},
  91. {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
  92. {OMPD_end, OMPD_declare, OMPD_end_declare},
  93. {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
  94. {OMPD_target, OMPD_data, OMPD_target_data},
  95. {OMPD_target, OMPD_enter, OMPD_target_enter},
  96. {OMPD_target, OMPD_exit, OMPD_target_exit},
  97. {OMPD_target, OMPD_update, OMPD_target_update},
  98. {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
  99. {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
  100. {OMPD_for, OMPD_simd, OMPD_for_simd},
  101. {OMPD_parallel, OMPD_for, OMPD_parallel_for},
  102. {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
  103. {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
  104. {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
  105. {OMPD_target, OMPD_parallel, OMPD_target_parallel},
  106. {OMPD_target, OMPD_simd, OMPD_target_simd},
  107. {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
  108. {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
  109. {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
  110. {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
  111. {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
  112. {OMPD_teams_distribute_parallel, OMPD_for,
  113. OMPD_teams_distribute_parallel_for},
  114. {OMPD_teams_distribute_parallel_for, OMPD_simd,
  115. OMPD_teams_distribute_parallel_for_simd},
  116. {OMPD_target, OMPD_teams, OMPD_target_teams},
  117. {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
  118. {OMPD_target_teams_distribute, OMPD_parallel,
  119. OMPD_target_teams_distribute_parallel},
  120. {OMPD_target_teams_distribute, OMPD_simd,
  121. OMPD_target_teams_distribute_simd},
  122. {OMPD_target_teams_distribute_parallel, OMPD_for,
  123. OMPD_target_teams_distribute_parallel_for},
  124. {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
  125. OMPD_target_teams_distribute_parallel_for_simd}};
  126. enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
  127. Token Tok = P.getCurToken();
  128. unsigned DKind =
  129. Tok.isAnnotation()
  130. ? static_cast<unsigned>(OMPD_unknown)
  131. : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
  132. if (DKind == OMPD_unknown)
  133. return OMPD_unknown;
  134. for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
  135. if (DKind != F[I][0])
  136. continue;
  137. Tok = P.getPreprocessor().LookAhead(0);
  138. unsigned SDKind =
  139. Tok.isAnnotation()
  140. ? static_cast<unsigned>(OMPD_unknown)
  141. : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
  142. if (SDKind == OMPD_unknown)
  143. continue;
  144. if (SDKind == F[I][1]) {
  145. P.ConsumeToken();
  146. DKind = F[I][2];
  147. }
  148. }
  149. return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
  150. : OMPD_unknown;
  151. }
  152. static DeclarationName parseOpenMPReductionId(Parser &P) {
  153. Token Tok = P.getCurToken();
  154. Sema &Actions = P.getActions();
  155. OverloadedOperatorKind OOK = OO_None;
  156. // Allow to use 'operator' keyword for C++ operators
  157. bool WithOperator = false;
  158. if (Tok.is(tok::kw_operator)) {
  159. P.ConsumeToken();
  160. Tok = P.getCurToken();
  161. WithOperator = true;
  162. }
  163. switch (Tok.getKind()) {
  164. case tok::plus: // '+'
  165. OOK = OO_Plus;
  166. break;
  167. case tok::minus: // '-'
  168. OOK = OO_Minus;
  169. break;
  170. case tok::star: // '*'
  171. OOK = OO_Star;
  172. break;
  173. case tok::amp: // '&'
  174. OOK = OO_Amp;
  175. break;
  176. case tok::pipe: // '|'
  177. OOK = OO_Pipe;
  178. break;
  179. case tok::caret: // '^'
  180. OOK = OO_Caret;
  181. break;
  182. case tok::ampamp: // '&&'
  183. OOK = OO_AmpAmp;
  184. break;
  185. case tok::pipepipe: // '||'
  186. OOK = OO_PipePipe;
  187. break;
  188. case tok::identifier: // identifier
  189. if (!WithOperator)
  190. break;
  191. LLVM_FALLTHROUGH;
  192. default:
  193. P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
  194. P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  195. Parser::StopBeforeMatch);
  196. return DeclarationName();
  197. }
  198. P.ConsumeToken();
  199. auto &DeclNames = Actions.getASTContext().DeclarationNames;
  200. return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
  201. : DeclNames.getCXXOperatorName(OOK);
  202. }
  203. /// Parse 'omp declare reduction' construct.
  204. ///
  205. /// declare-reduction-directive:
  206. /// annot_pragma_openmp 'declare' 'reduction'
  207. /// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
  208. /// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
  209. /// annot_pragma_openmp_end
  210. /// <reduction_id> is either a base language identifier or one of the following
  211. /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
  212. ///
  213. Parser::DeclGroupPtrTy
  214. Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
  215. // Parse '('.
  216. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  217. if (T.expectAndConsume(diag::err_expected_lparen_after,
  218. getOpenMPDirectiveName(OMPD_declare_reduction))) {
  219. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  220. return DeclGroupPtrTy();
  221. }
  222. DeclarationName Name = parseOpenMPReductionId(*this);
  223. if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
  224. return DeclGroupPtrTy();
  225. // Consume ':'.
  226. bool IsCorrect = !ExpectAndConsume(tok::colon);
  227. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  228. return DeclGroupPtrTy();
  229. IsCorrect = IsCorrect && !Name.isEmpty();
  230. if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
  231. Diag(Tok.getLocation(), diag::err_expected_type);
  232. IsCorrect = false;
  233. }
  234. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  235. return DeclGroupPtrTy();
  236. SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
  237. // Parse list of types until ':' token.
  238. do {
  239. ColonProtectionRAIIObject ColonRAII(*this);
  240. SourceRange Range;
  241. TypeResult TR =
  242. ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
  243. if (TR.isUsable()) {
  244. QualType ReductionType =
  245. Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
  246. if (!ReductionType.isNull()) {
  247. ReductionTypes.push_back(
  248. std::make_pair(ReductionType, Range.getBegin()));
  249. }
  250. } else {
  251. SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
  252. StopBeforeMatch);
  253. }
  254. if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
  255. break;
  256. // Consume ','.
  257. if (ExpectAndConsume(tok::comma)) {
  258. IsCorrect = false;
  259. if (Tok.is(tok::annot_pragma_openmp_end)) {
  260. Diag(Tok.getLocation(), diag::err_expected_type);
  261. return DeclGroupPtrTy();
  262. }
  263. }
  264. } while (Tok.isNot(tok::annot_pragma_openmp_end));
  265. if (ReductionTypes.empty()) {
  266. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  267. return DeclGroupPtrTy();
  268. }
  269. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  270. return DeclGroupPtrTy();
  271. // Consume ':'.
  272. if (ExpectAndConsume(tok::colon))
  273. IsCorrect = false;
  274. if (Tok.is(tok::annot_pragma_openmp_end)) {
  275. Diag(Tok.getLocation(), diag::err_expected_expression);
  276. return DeclGroupPtrTy();
  277. }
  278. DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
  279. getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
  280. // Parse <combiner> expression and then parse initializer if any for each
  281. // correct type.
  282. unsigned I = 0, E = ReductionTypes.size();
  283. for (Decl *D : DRD.get()) {
  284. TentativeParsingAction TPA(*this);
  285. ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
  286. Scope::CompoundStmtScope |
  287. Scope::OpenMPDirectiveScope);
  288. // Parse <combiner> expression.
  289. Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
  290. ExprResult CombinerResult =
  291. Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
  292. D->getLocation(), /*DiscardedValue*/ false);
  293. Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
  294. if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
  295. Tok.isNot(tok::annot_pragma_openmp_end)) {
  296. TPA.Commit();
  297. IsCorrect = false;
  298. break;
  299. }
  300. IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
  301. ExprResult InitializerResult;
  302. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  303. // Parse <initializer> expression.
  304. if (Tok.is(tok::identifier) &&
  305. Tok.getIdentifierInfo()->isStr("initializer")) {
  306. ConsumeToken();
  307. } else {
  308. Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
  309. TPA.Commit();
  310. IsCorrect = false;
  311. break;
  312. }
  313. // Parse '('.
  314. BalancedDelimiterTracker T(*this, tok::l_paren,
  315. tok::annot_pragma_openmp_end);
  316. IsCorrect =
  317. !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
  318. IsCorrect;
  319. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  320. ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
  321. Scope::CompoundStmtScope |
  322. Scope::OpenMPDirectiveScope);
  323. // Parse expression.
  324. VarDecl *OmpPrivParm =
  325. Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
  326. D);
  327. // Check if initializer is omp_priv <init_expr> or something else.
  328. if (Tok.is(tok::identifier) &&
  329. Tok.getIdentifierInfo()->isStr("omp_priv")) {
  330. if (Actions.getLangOpts().CPlusPlus) {
  331. InitializerResult = Actions.ActOnFinishFullExpr(
  332. ParseAssignmentExpression().get(), D->getLocation(),
  333. /*DiscardedValue*/ false);
  334. } else {
  335. ConsumeToken();
  336. ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
  337. }
  338. } else {
  339. InitializerResult = Actions.ActOnFinishFullExpr(
  340. ParseAssignmentExpression().get(), D->getLocation(),
  341. /*DiscardedValue*/ false);
  342. }
  343. Actions.ActOnOpenMPDeclareReductionInitializerEnd(
  344. D, InitializerResult.get(), OmpPrivParm);
  345. if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
  346. Tok.isNot(tok::annot_pragma_openmp_end)) {
  347. TPA.Commit();
  348. IsCorrect = false;
  349. break;
  350. }
  351. IsCorrect =
  352. !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
  353. }
  354. }
  355. ++I;
  356. // Revert parsing if not the last type, otherwise accept it, we're done with
  357. // parsing.
  358. if (I != E)
  359. TPA.Revert();
  360. else
  361. TPA.Commit();
  362. }
  363. return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
  364. IsCorrect);
  365. }
  366. void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
  367. // Parse declarator '=' initializer.
  368. // If a '==' or '+=' is found, suggest a fixit to '='.
  369. if (isTokenEqualOrEqualTypo()) {
  370. ConsumeToken();
  371. if (Tok.is(tok::code_completion)) {
  372. Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
  373. Actions.FinalizeDeclaration(OmpPrivParm);
  374. cutOffParsing();
  375. return;
  376. }
  377. ExprResult Init(ParseInitializer());
  378. if (Init.isInvalid()) {
  379. SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
  380. Actions.ActOnInitializerError(OmpPrivParm);
  381. } else {
  382. Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
  383. /*DirectInit=*/false);
  384. }
  385. } else if (Tok.is(tok::l_paren)) {
  386. // Parse C++ direct initializer: '(' expression-list ')'
  387. BalancedDelimiterTracker T(*this, tok::l_paren);
  388. T.consumeOpen();
  389. ExprVector Exprs;
  390. CommaLocsTy CommaLocs;
  391. SourceLocation LParLoc = T.getOpenLocation();
  392. auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
  393. QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
  394. getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
  395. OmpPrivParm->getLocation(), Exprs, LParLoc);
  396. CalledSignatureHelp = true;
  397. return PreferredType;
  398. };
  399. if (ParseExpressionList(Exprs, CommaLocs, [&] {
  400. PreferredType.enterFunctionArgument(Tok.getLocation(),
  401. RunSignatureHelp);
  402. })) {
  403. if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
  404. RunSignatureHelp();
  405. Actions.ActOnInitializerError(OmpPrivParm);
  406. SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
  407. } else {
  408. // Match the ')'.
  409. SourceLocation RLoc = Tok.getLocation();
  410. if (!T.consumeClose())
  411. RLoc = T.getCloseLocation();
  412. assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
  413. "Unexpected number of commas!");
  414. ExprResult Initializer =
  415. Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
  416. Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
  417. /*DirectInit=*/true);
  418. }
  419. } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
  420. // Parse C++0x braced-init-list.
  421. Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
  422. ExprResult Init(ParseBraceInitializer());
  423. if (Init.isInvalid()) {
  424. Actions.ActOnInitializerError(OmpPrivParm);
  425. } else {
  426. Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
  427. /*DirectInit=*/true);
  428. }
  429. } else {
  430. Actions.ActOnUninitializedDecl(OmpPrivParm);
  431. }
  432. }
  433. /// Parses 'omp declare mapper' directive.
  434. ///
  435. /// declare-mapper-directive:
  436. /// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
  437. /// <type> <var> ')' [<clause>[[,] <clause>] ... ]
  438. /// annot_pragma_openmp_end
  439. /// <mapper-identifier> and <var> are base language identifiers.
  440. ///
  441. Parser::DeclGroupPtrTy
  442. Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
  443. bool IsCorrect = true;
  444. // Parse '('
  445. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  446. if (T.expectAndConsume(diag::err_expected_lparen_after,
  447. getOpenMPDirectiveName(OMPD_declare_mapper))) {
  448. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  449. return DeclGroupPtrTy();
  450. }
  451. // Parse <mapper-identifier>
  452. auto &DeclNames = Actions.getASTContext().DeclarationNames;
  453. DeclarationName MapperId;
  454. if (PP.LookAhead(0).is(tok::colon)) {
  455. if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
  456. Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
  457. IsCorrect = false;
  458. } else {
  459. MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
  460. }
  461. ConsumeToken();
  462. // Consume ':'.
  463. ExpectAndConsume(tok::colon);
  464. } else {
  465. // If no mapper identifier is provided, its name is "default" by default
  466. MapperId =
  467. DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
  468. }
  469. if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
  470. return DeclGroupPtrTy();
  471. // Parse <type> <var>
  472. DeclarationName VName;
  473. QualType MapperType;
  474. SourceRange Range;
  475. TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
  476. if (ParsedType.isUsable())
  477. MapperType =
  478. Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
  479. if (MapperType.isNull())
  480. IsCorrect = false;
  481. if (!IsCorrect) {
  482. SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
  483. return DeclGroupPtrTy();
  484. }
  485. // Consume ')'.
  486. IsCorrect &= !T.consumeClose();
  487. if (!IsCorrect) {
  488. SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
  489. return DeclGroupPtrTy();
  490. }
  491. // Enter scope.
  492. OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
  493. getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
  494. Range.getBegin(), VName, AS);
  495. DeclarationNameInfo DirName;
  496. SourceLocation Loc = Tok.getLocation();
  497. unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
  498. Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
  499. ParseScope OMPDirectiveScope(this, ScopeFlags);
  500. Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
  501. // Add the mapper variable declaration.
  502. Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
  503. DMD, getCurScope(), MapperType, Range.getBegin(), VName);
  504. // Parse map clauses.
  505. SmallVector<OMPClause *, 6> Clauses;
  506. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  507. OpenMPClauseKind CKind = Tok.isAnnotation()
  508. ? OMPC_unknown
  509. : getOpenMPClauseKind(PP.getSpelling(Tok));
  510. Actions.StartOpenMPClause(CKind);
  511. OMPClause *Clause =
  512. ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
  513. if (Clause)
  514. Clauses.push_back(Clause);
  515. else
  516. IsCorrect = false;
  517. // Skip ',' if any.
  518. if (Tok.is(tok::comma))
  519. ConsumeToken();
  520. Actions.EndOpenMPClause();
  521. }
  522. if (Clauses.empty()) {
  523. Diag(Tok, diag::err_omp_expected_clause)
  524. << getOpenMPDirectiveName(OMPD_declare_mapper);
  525. IsCorrect = false;
  526. }
  527. // Exit scope.
  528. Actions.EndOpenMPDSABlock(nullptr);
  529. OMPDirectiveScope.Exit();
  530. DeclGroupPtrTy DGP =
  531. Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
  532. if (!IsCorrect)
  533. return DeclGroupPtrTy();
  534. return DGP;
  535. }
  536. TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
  537. DeclarationName &Name,
  538. AccessSpecifier AS) {
  539. // Parse the common declaration-specifiers piece.
  540. Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
  541. DeclSpec DS(AttrFactory);
  542. ParseSpecifierQualifierList(DS, AS, DSC);
  543. // Parse the declarator.
  544. DeclaratorContext Context = DeclaratorContext::PrototypeContext;
  545. Declarator DeclaratorInfo(DS, Context);
  546. ParseDeclarator(DeclaratorInfo);
  547. Range = DeclaratorInfo.getSourceRange();
  548. if (DeclaratorInfo.getIdentifier() == nullptr) {
  549. Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
  550. return true;
  551. }
  552. Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
  553. return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
  554. }
  555. namespace {
  556. /// RAII that recreates function context for correct parsing of clauses of
  557. /// 'declare simd' construct.
  558. /// OpenMP, 2.8.2 declare simd Construct
  559. /// The expressions appearing in the clauses of this directive are evaluated in
  560. /// the scope of the arguments of the function declaration or definition.
  561. class FNContextRAII final {
  562. Parser &P;
  563. Sema::CXXThisScopeRAII *ThisScope;
  564. Parser::ParseScope *TempScope;
  565. Parser::ParseScope *FnScope;
  566. bool HasTemplateScope = false;
  567. bool HasFunScope = false;
  568. FNContextRAII() = delete;
  569. FNContextRAII(const FNContextRAII &) = delete;
  570. FNContextRAII &operator=(const FNContextRAII &) = delete;
  571. public:
  572. FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
  573. Decl *D = *Ptr.get().begin();
  574. NamedDecl *ND = dyn_cast<NamedDecl>(D);
  575. RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
  576. Sema &Actions = P.getActions();
  577. // Allow 'this' within late-parsed attributes.
  578. ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
  579. ND && ND->isCXXInstanceMember());
  580. // If the Decl is templatized, add template parameters to scope.
  581. HasTemplateScope = D->isTemplateDecl();
  582. TempScope =
  583. new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
  584. if (HasTemplateScope)
  585. Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
  586. // If the Decl is on a function, add function parameters to the scope.
  587. HasFunScope = D->isFunctionOrFunctionTemplate();
  588. FnScope = new Parser::ParseScope(
  589. &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
  590. HasFunScope);
  591. if (HasFunScope)
  592. Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
  593. }
  594. ~FNContextRAII() {
  595. if (HasFunScope) {
  596. P.getActions().ActOnExitFunctionContext();
  597. FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
  598. }
  599. if (HasTemplateScope)
  600. TempScope->Exit();
  601. delete FnScope;
  602. delete TempScope;
  603. delete ThisScope;
  604. }
  605. };
  606. } // namespace
  607. /// Parses clauses for 'declare simd' directive.
  608. /// clause:
  609. /// 'inbranch' | 'notinbranch'
  610. /// 'simdlen' '(' <expr> ')'
  611. /// { 'uniform' '(' <argument_list> ')' }
  612. /// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
  613. /// { 'linear '(' <argument_list> [ ':' <step> ] ')' }
  614. static bool parseDeclareSimdClauses(
  615. Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
  616. SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
  617. SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
  618. SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
  619. SourceRange BSRange;
  620. const Token &Tok = P.getCurToken();
  621. bool IsError = false;
  622. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  623. if (Tok.isNot(tok::identifier))
  624. break;
  625. OMPDeclareSimdDeclAttr::BranchStateTy Out;
  626. IdentifierInfo *II = Tok.getIdentifierInfo();
  627. StringRef ClauseName = II->getName();
  628. // Parse 'inranch|notinbranch' clauses.
  629. if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
  630. if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
  631. P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
  632. << ClauseName
  633. << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
  634. IsError = true;
  635. }
  636. BS = Out;
  637. BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
  638. P.ConsumeToken();
  639. } else if (ClauseName.equals("simdlen")) {
  640. if (SimdLen.isUsable()) {
  641. P.Diag(Tok, diag::err_omp_more_one_clause)
  642. << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
  643. IsError = true;
  644. }
  645. P.ConsumeToken();
  646. SourceLocation RLoc;
  647. SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
  648. if (SimdLen.isInvalid())
  649. IsError = true;
  650. } else {
  651. OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
  652. if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
  653. CKind == OMPC_linear) {
  654. Parser::OpenMPVarListDataTy Data;
  655. SmallVectorImpl<Expr *> *Vars = &Uniforms;
  656. if (CKind == OMPC_aligned)
  657. Vars = &Aligneds;
  658. else if (CKind == OMPC_linear)
  659. Vars = &Linears;
  660. P.ConsumeToken();
  661. if (P.ParseOpenMPVarList(OMPD_declare_simd,
  662. getOpenMPClauseKind(ClauseName), *Vars, Data))
  663. IsError = true;
  664. if (CKind == OMPC_aligned) {
  665. Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
  666. } else if (CKind == OMPC_linear) {
  667. if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
  668. Data.DepLinMapLoc))
  669. Data.LinKind = OMPC_LINEAR_val;
  670. LinModifiers.append(Linears.size() - LinModifiers.size(),
  671. Data.LinKind);
  672. Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
  673. }
  674. } else
  675. // TODO: add parsing of other clauses.
  676. break;
  677. }
  678. // Skip ',' if any.
  679. if (Tok.is(tok::comma))
  680. P.ConsumeToken();
  681. }
  682. return IsError;
  683. }
  684. /// Parse clauses for '#pragma omp declare simd'.
  685. Parser::DeclGroupPtrTy
  686. Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
  687. CachedTokens &Toks, SourceLocation Loc) {
  688. PP.EnterToken(Tok);
  689. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
  690. // Consume the previously pushed token.
  691. ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
  692. FNContextRAII FnContext(*this, Ptr);
  693. OMPDeclareSimdDeclAttr::BranchStateTy BS =
  694. OMPDeclareSimdDeclAttr::BS_Undefined;
  695. ExprResult Simdlen;
  696. SmallVector<Expr *, 4> Uniforms;
  697. SmallVector<Expr *, 4> Aligneds;
  698. SmallVector<Expr *, 4> Alignments;
  699. SmallVector<Expr *, 4> Linears;
  700. SmallVector<unsigned, 4> LinModifiers;
  701. SmallVector<Expr *, 4> Steps;
  702. bool IsError =
  703. parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
  704. Alignments, Linears, LinModifiers, Steps);
  705. // Need to check for extra tokens.
  706. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  707. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  708. << getOpenMPDirectiveName(OMPD_declare_simd);
  709. while (Tok.isNot(tok::annot_pragma_openmp_end))
  710. ConsumeAnyToken();
  711. }
  712. // Skip the last annot_pragma_openmp_end.
  713. SourceLocation EndLoc = ConsumeAnnotationToken();
  714. if (IsError)
  715. return Ptr;
  716. return Actions.ActOnOpenMPDeclareSimdDirective(
  717. Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
  718. LinModifiers, Steps, SourceRange(Loc, EndLoc));
  719. }
  720. Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
  721. // OpenMP 4.5 syntax with list of entities.
  722. Sema::NamedDeclSetType SameDirectiveDecls;
  723. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  724. OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
  725. if (Tok.is(tok::identifier)) {
  726. IdentifierInfo *II = Tok.getIdentifierInfo();
  727. StringRef ClauseName = II->getName();
  728. // Parse 'to|link' clauses.
  729. if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
  730. Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
  731. break;
  732. }
  733. ConsumeToken();
  734. }
  735. auto &&Callback = [this, MT, &SameDirectiveDecls](
  736. CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
  737. Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
  738. SameDirectiveDecls);
  739. };
  740. if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
  741. /*AllowScopeSpecifier=*/true))
  742. break;
  743. // Consume optional ','.
  744. if (Tok.is(tok::comma))
  745. ConsumeToken();
  746. }
  747. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  748. ConsumeAnyToken();
  749. SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
  750. SameDirectiveDecls.end());
  751. if (Decls.empty())
  752. return DeclGroupPtrTy();
  753. return Actions.BuildDeclaratorGroup(Decls);
  754. }
  755. void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
  756. SourceLocation DTLoc) {
  757. if (DKind != OMPD_end_declare_target) {
  758. Diag(Tok, diag::err_expected_end_declare_target);
  759. Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
  760. return;
  761. }
  762. ConsumeAnyToken();
  763. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  764. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  765. << getOpenMPDirectiveName(OMPD_end_declare_target);
  766. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  767. }
  768. // Skip the last annot_pragma_openmp_end.
  769. ConsumeAnyToken();
  770. }
  771. /// Parsing of declarative OpenMP directives.
  772. ///
  773. /// threadprivate-directive:
  774. /// annot_pragma_openmp 'threadprivate' simple-variable-list
  775. /// annot_pragma_openmp_end
  776. ///
  777. /// allocate-directive:
  778. /// annot_pragma_openmp 'allocate' simple-variable-list
  779. /// annot_pragma_openmp_end
  780. ///
  781. /// declare-reduction-directive:
  782. /// annot_pragma_openmp 'declare' 'reduction' [...]
  783. /// annot_pragma_openmp_end
  784. ///
  785. /// declare-mapper-directive:
  786. /// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
  787. /// <type> <var> ')' [<clause>[[,] <clause>] ... ]
  788. /// annot_pragma_openmp_end
  789. ///
  790. /// declare-simd-directive:
  791. /// annot_pragma_openmp 'declare simd' {<clause> [,]}
  792. /// annot_pragma_openmp_end
  793. /// <function declaration/definition>
  794. ///
  795. /// requires directive:
  796. /// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
  797. /// annot_pragma_openmp_end
  798. ///
  799. Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
  800. AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
  801. DeclSpec::TST TagType, Decl *Tag) {
  802. assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  803. ParenBraceBracketBalancer BalancerRAIIObj(*this);
  804. SourceLocation Loc = ConsumeAnnotationToken();
  805. OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
  806. switch (DKind) {
  807. case OMPD_threadprivate: {
  808. ConsumeToken();
  809. DeclDirectiveListParserHelper Helper(this, DKind);
  810. if (!ParseOpenMPSimpleVarList(DKind, Helper,
  811. /*AllowScopeSpecifier=*/true)) {
  812. // The last seen token is annot_pragma_openmp_end - need to check for
  813. // extra tokens.
  814. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  815. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  816. << getOpenMPDirectiveName(DKind);
  817. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  818. }
  819. // Skip the last annot_pragma_openmp_end.
  820. ConsumeAnnotationToken();
  821. return Actions.ActOnOpenMPThreadprivateDirective(Loc,
  822. Helper.getIdentifiers());
  823. }
  824. break;
  825. }
  826. case OMPD_allocate: {
  827. ConsumeToken();
  828. DeclDirectiveListParserHelper Helper(this, DKind);
  829. if (!ParseOpenMPSimpleVarList(DKind, Helper,
  830. /*AllowScopeSpecifier=*/true)) {
  831. // The last seen token is annot_pragma_openmp_end - need to check for
  832. // extra tokens.
  833. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  834. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  835. << getOpenMPDirectiveName(DKind);
  836. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  837. }
  838. // Skip the last annot_pragma_openmp_end.
  839. ConsumeAnnotationToken();
  840. return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
  841. }
  842. break;
  843. }
  844. case OMPD_requires: {
  845. SourceLocation StartLoc = ConsumeToken();
  846. SmallVector<OMPClause *, 5> Clauses;
  847. SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
  848. FirstClauses(OMPC_unknown + 1);
  849. if (Tok.is(tok::annot_pragma_openmp_end)) {
  850. Diag(Tok, diag::err_omp_expected_clause)
  851. << getOpenMPDirectiveName(OMPD_requires);
  852. break;
  853. }
  854. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  855. OpenMPClauseKind CKind = Tok.isAnnotation()
  856. ? OMPC_unknown
  857. : getOpenMPClauseKind(PP.getSpelling(Tok));
  858. Actions.StartOpenMPClause(CKind);
  859. OMPClause *Clause =
  860. ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
  861. SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
  862. FirstClauses[CKind].setInt(true);
  863. if (Clause != nullptr)
  864. Clauses.push_back(Clause);
  865. if (Tok.is(tok::annot_pragma_openmp_end)) {
  866. Actions.EndOpenMPClause();
  867. break;
  868. }
  869. // Skip ',' if any.
  870. if (Tok.is(tok::comma))
  871. ConsumeToken();
  872. Actions.EndOpenMPClause();
  873. }
  874. // Consume final annot_pragma_openmp_end
  875. if (Clauses.size() == 0) {
  876. Diag(Tok, diag::err_omp_expected_clause)
  877. << getOpenMPDirectiveName(OMPD_requires);
  878. ConsumeAnnotationToken();
  879. return nullptr;
  880. }
  881. ConsumeAnnotationToken();
  882. return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
  883. }
  884. case OMPD_declare_reduction:
  885. ConsumeToken();
  886. if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
  887. // The last seen token is annot_pragma_openmp_end - need to check for
  888. // extra tokens.
  889. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  890. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  891. << getOpenMPDirectiveName(OMPD_declare_reduction);
  892. while (Tok.isNot(tok::annot_pragma_openmp_end))
  893. ConsumeAnyToken();
  894. }
  895. // Skip the last annot_pragma_openmp_end.
  896. ConsumeAnnotationToken();
  897. return Res;
  898. }
  899. break;
  900. case OMPD_declare_mapper: {
  901. ConsumeToken();
  902. if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
  903. // Skip the last annot_pragma_openmp_end.
  904. ConsumeAnnotationToken();
  905. return Res;
  906. }
  907. break;
  908. }
  909. case OMPD_declare_simd: {
  910. // The syntax is:
  911. // { #pragma omp declare simd }
  912. // <function-declaration-or-definition>
  913. //
  914. ConsumeToken();
  915. CachedTokens Toks;
  916. while(Tok.isNot(tok::annot_pragma_openmp_end)) {
  917. Toks.push_back(Tok);
  918. ConsumeAnyToken();
  919. }
  920. Toks.push_back(Tok);
  921. ConsumeAnyToken();
  922. DeclGroupPtrTy Ptr;
  923. if (Tok.is(tok::annot_pragma_openmp)) {
  924. Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
  925. } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
  926. // Here we expect to see some function declaration.
  927. if (AS == AS_none) {
  928. assert(TagType == DeclSpec::TST_unspecified);
  929. MaybeParseCXX11Attributes(Attrs);
  930. ParsingDeclSpec PDS(*this);
  931. Ptr = ParseExternalDeclaration(Attrs, &PDS);
  932. } else {
  933. Ptr =
  934. ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
  935. }
  936. }
  937. if (!Ptr) {
  938. Diag(Loc, diag::err_omp_decl_in_declare_simd);
  939. return DeclGroupPtrTy();
  940. }
  941. return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
  942. }
  943. case OMPD_declare_target: {
  944. SourceLocation DTLoc = ConsumeAnyToken();
  945. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  946. return ParseOMPDeclareTargetClauses();
  947. }
  948. // Skip the last annot_pragma_openmp_end.
  949. ConsumeAnyToken();
  950. if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
  951. return DeclGroupPtrTy();
  952. llvm::SmallVector<Decl *, 4> Decls;
  953. DKind = parseOpenMPDirectiveKind(*this);
  954. while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
  955. Tok.isNot(tok::r_brace)) {
  956. DeclGroupPtrTy Ptr;
  957. // Here we expect to see some function declaration.
  958. if (AS == AS_none) {
  959. assert(TagType == DeclSpec::TST_unspecified);
  960. MaybeParseCXX11Attributes(Attrs);
  961. ParsingDeclSpec PDS(*this);
  962. Ptr = ParseExternalDeclaration(Attrs, &PDS);
  963. } else {
  964. Ptr =
  965. ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
  966. }
  967. if (Ptr) {
  968. DeclGroupRef Ref = Ptr.get();
  969. Decls.append(Ref.begin(), Ref.end());
  970. }
  971. if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
  972. TentativeParsingAction TPA(*this);
  973. ConsumeAnnotationToken();
  974. DKind = parseOpenMPDirectiveKind(*this);
  975. if (DKind != OMPD_end_declare_target)
  976. TPA.Revert();
  977. else
  978. TPA.Commit();
  979. }
  980. }
  981. ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
  982. Actions.ActOnFinishOpenMPDeclareTargetDirective();
  983. return Actions.BuildDeclaratorGroup(Decls);
  984. }
  985. case OMPD_unknown:
  986. Diag(Tok, diag::err_omp_unknown_directive);
  987. break;
  988. case OMPD_parallel:
  989. case OMPD_simd:
  990. case OMPD_task:
  991. case OMPD_taskyield:
  992. case OMPD_barrier:
  993. case OMPD_taskwait:
  994. case OMPD_taskgroup:
  995. case OMPD_flush:
  996. case OMPD_for:
  997. case OMPD_for_simd:
  998. case OMPD_sections:
  999. case OMPD_section:
  1000. case OMPD_single:
  1001. case OMPD_master:
  1002. case OMPD_ordered:
  1003. case OMPD_critical:
  1004. case OMPD_parallel_for:
  1005. case OMPD_parallel_for_simd:
  1006. case OMPD_parallel_sections:
  1007. case OMPD_atomic:
  1008. case OMPD_target:
  1009. case OMPD_teams:
  1010. case OMPD_cancellation_point:
  1011. case OMPD_cancel:
  1012. case OMPD_target_data:
  1013. case OMPD_target_enter_data:
  1014. case OMPD_target_exit_data:
  1015. case OMPD_target_parallel:
  1016. case OMPD_target_parallel_for:
  1017. case OMPD_taskloop:
  1018. case OMPD_taskloop_simd:
  1019. case OMPD_distribute:
  1020. case OMPD_end_declare_target:
  1021. case OMPD_target_update:
  1022. case OMPD_distribute_parallel_for:
  1023. case OMPD_distribute_parallel_for_simd:
  1024. case OMPD_distribute_simd:
  1025. case OMPD_target_parallel_for_simd:
  1026. case OMPD_target_simd:
  1027. case OMPD_teams_distribute:
  1028. case OMPD_teams_distribute_simd:
  1029. case OMPD_teams_distribute_parallel_for_simd:
  1030. case OMPD_teams_distribute_parallel_for:
  1031. case OMPD_target_teams:
  1032. case OMPD_target_teams_distribute:
  1033. case OMPD_target_teams_distribute_parallel_for:
  1034. case OMPD_target_teams_distribute_parallel_for_simd:
  1035. case OMPD_target_teams_distribute_simd:
  1036. Diag(Tok, diag::err_omp_unexpected_directive)
  1037. << 1 << getOpenMPDirectiveName(DKind);
  1038. break;
  1039. }
  1040. while (Tok.isNot(tok::annot_pragma_openmp_end))
  1041. ConsumeAnyToken();
  1042. ConsumeAnyToken();
  1043. return nullptr;
  1044. }
  1045. /// Parsing of declarative or executable OpenMP directives.
  1046. ///
  1047. /// threadprivate-directive:
  1048. /// annot_pragma_openmp 'threadprivate' simple-variable-list
  1049. /// annot_pragma_openmp_end
  1050. ///
  1051. /// allocate-directive:
  1052. /// annot_pragma_openmp 'allocate' simple-variable-list
  1053. /// annot_pragma_openmp_end
  1054. ///
  1055. /// declare-reduction-directive:
  1056. /// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
  1057. /// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
  1058. /// ('omp_priv' '=' <expression>|<function_call>) ')']
  1059. /// annot_pragma_openmp_end
  1060. ///
  1061. /// declare-mapper-directive:
  1062. /// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
  1063. /// <type> <var> ')' [<clause>[[,] <clause>] ... ]
  1064. /// annot_pragma_openmp_end
  1065. ///
  1066. /// executable-directive:
  1067. /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
  1068. /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
  1069. /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
  1070. /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
  1071. /// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
  1072. /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
  1073. /// 'distribute' | 'target enter data' | 'target exit data' |
  1074. /// 'target parallel' | 'target parallel for' |
  1075. /// 'target update' | 'distribute parallel for' |
  1076. /// 'distribute paralle for simd' | 'distribute simd' |
  1077. /// 'target parallel for simd' | 'target simd' |
  1078. /// 'teams distribute' | 'teams distribute simd' |
  1079. /// 'teams distribute parallel for simd' |
  1080. /// 'teams distribute parallel for' | 'target teams' |
  1081. /// 'target teams distribute' |
  1082. /// 'target teams distribute parallel for' |
  1083. /// 'target teams distribute parallel for simd' |
  1084. /// 'target teams distribute simd' {clause}
  1085. /// annot_pragma_openmp_end
  1086. ///
  1087. StmtResult
  1088. Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
  1089. assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  1090. ParenBraceBracketBalancer BalancerRAIIObj(*this);
  1091. SmallVector<OMPClause *, 5> Clauses;
  1092. SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
  1093. FirstClauses(OMPC_unknown + 1);
  1094. unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
  1095. Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
  1096. SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
  1097. OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
  1098. OpenMPDirectiveKind CancelRegion = OMPD_unknown;
  1099. // Name of critical directive.
  1100. DeclarationNameInfo DirName;
  1101. StmtResult Directive = StmtError();
  1102. bool HasAssociatedStatement = true;
  1103. bool FlushHasClause = false;
  1104. switch (DKind) {
  1105. case OMPD_threadprivate: {
  1106. // FIXME: Should this be permitted in C++?
  1107. if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
  1108. ParsedStmtContext()) {
  1109. Diag(Tok, diag::err_omp_immediate_directive)
  1110. << getOpenMPDirectiveName(DKind) << 0;
  1111. }
  1112. ConsumeToken();
  1113. DeclDirectiveListParserHelper Helper(this, DKind);
  1114. if (!ParseOpenMPSimpleVarList(DKind, Helper,
  1115. /*AllowScopeSpecifier=*/false)) {
  1116. // The last seen token is annot_pragma_openmp_end - need to check for
  1117. // extra tokens.
  1118. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  1119. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  1120. << getOpenMPDirectiveName(DKind);
  1121. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  1122. }
  1123. DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
  1124. Loc, Helper.getIdentifiers());
  1125. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  1126. }
  1127. SkipUntil(tok::annot_pragma_openmp_end);
  1128. break;
  1129. }
  1130. case OMPD_allocate: {
  1131. // FIXME: Should this be permitted in C++?
  1132. if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
  1133. ParsedStmtContext()) {
  1134. Diag(Tok, diag::err_omp_immediate_directive)
  1135. << getOpenMPDirectiveName(DKind) << 0;
  1136. }
  1137. ConsumeToken();
  1138. DeclDirectiveListParserHelper Helper(this, DKind);
  1139. if (!ParseOpenMPSimpleVarList(DKind, Helper,
  1140. /*AllowScopeSpecifier=*/false)) {
  1141. // The last seen token is annot_pragma_openmp_end - need to check for
  1142. // extra tokens.
  1143. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  1144. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  1145. << getOpenMPDirectiveName(DKind);
  1146. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  1147. }
  1148. DeclGroupPtrTy Res =
  1149. Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
  1150. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  1151. }
  1152. SkipUntil(tok::annot_pragma_openmp_end);
  1153. break;
  1154. }
  1155. case OMPD_declare_reduction:
  1156. ConsumeToken();
  1157. if (DeclGroupPtrTy Res =
  1158. ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
  1159. // The last seen token is annot_pragma_openmp_end - need to check for
  1160. // extra tokens.
  1161. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  1162. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  1163. << getOpenMPDirectiveName(OMPD_declare_reduction);
  1164. while (Tok.isNot(tok::annot_pragma_openmp_end))
  1165. ConsumeAnyToken();
  1166. }
  1167. ConsumeAnyToken();
  1168. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  1169. } else {
  1170. SkipUntil(tok::annot_pragma_openmp_end);
  1171. }
  1172. break;
  1173. case OMPD_declare_mapper: {
  1174. ConsumeToken();
  1175. if (DeclGroupPtrTy Res =
  1176. ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
  1177. // Skip the last annot_pragma_openmp_end.
  1178. ConsumeAnnotationToken();
  1179. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  1180. } else {
  1181. SkipUntil(tok::annot_pragma_openmp_end);
  1182. }
  1183. break;
  1184. }
  1185. case OMPD_flush:
  1186. if (PP.LookAhead(0).is(tok::l_paren)) {
  1187. FlushHasClause = true;
  1188. // Push copy of the current token back to stream to properly parse
  1189. // pseudo-clause OMPFlushClause.
  1190. PP.EnterToken(Tok);
  1191. }
  1192. LLVM_FALLTHROUGH;
  1193. case OMPD_taskyield:
  1194. case OMPD_barrier:
  1195. case OMPD_taskwait:
  1196. case OMPD_cancellation_point:
  1197. case OMPD_cancel:
  1198. case OMPD_target_enter_data:
  1199. case OMPD_target_exit_data:
  1200. case OMPD_target_update:
  1201. if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
  1202. ParsedStmtContext()) {
  1203. Diag(Tok, diag::err_omp_immediate_directive)
  1204. << getOpenMPDirectiveName(DKind) << 0;
  1205. }
  1206. HasAssociatedStatement = false;
  1207. // Fall through for further analysis.
  1208. LLVM_FALLTHROUGH;
  1209. case OMPD_parallel:
  1210. case OMPD_simd:
  1211. case OMPD_for:
  1212. case OMPD_for_simd:
  1213. case OMPD_sections:
  1214. case OMPD_single:
  1215. case OMPD_section:
  1216. case OMPD_master:
  1217. case OMPD_critical:
  1218. case OMPD_parallel_for:
  1219. case OMPD_parallel_for_simd:
  1220. case OMPD_parallel_sections:
  1221. case OMPD_task:
  1222. case OMPD_ordered:
  1223. case OMPD_atomic:
  1224. case OMPD_target:
  1225. case OMPD_teams:
  1226. case OMPD_taskgroup:
  1227. case OMPD_target_data:
  1228. case OMPD_target_parallel:
  1229. case OMPD_target_parallel_for:
  1230. case OMPD_taskloop:
  1231. case OMPD_taskloop_simd:
  1232. case OMPD_distribute:
  1233. case OMPD_distribute_parallel_for:
  1234. case OMPD_distribute_parallel_for_simd:
  1235. case OMPD_distribute_simd:
  1236. case OMPD_target_parallel_for_simd:
  1237. case OMPD_target_simd:
  1238. case OMPD_teams_distribute:
  1239. case OMPD_teams_distribute_simd:
  1240. case OMPD_teams_distribute_parallel_for_simd:
  1241. case OMPD_teams_distribute_parallel_for:
  1242. case OMPD_target_teams:
  1243. case OMPD_target_teams_distribute:
  1244. case OMPD_target_teams_distribute_parallel_for:
  1245. case OMPD_target_teams_distribute_parallel_for_simd:
  1246. case OMPD_target_teams_distribute_simd: {
  1247. ConsumeToken();
  1248. // Parse directive name of the 'critical' directive if any.
  1249. if (DKind == OMPD_critical) {
  1250. BalancedDelimiterTracker T(*this, tok::l_paren,
  1251. tok::annot_pragma_openmp_end);
  1252. if (!T.consumeOpen()) {
  1253. if (Tok.isAnyIdentifier()) {
  1254. DirName =
  1255. DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
  1256. ConsumeAnyToken();
  1257. } else {
  1258. Diag(Tok, diag::err_omp_expected_identifier_for_critical);
  1259. }
  1260. T.consumeClose();
  1261. }
  1262. } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
  1263. CancelRegion = parseOpenMPDirectiveKind(*this);
  1264. if (Tok.isNot(tok::annot_pragma_openmp_end))
  1265. ConsumeToken();
  1266. }
  1267. if (isOpenMPLoopDirective(DKind))
  1268. ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
  1269. if (isOpenMPSimdDirective(DKind))
  1270. ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
  1271. ParseScope OMPDirectiveScope(this, ScopeFlags);
  1272. Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
  1273. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  1274. OpenMPClauseKind CKind =
  1275. Tok.isAnnotation()
  1276. ? OMPC_unknown
  1277. : FlushHasClause ? OMPC_flush
  1278. : getOpenMPClauseKind(PP.getSpelling(Tok));
  1279. Actions.StartOpenMPClause(CKind);
  1280. FlushHasClause = false;
  1281. OMPClause *Clause =
  1282. ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
  1283. FirstClauses[CKind].setInt(true);
  1284. if (Clause) {
  1285. FirstClauses[CKind].setPointer(Clause);
  1286. Clauses.push_back(Clause);
  1287. }
  1288. // Skip ',' if any.
  1289. if (Tok.is(tok::comma))
  1290. ConsumeToken();
  1291. Actions.EndOpenMPClause();
  1292. }
  1293. // End location of the directive.
  1294. EndLoc = Tok.getLocation();
  1295. // Consume final annot_pragma_openmp_end.
  1296. ConsumeAnnotationToken();
  1297. // OpenMP [2.13.8, ordered Construct, Syntax]
  1298. // If the depend clause is specified, the ordered construct is a stand-alone
  1299. // directive.
  1300. if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
  1301. if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
  1302. ParsedStmtContext()) {
  1303. Diag(Loc, diag::err_omp_immediate_directive)
  1304. << getOpenMPDirectiveName(DKind) << 1
  1305. << getOpenMPClauseName(OMPC_depend);
  1306. }
  1307. HasAssociatedStatement = false;
  1308. }
  1309. StmtResult AssociatedStmt;
  1310. if (HasAssociatedStatement) {
  1311. // The body is a block scope like in Lambdas and Blocks.
  1312. Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
  1313. // FIXME: We create a bogus CompoundStmt scope to hold the contents of
  1314. // the captured region. Code elsewhere assumes that any FunctionScopeInfo
  1315. // should have at least one compound statement scope within it.
  1316. AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
  1317. AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
  1318. } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
  1319. DKind == OMPD_target_exit_data) {
  1320. Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
  1321. AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
  1322. Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
  1323. /*isStmtExpr=*/false));
  1324. AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
  1325. }
  1326. Directive = Actions.ActOnOpenMPExecutableDirective(
  1327. DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
  1328. EndLoc);
  1329. // Exit scope.
  1330. Actions.EndOpenMPDSABlock(Directive.get());
  1331. OMPDirectiveScope.Exit();
  1332. break;
  1333. }
  1334. case OMPD_declare_simd:
  1335. case OMPD_declare_target:
  1336. case OMPD_end_declare_target:
  1337. case OMPD_requires:
  1338. Diag(Tok, diag::err_omp_unexpected_directive)
  1339. << 1 << getOpenMPDirectiveName(DKind);
  1340. SkipUntil(tok::annot_pragma_openmp_end);
  1341. break;
  1342. case OMPD_unknown:
  1343. Diag(Tok, diag::err_omp_unknown_directive);
  1344. SkipUntil(tok::annot_pragma_openmp_end);
  1345. break;
  1346. }
  1347. return Directive;
  1348. }
  1349. // Parses simple list:
  1350. // simple-variable-list:
  1351. // '(' id-expression {, id-expression} ')'
  1352. //
  1353. bool Parser::ParseOpenMPSimpleVarList(
  1354. OpenMPDirectiveKind Kind,
  1355. const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
  1356. Callback,
  1357. bool AllowScopeSpecifier) {
  1358. // Parse '('.
  1359. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1360. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1361. getOpenMPDirectiveName(Kind)))
  1362. return true;
  1363. bool IsCorrect = true;
  1364. bool NoIdentIsFound = true;
  1365. // Read tokens while ')' or annot_pragma_openmp_end is not found.
  1366. while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
  1367. CXXScopeSpec SS;
  1368. UnqualifiedId Name;
  1369. // Read var name.
  1370. Token PrevTok = Tok;
  1371. NoIdentIsFound = false;
  1372. if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
  1373. ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
  1374. IsCorrect = false;
  1375. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  1376. StopBeforeMatch);
  1377. } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
  1378. nullptr, Name)) {
  1379. IsCorrect = false;
  1380. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  1381. StopBeforeMatch);
  1382. } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
  1383. Tok.isNot(tok::annot_pragma_openmp_end)) {
  1384. IsCorrect = false;
  1385. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  1386. StopBeforeMatch);
  1387. Diag(PrevTok.getLocation(), diag::err_expected)
  1388. << tok::identifier
  1389. << SourceRange(PrevTok.getLocation(), PrevTokLocation);
  1390. } else {
  1391. Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
  1392. }
  1393. // Consume ','.
  1394. if (Tok.is(tok::comma)) {
  1395. ConsumeToken();
  1396. }
  1397. }
  1398. if (NoIdentIsFound) {
  1399. Diag(Tok, diag::err_expected) << tok::identifier;
  1400. IsCorrect = false;
  1401. }
  1402. // Parse ')'.
  1403. IsCorrect = !T.consumeClose() && IsCorrect;
  1404. return !IsCorrect;
  1405. }
  1406. /// Parsing of OpenMP clauses.
  1407. ///
  1408. /// clause:
  1409. /// if-clause | final-clause | num_threads-clause | safelen-clause |
  1410. /// default-clause | private-clause | firstprivate-clause | shared-clause
  1411. /// | linear-clause | aligned-clause | collapse-clause |
  1412. /// lastprivate-clause | reduction-clause | proc_bind-clause |
  1413. /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
  1414. /// mergeable-clause | flush-clause | read-clause | write-clause |
  1415. /// update-clause | capture-clause | seq_cst-clause | device-clause |
  1416. /// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
  1417. /// thread_limit-clause | priority-clause | grainsize-clause |
  1418. /// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
  1419. /// from-clause | is_device_ptr-clause | task_reduction-clause |
  1420. /// in_reduction-clause
  1421. ///
  1422. OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
  1423. OpenMPClauseKind CKind, bool FirstClause) {
  1424. OMPClause *Clause = nullptr;
  1425. bool ErrorFound = false;
  1426. bool WrongDirective = false;
  1427. // Check if clause is allowed for the given directive.
  1428. if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
  1429. Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
  1430. << getOpenMPDirectiveName(DKind);
  1431. ErrorFound = true;
  1432. WrongDirective = true;
  1433. }
  1434. switch (CKind) {
  1435. case OMPC_final:
  1436. case OMPC_num_threads:
  1437. case OMPC_safelen:
  1438. case OMPC_simdlen:
  1439. case OMPC_collapse:
  1440. case OMPC_ordered:
  1441. case OMPC_device:
  1442. case OMPC_num_teams:
  1443. case OMPC_thread_limit:
  1444. case OMPC_priority:
  1445. case OMPC_grainsize:
  1446. case OMPC_num_tasks:
  1447. case OMPC_hint:
  1448. // OpenMP [2.5, Restrictions]
  1449. // At most one num_threads clause can appear on the directive.
  1450. // OpenMP [2.8.1, simd construct, Restrictions]
  1451. // Only one safelen clause can appear on a simd directive.
  1452. // Only one simdlen clause can appear on a simd directive.
  1453. // Only one collapse clause can appear on a simd directive.
  1454. // OpenMP [2.9.1, target data construct, Restrictions]
  1455. // At most one device clause can appear on the directive.
  1456. // OpenMP [2.11.1, task Construct, Restrictions]
  1457. // At most one if clause can appear on the directive.
  1458. // At most one final clause can appear on the directive.
  1459. // OpenMP [teams Construct, Restrictions]
  1460. // At most one num_teams clause can appear on the directive.
  1461. // At most one thread_limit clause can appear on the directive.
  1462. // OpenMP [2.9.1, task Construct, Restrictions]
  1463. // At most one priority clause can appear on the directive.
  1464. // OpenMP [2.9.2, taskloop Construct, Restrictions]
  1465. // At most one grainsize clause can appear on the directive.
  1466. // OpenMP [2.9.2, taskloop Construct, Restrictions]
  1467. // At most one num_tasks clause can appear on the directive.
  1468. if (!FirstClause) {
  1469. Diag(Tok, diag::err_omp_more_one_clause)
  1470. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1471. ErrorFound = true;
  1472. }
  1473. if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
  1474. Clause = ParseOpenMPClause(CKind, WrongDirective);
  1475. else
  1476. Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
  1477. break;
  1478. case OMPC_default:
  1479. case OMPC_proc_bind:
  1480. case OMPC_atomic_default_mem_order:
  1481. // OpenMP [2.14.3.1, Restrictions]
  1482. // Only a single default clause may be specified on a parallel, task or
  1483. // teams directive.
  1484. // OpenMP [2.5, parallel Construct, Restrictions]
  1485. // At most one proc_bind clause can appear on the directive.
  1486. // OpenMP [5.0, Requires directive, Restrictions]
  1487. // At most one atomic_default_mem_order clause can appear
  1488. // on the directive
  1489. if (!FirstClause) {
  1490. Diag(Tok, diag::err_omp_more_one_clause)
  1491. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1492. ErrorFound = true;
  1493. }
  1494. Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
  1495. break;
  1496. case OMPC_schedule:
  1497. case OMPC_dist_schedule:
  1498. case OMPC_defaultmap:
  1499. // OpenMP [2.7.1, Restrictions, p. 3]
  1500. // Only one schedule clause can appear on a loop directive.
  1501. // OpenMP [2.10.4, Restrictions, p. 106]
  1502. // At most one defaultmap clause can appear on the directive.
  1503. if (!FirstClause) {
  1504. Diag(Tok, diag::err_omp_more_one_clause)
  1505. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1506. ErrorFound = true;
  1507. }
  1508. LLVM_FALLTHROUGH;
  1509. case OMPC_if:
  1510. Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
  1511. break;
  1512. case OMPC_nowait:
  1513. case OMPC_untied:
  1514. case OMPC_mergeable:
  1515. case OMPC_read:
  1516. case OMPC_write:
  1517. case OMPC_update:
  1518. case OMPC_capture:
  1519. case OMPC_seq_cst:
  1520. case OMPC_threads:
  1521. case OMPC_simd:
  1522. case OMPC_nogroup:
  1523. case OMPC_unified_address:
  1524. case OMPC_unified_shared_memory:
  1525. case OMPC_reverse_offload:
  1526. case OMPC_dynamic_allocators:
  1527. // OpenMP [2.7.1, Restrictions, p. 9]
  1528. // Only one ordered clause can appear on a loop directive.
  1529. // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
  1530. // Only one nowait clause can appear on a for directive.
  1531. // OpenMP [5.0, Requires directive, Restrictions]
  1532. // Each of the requires clauses can appear at most once on the directive.
  1533. if (!FirstClause) {
  1534. Diag(Tok, diag::err_omp_more_one_clause)
  1535. << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
  1536. ErrorFound = true;
  1537. }
  1538. Clause = ParseOpenMPClause(CKind, WrongDirective);
  1539. break;
  1540. case OMPC_private:
  1541. case OMPC_firstprivate:
  1542. case OMPC_lastprivate:
  1543. case OMPC_shared:
  1544. case OMPC_reduction:
  1545. case OMPC_task_reduction:
  1546. case OMPC_in_reduction:
  1547. case OMPC_linear:
  1548. case OMPC_aligned:
  1549. case OMPC_copyin:
  1550. case OMPC_copyprivate:
  1551. case OMPC_flush:
  1552. case OMPC_depend:
  1553. case OMPC_map:
  1554. case OMPC_to:
  1555. case OMPC_from:
  1556. case OMPC_use_device_ptr:
  1557. case OMPC_is_device_ptr:
  1558. Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
  1559. break;
  1560. case OMPC_unknown:
  1561. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  1562. << getOpenMPDirectiveName(DKind);
  1563. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  1564. break;
  1565. case OMPC_threadprivate:
  1566. case OMPC_allocate:
  1567. case OMPC_uniform:
  1568. if (!WrongDirective)
  1569. Diag(Tok, diag::err_omp_unexpected_clause)
  1570. << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
  1571. SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
  1572. break;
  1573. }
  1574. return ErrorFound ? nullptr : Clause;
  1575. }
  1576. /// Parses simple expression in parens for single-expression clauses of OpenMP
  1577. /// constructs.
  1578. /// \param RLoc Returned location of right paren.
  1579. ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
  1580. SourceLocation &RLoc) {
  1581. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1582. if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
  1583. return ExprError();
  1584. SourceLocation ELoc = Tok.getLocation();
  1585. ExprResult LHS(ParseCastExpression(
  1586. /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
  1587. ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
  1588. Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
  1589. // Parse ')'.
  1590. RLoc = Tok.getLocation();
  1591. if (!T.consumeClose())
  1592. RLoc = T.getCloseLocation();
  1593. return Val;
  1594. }
  1595. /// Parsing of OpenMP clauses with single expressions like 'final',
  1596. /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
  1597. /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
  1598. ///
  1599. /// final-clause:
  1600. /// 'final' '(' expression ')'
  1601. ///
  1602. /// num_threads-clause:
  1603. /// 'num_threads' '(' expression ')'
  1604. ///
  1605. /// safelen-clause:
  1606. /// 'safelen' '(' expression ')'
  1607. ///
  1608. /// simdlen-clause:
  1609. /// 'simdlen' '(' expression ')'
  1610. ///
  1611. /// collapse-clause:
  1612. /// 'collapse' '(' expression ')'
  1613. ///
  1614. /// priority-clause:
  1615. /// 'priority' '(' expression ')'
  1616. ///
  1617. /// grainsize-clause:
  1618. /// 'grainsize' '(' expression ')'
  1619. ///
  1620. /// num_tasks-clause:
  1621. /// 'num_tasks' '(' expression ')'
  1622. ///
  1623. /// hint-clause:
  1624. /// 'hint' '(' expression ')'
  1625. ///
  1626. OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
  1627. bool ParseOnly) {
  1628. SourceLocation Loc = ConsumeToken();
  1629. SourceLocation LLoc = Tok.getLocation();
  1630. SourceLocation RLoc;
  1631. ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
  1632. if (Val.isInvalid())
  1633. return nullptr;
  1634. if (ParseOnly)
  1635. return nullptr;
  1636. return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
  1637. }
  1638. /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
  1639. ///
  1640. /// default-clause:
  1641. /// 'default' '(' 'none' | 'shared' ')
  1642. ///
  1643. /// proc_bind-clause:
  1644. /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
  1645. ///
  1646. OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
  1647. bool ParseOnly) {
  1648. SourceLocation Loc = Tok.getLocation();
  1649. SourceLocation LOpen = ConsumeToken();
  1650. // Parse '('.
  1651. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1652. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1653. getOpenMPClauseName(Kind)))
  1654. return nullptr;
  1655. unsigned Type = getOpenMPSimpleClauseType(
  1656. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1657. SourceLocation TypeLoc = Tok.getLocation();
  1658. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1659. Tok.isNot(tok::annot_pragma_openmp_end))
  1660. ConsumeAnyToken();
  1661. // Parse ')'.
  1662. SourceLocation RLoc = Tok.getLocation();
  1663. if (!T.consumeClose())
  1664. RLoc = T.getCloseLocation();
  1665. if (ParseOnly)
  1666. return nullptr;
  1667. return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
  1668. }
  1669. /// Parsing of OpenMP clauses like 'ordered'.
  1670. ///
  1671. /// ordered-clause:
  1672. /// 'ordered'
  1673. ///
  1674. /// nowait-clause:
  1675. /// 'nowait'
  1676. ///
  1677. /// untied-clause:
  1678. /// 'untied'
  1679. ///
  1680. /// mergeable-clause:
  1681. /// 'mergeable'
  1682. ///
  1683. /// read-clause:
  1684. /// 'read'
  1685. ///
  1686. /// threads-clause:
  1687. /// 'threads'
  1688. ///
  1689. /// simd-clause:
  1690. /// 'simd'
  1691. ///
  1692. /// nogroup-clause:
  1693. /// 'nogroup'
  1694. ///
  1695. OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
  1696. SourceLocation Loc = Tok.getLocation();
  1697. ConsumeAnyToken();
  1698. if (ParseOnly)
  1699. return nullptr;
  1700. return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
  1701. }
  1702. /// Parsing of OpenMP clauses with single expressions and some additional
  1703. /// argument like 'schedule' or 'dist_schedule'.
  1704. ///
  1705. /// schedule-clause:
  1706. /// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
  1707. /// ')'
  1708. ///
  1709. /// if-clause:
  1710. /// 'if' '(' [ directive-name-modifier ':' ] expression ')'
  1711. ///
  1712. /// defaultmap:
  1713. /// 'defaultmap' '(' modifier ':' kind ')'
  1714. ///
  1715. OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
  1716. bool ParseOnly) {
  1717. SourceLocation Loc = ConsumeToken();
  1718. SourceLocation DelimLoc;
  1719. // Parse '('.
  1720. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1721. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1722. getOpenMPClauseName(Kind)))
  1723. return nullptr;
  1724. ExprResult Val;
  1725. SmallVector<unsigned, 4> Arg;
  1726. SmallVector<SourceLocation, 4> KLoc;
  1727. if (Kind == OMPC_schedule) {
  1728. enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
  1729. Arg.resize(NumberOfElements);
  1730. KLoc.resize(NumberOfElements);
  1731. Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
  1732. Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
  1733. Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
  1734. unsigned KindModifier = getOpenMPSimpleClauseType(
  1735. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1736. if (KindModifier > OMPC_SCHEDULE_unknown) {
  1737. // Parse 'modifier'
  1738. Arg[Modifier1] = KindModifier;
  1739. KLoc[Modifier1] = Tok.getLocation();
  1740. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1741. Tok.isNot(tok::annot_pragma_openmp_end))
  1742. ConsumeAnyToken();
  1743. if (Tok.is(tok::comma)) {
  1744. // Parse ',' 'modifier'
  1745. ConsumeAnyToken();
  1746. KindModifier = getOpenMPSimpleClauseType(
  1747. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1748. Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
  1749. ? KindModifier
  1750. : (unsigned)OMPC_SCHEDULE_unknown;
  1751. KLoc[Modifier2] = Tok.getLocation();
  1752. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1753. Tok.isNot(tok::annot_pragma_openmp_end))
  1754. ConsumeAnyToken();
  1755. }
  1756. // Parse ':'
  1757. if (Tok.is(tok::colon))
  1758. ConsumeAnyToken();
  1759. else
  1760. Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
  1761. KindModifier = getOpenMPSimpleClauseType(
  1762. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  1763. }
  1764. Arg[ScheduleKind] = KindModifier;
  1765. KLoc[ScheduleKind] = Tok.getLocation();
  1766. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1767. Tok.isNot(tok::annot_pragma_openmp_end))
  1768. ConsumeAnyToken();
  1769. if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
  1770. Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
  1771. Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
  1772. Tok.is(tok::comma))
  1773. DelimLoc = ConsumeAnyToken();
  1774. } else if (Kind == OMPC_dist_schedule) {
  1775. Arg.push_back(getOpenMPSimpleClauseType(
  1776. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
  1777. KLoc.push_back(Tok.getLocation());
  1778. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1779. Tok.isNot(tok::annot_pragma_openmp_end))
  1780. ConsumeAnyToken();
  1781. if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
  1782. DelimLoc = ConsumeAnyToken();
  1783. } else if (Kind == OMPC_defaultmap) {
  1784. // Get a defaultmap modifier
  1785. Arg.push_back(getOpenMPSimpleClauseType(
  1786. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
  1787. KLoc.push_back(Tok.getLocation());
  1788. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1789. Tok.isNot(tok::annot_pragma_openmp_end))
  1790. ConsumeAnyToken();
  1791. // Parse ':'
  1792. if (Tok.is(tok::colon))
  1793. ConsumeAnyToken();
  1794. else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
  1795. Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
  1796. // Get a defaultmap kind
  1797. Arg.push_back(getOpenMPSimpleClauseType(
  1798. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
  1799. KLoc.push_back(Tok.getLocation());
  1800. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  1801. Tok.isNot(tok::annot_pragma_openmp_end))
  1802. ConsumeAnyToken();
  1803. } else {
  1804. assert(Kind == OMPC_if);
  1805. KLoc.push_back(Tok.getLocation());
  1806. TentativeParsingAction TPA(*this);
  1807. Arg.push_back(parseOpenMPDirectiveKind(*this));
  1808. if (Arg.back() != OMPD_unknown) {
  1809. ConsumeToken();
  1810. if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
  1811. TPA.Commit();
  1812. DelimLoc = ConsumeToken();
  1813. } else {
  1814. TPA.Revert();
  1815. Arg.back() = OMPD_unknown;
  1816. }
  1817. } else {
  1818. TPA.Revert();
  1819. }
  1820. }
  1821. bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
  1822. (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
  1823. Kind == OMPC_if;
  1824. if (NeedAnExpression) {
  1825. SourceLocation ELoc = Tok.getLocation();
  1826. ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
  1827. Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
  1828. Val =
  1829. Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
  1830. }
  1831. // Parse ')'.
  1832. SourceLocation RLoc = Tok.getLocation();
  1833. if (!T.consumeClose())
  1834. RLoc = T.getCloseLocation();
  1835. if (NeedAnExpression && Val.isInvalid())
  1836. return nullptr;
  1837. if (ParseOnly)
  1838. return nullptr;
  1839. return Actions.ActOnOpenMPSingleExprWithArgClause(
  1840. Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
  1841. }
  1842. static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
  1843. UnqualifiedId &ReductionId) {
  1844. if (ReductionIdScopeSpec.isEmpty()) {
  1845. auto OOK = OO_None;
  1846. switch (P.getCurToken().getKind()) {
  1847. case tok::plus:
  1848. OOK = OO_Plus;
  1849. break;
  1850. case tok::minus:
  1851. OOK = OO_Minus;
  1852. break;
  1853. case tok::star:
  1854. OOK = OO_Star;
  1855. break;
  1856. case tok::amp:
  1857. OOK = OO_Amp;
  1858. break;
  1859. case tok::pipe:
  1860. OOK = OO_Pipe;
  1861. break;
  1862. case tok::caret:
  1863. OOK = OO_Caret;
  1864. break;
  1865. case tok::ampamp:
  1866. OOK = OO_AmpAmp;
  1867. break;
  1868. case tok::pipepipe:
  1869. OOK = OO_PipePipe;
  1870. break;
  1871. default:
  1872. break;
  1873. }
  1874. if (OOK != OO_None) {
  1875. SourceLocation OpLoc = P.ConsumeToken();
  1876. SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
  1877. ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
  1878. return false;
  1879. }
  1880. }
  1881. return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
  1882. /*AllowDestructorName*/ false,
  1883. /*AllowConstructorName*/ false,
  1884. /*AllowDeductionGuide*/ false,
  1885. nullptr, nullptr, ReductionId);
  1886. }
  1887. /// Checks if the token is a valid map-type-modifier.
  1888. static OpenMPMapModifierKind isMapModifier(Parser &P) {
  1889. Token Tok = P.getCurToken();
  1890. if (!Tok.is(tok::identifier))
  1891. return OMPC_MAP_MODIFIER_unknown;
  1892. Preprocessor &PP = P.getPreprocessor();
  1893. OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
  1894. getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
  1895. return TypeModifier;
  1896. }
  1897. /// Parse the mapper modifier in map, to, and from clauses.
  1898. bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
  1899. // Parse '('.
  1900. BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
  1901. if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
  1902. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  1903. StopBeforeMatch);
  1904. return true;
  1905. }
  1906. // Parse mapper-identifier
  1907. if (getLangOpts().CPlusPlus)
  1908. ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
  1909. /*ObjectType=*/nullptr,
  1910. /*EnteringContext=*/false);
  1911. if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
  1912. Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
  1913. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  1914. StopBeforeMatch);
  1915. return true;
  1916. }
  1917. auto &DeclNames = Actions.getASTContext().DeclarationNames;
  1918. Data.ReductionOrMapperId = DeclarationNameInfo(
  1919. DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
  1920. ConsumeToken();
  1921. // Parse ')'.
  1922. return T.consumeClose();
  1923. }
  1924. /// Parse map-type-modifiers in map clause.
  1925. /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
  1926. /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
  1927. bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
  1928. while (getCurToken().isNot(tok::colon)) {
  1929. OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
  1930. if (TypeModifier == OMPC_MAP_MODIFIER_always ||
  1931. TypeModifier == OMPC_MAP_MODIFIER_close) {
  1932. Data.MapTypeModifiers.push_back(TypeModifier);
  1933. Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
  1934. ConsumeToken();
  1935. } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
  1936. Data.MapTypeModifiers.push_back(TypeModifier);
  1937. Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
  1938. ConsumeToken();
  1939. if (parseMapperModifier(Data))
  1940. return true;
  1941. } else {
  1942. // For the case of unknown map-type-modifier or a map-type.
  1943. // Map-type is followed by a colon; the function returns when it
  1944. // encounters a token followed by a colon.
  1945. if (Tok.is(tok::comma)) {
  1946. Diag(Tok, diag::err_omp_map_type_modifier_missing);
  1947. ConsumeToken();
  1948. continue;
  1949. }
  1950. // Potential map-type token as it is followed by a colon.
  1951. if (PP.LookAhead(0).is(tok::colon))
  1952. return false;
  1953. Diag(Tok, diag::err_omp_unknown_map_type_modifier);
  1954. ConsumeToken();
  1955. }
  1956. if (getCurToken().is(tok::comma))
  1957. ConsumeToken();
  1958. }
  1959. return false;
  1960. }
  1961. /// Checks if the token is a valid map-type.
  1962. static OpenMPMapClauseKind isMapType(Parser &P) {
  1963. Token Tok = P.getCurToken();
  1964. // The map-type token can be either an identifier or the C++ delete keyword.
  1965. if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
  1966. return OMPC_MAP_unknown;
  1967. Preprocessor &PP = P.getPreprocessor();
  1968. OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
  1969. getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
  1970. return MapType;
  1971. }
  1972. /// Parse map-type in map clause.
  1973. /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
  1974. /// where, map-type ::= to | from | tofrom | alloc | release | delete
  1975. static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
  1976. Token Tok = P.getCurToken();
  1977. if (Tok.is(tok::colon)) {
  1978. P.Diag(Tok, diag::err_omp_map_type_missing);
  1979. return;
  1980. }
  1981. Data.MapType = isMapType(P);
  1982. if (Data.MapType == OMPC_MAP_unknown)
  1983. P.Diag(Tok, diag::err_omp_unknown_map_type);
  1984. P.ConsumeToken();
  1985. }
  1986. /// Parses clauses with list.
  1987. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
  1988. OpenMPClauseKind Kind,
  1989. SmallVectorImpl<Expr *> &Vars,
  1990. OpenMPVarListDataTy &Data) {
  1991. UnqualifiedId UnqualifiedReductionId;
  1992. bool InvalidReductionId = false;
  1993. bool IsInvalidMapperModifier = false;
  1994. // Parse '('.
  1995. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  1996. if (T.expectAndConsume(diag::err_expected_lparen_after,
  1997. getOpenMPClauseName(Kind)))
  1998. return true;
  1999. bool NeedRParenForLinear = false;
  2000. BalancedDelimiterTracker LinearT(*this, tok::l_paren,
  2001. tok::annot_pragma_openmp_end);
  2002. // Handle reduction-identifier for reduction clause.
  2003. if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
  2004. Kind == OMPC_in_reduction) {
  2005. ColonProtectionRAIIObject ColonRAII(*this);
  2006. if (getLangOpts().CPlusPlus)
  2007. ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
  2008. /*ObjectType=*/nullptr,
  2009. /*EnteringContext=*/false);
  2010. InvalidReductionId = ParseReductionId(
  2011. *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
  2012. if (InvalidReductionId) {
  2013. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  2014. StopBeforeMatch);
  2015. }
  2016. if (Tok.is(tok::colon))
  2017. Data.ColonLoc = ConsumeToken();
  2018. else
  2019. Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
  2020. if (!InvalidReductionId)
  2021. Data.ReductionOrMapperId =
  2022. Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
  2023. } else if (Kind == OMPC_depend) {
  2024. // Handle dependency type for depend clause.
  2025. ColonProtectionRAIIObject ColonRAII(*this);
  2026. Data.DepKind =
  2027. static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
  2028. Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
  2029. Data.DepLinMapLoc = Tok.getLocation();
  2030. if (Data.DepKind == OMPC_DEPEND_unknown) {
  2031. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  2032. StopBeforeMatch);
  2033. } else {
  2034. ConsumeToken();
  2035. // Special processing for depend(source) clause.
  2036. if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
  2037. // Parse ')'.
  2038. T.consumeClose();
  2039. return false;
  2040. }
  2041. }
  2042. if (Tok.is(tok::colon)) {
  2043. Data.ColonLoc = ConsumeToken();
  2044. } else {
  2045. Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
  2046. : diag::warn_pragma_expected_colon)
  2047. << "dependency type";
  2048. }
  2049. } else if (Kind == OMPC_linear) {
  2050. // Try to parse modifier if any.
  2051. if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
  2052. Data.LinKind = static_cast<OpenMPLinearClauseKind>(
  2053. getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
  2054. Data.DepLinMapLoc = ConsumeToken();
  2055. LinearT.consumeOpen();
  2056. NeedRParenForLinear = true;
  2057. }
  2058. } else if (Kind == OMPC_map) {
  2059. // Handle map type for map clause.
  2060. ColonProtectionRAIIObject ColonRAII(*this);
  2061. // The first identifier may be a list item, a map-type or a
  2062. // map-type-modifier. The map-type can also be delete which has the same
  2063. // spelling of the C++ delete keyword.
  2064. Data.DepLinMapLoc = Tok.getLocation();
  2065. // Check for presence of a colon in the map clause.
  2066. TentativeParsingAction TPA(*this);
  2067. bool ColonPresent = false;
  2068. if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  2069. StopBeforeMatch)) {
  2070. if (Tok.is(tok::colon))
  2071. ColonPresent = true;
  2072. }
  2073. TPA.Revert();
  2074. // Only parse map-type-modifier[s] and map-type if a colon is present in
  2075. // the map clause.
  2076. if (ColonPresent) {
  2077. IsInvalidMapperModifier = parseMapTypeModifiers(Data);
  2078. if (!IsInvalidMapperModifier)
  2079. parseMapType(*this, Data);
  2080. else
  2081. SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
  2082. }
  2083. if (Data.MapType == OMPC_MAP_unknown) {
  2084. Data.MapType = OMPC_MAP_tofrom;
  2085. Data.IsMapTypeImplicit = true;
  2086. }
  2087. if (Tok.is(tok::colon))
  2088. Data.ColonLoc = ConsumeToken();
  2089. } else if (Kind == OMPC_to || Kind == OMPC_from) {
  2090. if (Tok.is(tok::identifier)) {
  2091. bool IsMapperModifier = false;
  2092. if (Kind == OMPC_to) {
  2093. auto Modifier = static_cast<OpenMPToModifierKind>(
  2094. getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
  2095. if (Modifier == OMPC_TO_MODIFIER_mapper)
  2096. IsMapperModifier = true;
  2097. } else {
  2098. auto Modifier = static_cast<OpenMPFromModifierKind>(
  2099. getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
  2100. if (Modifier == OMPC_FROM_MODIFIER_mapper)
  2101. IsMapperModifier = true;
  2102. }
  2103. if (IsMapperModifier) {
  2104. // Parse the mapper modifier.
  2105. ConsumeToken();
  2106. IsInvalidMapperModifier = parseMapperModifier(Data);
  2107. if (Tok.isNot(tok::colon)) {
  2108. if (!IsInvalidMapperModifier)
  2109. Diag(Tok, diag::warn_pragma_expected_colon) << ")";
  2110. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  2111. StopBeforeMatch);
  2112. }
  2113. // Consume ':'.
  2114. if (Tok.is(tok::colon))
  2115. ConsumeToken();
  2116. }
  2117. }
  2118. }
  2119. bool IsComma =
  2120. (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
  2121. Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
  2122. (Kind == OMPC_reduction && !InvalidReductionId) ||
  2123. (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
  2124. (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
  2125. const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
  2126. while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
  2127. Tok.isNot(tok::annot_pragma_openmp_end))) {
  2128. ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
  2129. // Parse variable
  2130. ExprResult VarExpr =
  2131. Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
  2132. if (VarExpr.isUsable()) {
  2133. Vars.push_back(VarExpr.get());
  2134. } else {
  2135. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  2136. StopBeforeMatch);
  2137. }
  2138. // Skip ',' if any
  2139. IsComma = Tok.is(tok::comma);
  2140. if (IsComma)
  2141. ConsumeToken();
  2142. else if (Tok.isNot(tok::r_paren) &&
  2143. Tok.isNot(tok::annot_pragma_openmp_end) &&
  2144. (!MayHaveTail || Tok.isNot(tok::colon)))
  2145. Diag(Tok, diag::err_omp_expected_punc)
  2146. << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
  2147. : getOpenMPClauseName(Kind))
  2148. << (Kind == OMPC_flush);
  2149. }
  2150. // Parse ')' for linear clause with modifier.
  2151. if (NeedRParenForLinear)
  2152. LinearT.consumeClose();
  2153. // Parse ':' linear-step (or ':' alignment).
  2154. const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
  2155. if (MustHaveTail) {
  2156. Data.ColonLoc = Tok.getLocation();
  2157. SourceLocation ELoc = ConsumeToken();
  2158. ExprResult Tail = ParseAssignmentExpression();
  2159. Tail =
  2160. Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
  2161. if (Tail.isUsable())
  2162. Data.TailExpr = Tail.get();
  2163. else
  2164. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  2165. StopBeforeMatch);
  2166. }
  2167. // Parse ')'.
  2168. Data.RLoc = Tok.getLocation();
  2169. if (!T.consumeClose())
  2170. Data.RLoc = T.getCloseLocation();
  2171. return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
  2172. Vars.empty()) ||
  2173. (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
  2174. (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
  2175. IsInvalidMapperModifier;
  2176. }
  2177. /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
  2178. /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
  2179. /// 'in_reduction'.
  2180. ///
  2181. /// private-clause:
  2182. /// 'private' '(' list ')'
  2183. /// firstprivate-clause:
  2184. /// 'firstprivate' '(' list ')'
  2185. /// lastprivate-clause:
  2186. /// 'lastprivate' '(' list ')'
  2187. /// shared-clause:
  2188. /// 'shared' '(' list ')'
  2189. /// linear-clause:
  2190. /// 'linear' '(' linear-list [ ':' linear-step ] ')'
  2191. /// aligned-clause:
  2192. /// 'aligned' '(' list [ ':' alignment ] ')'
  2193. /// reduction-clause:
  2194. /// 'reduction' '(' reduction-identifier ':' list ')'
  2195. /// task_reduction-clause:
  2196. /// 'task_reduction' '(' reduction-identifier ':' list ')'
  2197. /// in_reduction-clause:
  2198. /// 'in_reduction' '(' reduction-identifier ':' list ')'
  2199. /// copyprivate-clause:
  2200. /// 'copyprivate' '(' list ')'
  2201. /// flush-clause:
  2202. /// 'flush' '(' list ')'
  2203. /// depend-clause:
  2204. /// 'depend' '(' in | out | inout : list | source ')'
  2205. /// map-clause:
  2206. /// 'map' '(' [ [ always [,] ] [ close [,] ]
  2207. /// [ mapper '(' mapper-identifier ')' [,] ]
  2208. /// to | from | tofrom | alloc | release | delete ':' ] list ')';
  2209. /// to-clause:
  2210. /// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
  2211. /// from-clause:
  2212. /// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
  2213. /// use_device_ptr-clause:
  2214. /// 'use_device_ptr' '(' list ')'
  2215. /// is_device_ptr-clause:
  2216. /// 'is_device_ptr' '(' list ')'
  2217. ///
  2218. /// For 'linear' clause linear-list may have the following forms:
  2219. /// list
  2220. /// modifier(list)
  2221. /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
  2222. OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
  2223. OpenMPClauseKind Kind,
  2224. bool ParseOnly) {
  2225. SourceLocation Loc = Tok.getLocation();
  2226. SourceLocation LOpen = ConsumeToken();
  2227. SmallVector<Expr *, 4> Vars;
  2228. OpenMPVarListDataTy Data;
  2229. if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
  2230. return nullptr;
  2231. if (ParseOnly)
  2232. return nullptr;
  2233. OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
  2234. return Actions.ActOnOpenMPVarListClause(
  2235. Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
  2236. Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
  2237. Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
  2238. Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
  2239. }