ParseOpenMP.cpp 103 KB

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