ParseOpenMP.cpp 103 KB

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