ParseOpenMP.cpp 103 KB

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