ParseOpenMP.cpp 66 KB

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