ParseOpenMP.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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 "RAIIObjectsForParser.h"
  14. #include "clang/AST/ASTConsumer.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/StmtOpenMP.h"
  17. #include "clang/Parse/ParseDiagnostic.h"
  18. #include "clang/Parse/Parser.h"
  19. #include "clang/Sema/Scope.h"
  20. #include "llvm/ADT/PointerIntPair.h"
  21. using namespace clang;
  22. //===----------------------------------------------------------------------===//
  23. // OpenMP declarative directives.
  24. //===----------------------------------------------------------------------===//
  25. static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
  26. // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
  27. // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
  28. // TODO: add other combined directives in topological order.
  29. const OpenMPDirectiveKind F[][3] = {
  30. {OMPD_unknown /*cancellation*/, OMPD_unknown /*point*/,
  31. OMPD_cancellation_point},
  32. {OMPD_for, OMPD_simd, OMPD_for_simd},
  33. {OMPD_parallel, OMPD_for, OMPD_parallel_for},
  34. {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
  35. {OMPD_parallel, OMPD_sections, OMPD_parallel_sections}};
  36. auto Tok = P.getCurToken();
  37. auto DKind =
  38. Tok.isAnnotation()
  39. ? OMPD_unknown
  40. : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
  41. bool TokenMatched = false;
  42. for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
  43. if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
  44. TokenMatched =
  45. (i == 0) &&
  46. !P.getPreprocessor().getSpelling(Tok).compare("cancellation");
  47. } else {
  48. TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;
  49. }
  50. if (TokenMatched) {
  51. Tok = P.getPreprocessor().LookAhead(0);
  52. auto SDKind =
  53. Tok.isAnnotation()
  54. ? OMPD_unknown
  55. : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
  56. if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
  57. TokenMatched =
  58. (i == 0) && !P.getPreprocessor().getSpelling(Tok).compare("point");
  59. } else {
  60. TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;
  61. }
  62. if (TokenMatched) {
  63. P.ConsumeToken();
  64. DKind = F[i][2];
  65. }
  66. }
  67. }
  68. return DKind;
  69. }
  70. /// \brief Parsing of declarative OpenMP directives.
  71. ///
  72. /// threadprivate-directive:
  73. /// annot_pragma_openmp 'threadprivate' simple-variable-list
  74. ///
  75. Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
  76. assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  77. ParenBraceBracketBalancer BalancerRAIIObj(*this);
  78. SourceLocation Loc = ConsumeToken();
  79. SmallVector<Expr *, 5> Identifiers;
  80. auto DKind = ParseOpenMPDirectiveKind(*this);
  81. switch (DKind) {
  82. case OMPD_threadprivate:
  83. ConsumeToken();
  84. if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
  85. // The last seen token is annot_pragma_openmp_end - need to check for
  86. // extra tokens.
  87. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  88. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  89. << getOpenMPDirectiveName(OMPD_threadprivate);
  90. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  91. }
  92. // Skip the last annot_pragma_openmp_end.
  93. ConsumeToken();
  94. return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
  95. }
  96. break;
  97. case OMPD_unknown:
  98. Diag(Tok, diag::err_omp_unknown_directive);
  99. break;
  100. case OMPD_parallel:
  101. case OMPD_simd:
  102. case OMPD_task:
  103. case OMPD_taskyield:
  104. case OMPD_barrier:
  105. case OMPD_taskwait:
  106. case OMPD_taskgroup:
  107. case OMPD_flush:
  108. case OMPD_for:
  109. case OMPD_for_simd:
  110. case OMPD_sections:
  111. case OMPD_section:
  112. case OMPD_single:
  113. case OMPD_master:
  114. case OMPD_ordered:
  115. case OMPD_critical:
  116. case OMPD_parallel_for:
  117. case OMPD_parallel_for_simd:
  118. case OMPD_parallel_sections:
  119. case OMPD_atomic:
  120. case OMPD_target:
  121. case OMPD_teams:
  122. case OMPD_cancellation_point:
  123. case OMPD_cancel:
  124. Diag(Tok, diag::err_omp_unexpected_directive)
  125. << getOpenMPDirectiveName(DKind);
  126. break;
  127. }
  128. SkipUntil(tok::annot_pragma_openmp_end);
  129. return DeclGroupPtrTy();
  130. }
  131. /// \brief Parsing of declarative or executable OpenMP directives.
  132. ///
  133. /// threadprivate-directive:
  134. /// annot_pragma_openmp 'threadprivate' simple-variable-list
  135. /// annot_pragma_openmp_end
  136. ///
  137. /// executable-directive:
  138. /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
  139. /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
  140. /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
  141. /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
  142. /// 'for simd' | 'parallel for simd' | 'target' | 'teams' | 'taskgroup'
  143. /// {clause}
  144. /// annot_pragma_openmp_end
  145. ///
  146. StmtResult
  147. Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
  148. assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  149. ParenBraceBracketBalancer BalancerRAIIObj(*this);
  150. SmallVector<Expr *, 5> Identifiers;
  151. SmallVector<OMPClause *, 5> Clauses;
  152. SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
  153. FirstClauses(OMPC_unknown + 1);
  154. unsigned ScopeFlags =
  155. Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
  156. SourceLocation Loc = ConsumeToken(), EndLoc;
  157. auto DKind = ParseOpenMPDirectiveKind(*this);
  158. OpenMPDirectiveKind CancelRegion = OMPD_unknown;
  159. // Name of critical directive.
  160. DeclarationNameInfo DirName;
  161. StmtResult Directive = StmtError();
  162. bool HasAssociatedStatement = true;
  163. bool FlushHasClause = false;
  164. switch (DKind) {
  165. case OMPD_threadprivate:
  166. ConsumeToken();
  167. if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
  168. // The last seen token is annot_pragma_openmp_end - need to check for
  169. // extra tokens.
  170. if (Tok.isNot(tok::annot_pragma_openmp_end)) {
  171. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  172. << getOpenMPDirectiveName(OMPD_threadprivate);
  173. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  174. }
  175. DeclGroupPtrTy Res =
  176. Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
  177. Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
  178. }
  179. SkipUntil(tok::annot_pragma_openmp_end);
  180. break;
  181. case OMPD_flush:
  182. if (PP.LookAhead(0).is(tok::l_paren)) {
  183. FlushHasClause = true;
  184. // Push copy of the current token back to stream to properly parse
  185. // pseudo-clause OMPFlushClause.
  186. PP.EnterToken(Tok);
  187. }
  188. case OMPD_taskyield:
  189. case OMPD_barrier:
  190. case OMPD_taskwait:
  191. case OMPD_cancellation_point:
  192. case OMPD_cancel:
  193. if (!StandAloneAllowed) {
  194. Diag(Tok, diag::err_omp_immediate_directive)
  195. << getOpenMPDirectiveName(DKind);
  196. }
  197. HasAssociatedStatement = false;
  198. // Fall through for further analysis.
  199. case OMPD_parallel:
  200. case OMPD_simd:
  201. case OMPD_for:
  202. case OMPD_for_simd:
  203. case OMPD_sections:
  204. case OMPD_single:
  205. case OMPD_section:
  206. case OMPD_master:
  207. case OMPD_critical:
  208. case OMPD_parallel_for:
  209. case OMPD_parallel_for_simd:
  210. case OMPD_parallel_sections:
  211. case OMPD_task:
  212. case OMPD_ordered:
  213. case OMPD_atomic:
  214. case OMPD_target:
  215. case OMPD_teams:
  216. case OMPD_taskgroup: {
  217. ConsumeToken();
  218. // Parse directive name of the 'critical' directive if any.
  219. if (DKind == OMPD_critical) {
  220. BalancedDelimiterTracker T(*this, tok::l_paren,
  221. tok::annot_pragma_openmp_end);
  222. if (!T.consumeOpen()) {
  223. if (Tok.isAnyIdentifier()) {
  224. DirName =
  225. DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
  226. ConsumeAnyToken();
  227. } else {
  228. Diag(Tok, diag::err_omp_expected_identifier_for_critical);
  229. }
  230. T.consumeClose();
  231. }
  232. } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
  233. CancelRegion = ParseOpenMPDirectiveKind(*this);
  234. if (Tok.isNot(tok::annot_pragma_openmp_end))
  235. ConsumeToken();
  236. }
  237. if (isOpenMPLoopDirective(DKind))
  238. ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
  239. if (isOpenMPSimdDirective(DKind))
  240. ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
  241. ParseScope OMPDirectiveScope(this, ScopeFlags);
  242. Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
  243. while (Tok.isNot(tok::annot_pragma_openmp_end)) {
  244. OpenMPClauseKind CKind =
  245. Tok.isAnnotation()
  246. ? OMPC_unknown
  247. : FlushHasClause ? OMPC_flush
  248. : getOpenMPClauseKind(PP.getSpelling(Tok));
  249. Actions.StartOpenMPClause(CKind);
  250. FlushHasClause = false;
  251. OMPClause *Clause =
  252. ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
  253. FirstClauses[CKind].setInt(true);
  254. if (Clause) {
  255. FirstClauses[CKind].setPointer(Clause);
  256. Clauses.push_back(Clause);
  257. }
  258. // Skip ',' if any.
  259. if (Tok.is(tok::comma))
  260. ConsumeToken();
  261. Actions.EndOpenMPClause();
  262. }
  263. // End location of the directive.
  264. EndLoc = Tok.getLocation();
  265. // Consume final annot_pragma_openmp_end.
  266. ConsumeToken();
  267. StmtResult AssociatedStmt;
  268. bool CreateDirective = true;
  269. if (HasAssociatedStatement) {
  270. // The body is a block scope like in Lambdas and Blocks.
  271. Sema::CompoundScopeRAII CompoundScope(Actions);
  272. Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
  273. Actions.ActOnStartOfCompoundStmt();
  274. // Parse statement
  275. AssociatedStmt = ParseStatement();
  276. Actions.ActOnFinishOfCompoundStmt();
  277. AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
  278. CreateDirective = AssociatedStmt.isUsable();
  279. }
  280. if (CreateDirective)
  281. Directive = Actions.ActOnOpenMPExecutableDirective(
  282. DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
  283. EndLoc);
  284. // Exit scope.
  285. Actions.EndOpenMPDSABlock(Directive.get());
  286. OMPDirectiveScope.Exit();
  287. break;
  288. }
  289. case OMPD_unknown:
  290. Diag(Tok, diag::err_omp_unknown_directive);
  291. SkipUntil(tok::annot_pragma_openmp_end);
  292. break;
  293. }
  294. return Directive;
  295. }
  296. /// \brief Parses list of simple variables for '#pragma omp threadprivate'
  297. /// directive.
  298. ///
  299. /// simple-variable-list:
  300. /// '(' id-expression {, id-expression} ')'
  301. ///
  302. bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
  303. SmallVectorImpl<Expr *> &VarList,
  304. bool AllowScopeSpecifier) {
  305. VarList.clear();
  306. // Parse '('.
  307. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  308. if (T.expectAndConsume(diag::err_expected_lparen_after,
  309. getOpenMPDirectiveName(Kind)))
  310. return true;
  311. bool IsCorrect = true;
  312. bool NoIdentIsFound = true;
  313. // Read tokens while ')' or annot_pragma_openmp_end is not found.
  314. while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
  315. CXXScopeSpec SS;
  316. SourceLocation TemplateKWLoc;
  317. UnqualifiedId Name;
  318. // Read var name.
  319. Token PrevTok = Tok;
  320. NoIdentIsFound = false;
  321. if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
  322. ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
  323. IsCorrect = false;
  324. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  325. StopBeforeMatch);
  326. } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
  327. TemplateKWLoc, Name)) {
  328. IsCorrect = false;
  329. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  330. StopBeforeMatch);
  331. } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
  332. Tok.isNot(tok::annot_pragma_openmp_end)) {
  333. IsCorrect = false;
  334. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  335. StopBeforeMatch);
  336. Diag(PrevTok.getLocation(), diag::err_expected)
  337. << tok::identifier
  338. << SourceRange(PrevTok.getLocation(), PrevTokLocation);
  339. } else {
  340. DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
  341. ExprResult Res =
  342. Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
  343. if (Res.isUsable())
  344. VarList.push_back(Res.get());
  345. }
  346. // Consume ','.
  347. if (Tok.is(tok::comma)) {
  348. ConsumeToken();
  349. }
  350. }
  351. if (NoIdentIsFound) {
  352. Diag(Tok, diag::err_expected) << tok::identifier;
  353. IsCorrect = false;
  354. }
  355. // Parse ')'.
  356. IsCorrect = !T.consumeClose() && IsCorrect;
  357. return !IsCorrect && VarList.empty();
  358. }
  359. /// \brief Parsing of OpenMP clauses.
  360. ///
  361. /// clause:
  362. /// if-clause | final-clause | num_threads-clause | safelen-clause |
  363. /// default-clause | private-clause | firstprivate-clause | shared-clause
  364. /// | linear-clause | aligned-clause | collapse-clause |
  365. /// lastprivate-clause | reduction-clause | proc_bind-clause |
  366. /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
  367. /// mergeable-clause | flush-clause | read-clause | write-clause |
  368. /// update-clause | capture-clause | seq_cst-clause
  369. ///
  370. OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
  371. OpenMPClauseKind CKind, bool FirstClause) {
  372. OMPClause *Clause = nullptr;
  373. bool ErrorFound = false;
  374. // Check if clause is allowed for the given directive.
  375. if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
  376. Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
  377. << getOpenMPDirectiveName(DKind);
  378. ErrorFound = true;
  379. }
  380. switch (CKind) {
  381. case OMPC_if:
  382. case OMPC_final:
  383. case OMPC_num_threads:
  384. case OMPC_safelen:
  385. case OMPC_collapse:
  386. // OpenMP [2.5, Restrictions]
  387. // At most one if clause can appear on the directive.
  388. // At most one num_threads clause can appear on the directive.
  389. // OpenMP [2.8.1, simd construct, Restrictions]
  390. // Only one safelen clause can appear on a simd directive.
  391. // Only one collapse clause can appear on a simd directive.
  392. // OpenMP [2.11.1, task Construct, Restrictions]
  393. // At most one if clause can appear on the directive.
  394. // At most one final clause can appear on the directive.
  395. if (!FirstClause) {
  396. Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
  397. << getOpenMPClauseName(CKind);
  398. ErrorFound = true;
  399. }
  400. Clause = ParseOpenMPSingleExprClause(CKind);
  401. break;
  402. case OMPC_default:
  403. case OMPC_proc_bind:
  404. // OpenMP [2.14.3.1, Restrictions]
  405. // Only a single default clause may be specified on a parallel, task or
  406. // teams directive.
  407. // OpenMP [2.5, parallel Construct, Restrictions]
  408. // At most one proc_bind clause can appear on the directive.
  409. if (!FirstClause) {
  410. Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
  411. << getOpenMPClauseName(CKind);
  412. ErrorFound = true;
  413. }
  414. Clause = ParseOpenMPSimpleClause(CKind);
  415. break;
  416. case OMPC_schedule:
  417. // OpenMP [2.7.1, Restrictions, p. 3]
  418. // Only one schedule clause can appear on a loop directive.
  419. if (!FirstClause) {
  420. Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
  421. << getOpenMPClauseName(CKind);
  422. ErrorFound = true;
  423. }
  424. Clause = ParseOpenMPSingleExprWithArgClause(CKind);
  425. break;
  426. case OMPC_ordered:
  427. case OMPC_nowait:
  428. case OMPC_untied:
  429. case OMPC_mergeable:
  430. case OMPC_read:
  431. case OMPC_write:
  432. case OMPC_update:
  433. case OMPC_capture:
  434. case OMPC_seq_cst:
  435. // OpenMP [2.7.1, Restrictions, p. 9]
  436. // Only one ordered clause can appear on a loop directive.
  437. // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
  438. // Only one nowait clause can appear on a for directive.
  439. if (!FirstClause) {
  440. Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
  441. << getOpenMPClauseName(CKind);
  442. ErrorFound = true;
  443. }
  444. Clause = ParseOpenMPClause(CKind);
  445. break;
  446. case OMPC_private:
  447. case OMPC_firstprivate:
  448. case OMPC_lastprivate:
  449. case OMPC_shared:
  450. case OMPC_reduction:
  451. case OMPC_linear:
  452. case OMPC_aligned:
  453. case OMPC_copyin:
  454. case OMPC_copyprivate:
  455. case OMPC_flush:
  456. case OMPC_depend:
  457. Clause = ParseOpenMPVarListClause(CKind);
  458. break;
  459. case OMPC_unknown:
  460. Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
  461. << getOpenMPDirectiveName(DKind);
  462. SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
  463. break;
  464. case OMPC_threadprivate:
  465. Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
  466. << getOpenMPDirectiveName(DKind);
  467. SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
  468. break;
  469. }
  470. return ErrorFound ? nullptr : Clause;
  471. }
  472. /// \brief Parsing of OpenMP clauses with single expressions like 'if',
  473. /// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams' or
  474. /// 'thread_limit'.
  475. ///
  476. /// if-clause:
  477. /// 'if' '(' expression ')'
  478. ///
  479. /// final-clause:
  480. /// 'final' '(' expression ')'
  481. ///
  482. /// num_threads-clause:
  483. /// 'num_threads' '(' expression ')'
  484. ///
  485. /// safelen-clause:
  486. /// 'safelen' '(' expression ')'
  487. ///
  488. /// collapse-clause:
  489. /// 'collapse' '(' expression ')'
  490. ///
  491. OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
  492. SourceLocation Loc = ConsumeToken();
  493. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  494. if (T.expectAndConsume(diag::err_expected_lparen_after,
  495. getOpenMPClauseName(Kind)))
  496. return nullptr;
  497. ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
  498. ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
  499. // Parse ')'.
  500. T.consumeClose();
  501. if (Val.isInvalid())
  502. return nullptr;
  503. return Actions.ActOnOpenMPSingleExprClause(
  504. Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
  505. }
  506. /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
  507. ///
  508. /// default-clause:
  509. /// 'default' '(' 'none' | 'shared' ')
  510. ///
  511. /// proc_bind-clause:
  512. /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
  513. ///
  514. OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
  515. SourceLocation Loc = Tok.getLocation();
  516. SourceLocation LOpen = ConsumeToken();
  517. // Parse '('.
  518. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  519. if (T.expectAndConsume(diag::err_expected_lparen_after,
  520. getOpenMPClauseName(Kind)))
  521. return nullptr;
  522. unsigned Type = getOpenMPSimpleClauseType(
  523. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  524. SourceLocation TypeLoc = Tok.getLocation();
  525. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  526. Tok.isNot(tok::annot_pragma_openmp_end))
  527. ConsumeAnyToken();
  528. // Parse ')'.
  529. T.consumeClose();
  530. return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
  531. Tok.getLocation());
  532. }
  533. /// \brief Parsing of OpenMP clauses like 'ordered'.
  534. ///
  535. /// ordered-clause:
  536. /// 'ordered'
  537. ///
  538. /// nowait-clause:
  539. /// 'nowait'
  540. ///
  541. /// untied-clause:
  542. /// 'untied'
  543. ///
  544. /// mergeable-clause:
  545. /// 'mergeable'
  546. ///
  547. /// read-clause:
  548. /// 'read'
  549. ///
  550. OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
  551. SourceLocation Loc = Tok.getLocation();
  552. ConsumeAnyToken();
  553. return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
  554. }
  555. /// \brief Parsing of OpenMP clauses with single expressions and some additional
  556. /// argument like 'schedule' or 'dist_schedule'.
  557. ///
  558. /// schedule-clause:
  559. /// 'schedule' '(' kind [',' expression ] ')'
  560. ///
  561. OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
  562. SourceLocation Loc = ConsumeToken();
  563. SourceLocation CommaLoc;
  564. // Parse '('.
  565. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  566. if (T.expectAndConsume(diag::err_expected_lparen_after,
  567. getOpenMPClauseName(Kind)))
  568. return nullptr;
  569. ExprResult Val;
  570. unsigned Type = getOpenMPSimpleClauseType(
  571. Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
  572. SourceLocation KLoc = Tok.getLocation();
  573. if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
  574. Tok.isNot(tok::annot_pragma_openmp_end))
  575. ConsumeAnyToken();
  576. if (Kind == OMPC_schedule &&
  577. (Type == OMPC_SCHEDULE_static || Type == OMPC_SCHEDULE_dynamic ||
  578. Type == OMPC_SCHEDULE_guided) &&
  579. Tok.is(tok::comma)) {
  580. CommaLoc = ConsumeAnyToken();
  581. ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
  582. Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
  583. if (Val.isInvalid())
  584. return nullptr;
  585. }
  586. // Parse ')'.
  587. T.consumeClose();
  588. return Actions.ActOnOpenMPSingleExprWithArgClause(
  589. Kind, Type, Val.get(), Loc, T.getOpenLocation(), KLoc, CommaLoc,
  590. T.getCloseLocation());
  591. }
  592. static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
  593. UnqualifiedId &ReductionId) {
  594. SourceLocation TemplateKWLoc;
  595. if (ReductionIdScopeSpec.isEmpty()) {
  596. auto OOK = OO_None;
  597. switch (P.getCurToken().getKind()) {
  598. case tok::plus:
  599. OOK = OO_Plus;
  600. break;
  601. case tok::minus:
  602. OOK = OO_Minus;
  603. break;
  604. case tok::star:
  605. OOK = OO_Star;
  606. break;
  607. case tok::amp:
  608. OOK = OO_Amp;
  609. break;
  610. case tok::pipe:
  611. OOK = OO_Pipe;
  612. break;
  613. case tok::caret:
  614. OOK = OO_Caret;
  615. break;
  616. case tok::ampamp:
  617. OOK = OO_AmpAmp;
  618. break;
  619. case tok::pipepipe:
  620. OOK = OO_PipePipe;
  621. break;
  622. default:
  623. break;
  624. }
  625. if (OOK != OO_None) {
  626. SourceLocation OpLoc = P.ConsumeToken();
  627. SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
  628. ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
  629. return false;
  630. }
  631. }
  632. return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
  633. /*AllowDestructorName*/ false,
  634. /*AllowConstructorName*/ false, ParsedType(),
  635. TemplateKWLoc, ReductionId);
  636. }
  637. /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
  638. /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
  639. ///
  640. /// private-clause:
  641. /// 'private' '(' list ')'
  642. /// firstprivate-clause:
  643. /// 'firstprivate' '(' list ')'
  644. /// lastprivate-clause:
  645. /// 'lastprivate' '(' list ')'
  646. /// shared-clause:
  647. /// 'shared' '(' list ')'
  648. /// linear-clause:
  649. /// 'linear' '(' list [ ':' linear-step ] ')'
  650. /// aligned-clause:
  651. /// 'aligned' '(' list [ ':' alignment ] ')'
  652. /// reduction-clause:
  653. /// 'reduction' '(' reduction-identifier ':' list ')'
  654. /// copyprivate-clause:
  655. /// 'copyprivate' '(' list ')'
  656. /// flush-clause:
  657. /// 'flush' '(' list ')'
  658. /// depend-clause:
  659. /// 'depend' '(' in | out | inout : list ')'
  660. ///
  661. OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
  662. SourceLocation Loc = Tok.getLocation();
  663. SourceLocation LOpen = ConsumeToken();
  664. SourceLocation ColonLoc = SourceLocation();
  665. // Optional scope specifier and unqualified id for reduction identifier.
  666. CXXScopeSpec ReductionIdScopeSpec;
  667. UnqualifiedId ReductionId;
  668. bool InvalidReductionId = false;
  669. OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
  670. SourceLocation DepLoc;
  671. // Parse '('.
  672. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
  673. if (T.expectAndConsume(diag::err_expected_lparen_after,
  674. getOpenMPClauseName(Kind)))
  675. return nullptr;
  676. // Handle reduction-identifier for reduction clause.
  677. if (Kind == OMPC_reduction) {
  678. ColonProtectionRAIIObject ColonRAII(*this);
  679. if (getLangOpts().CPlusPlus) {
  680. ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
  681. }
  682. InvalidReductionId =
  683. ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
  684. if (InvalidReductionId) {
  685. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  686. StopBeforeMatch);
  687. }
  688. if (Tok.is(tok::colon)) {
  689. ColonLoc = ConsumeToken();
  690. } else {
  691. Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
  692. }
  693. } else if (Kind == OMPC_depend) {
  694. // Handle dependency type for depend clause.
  695. ColonProtectionRAIIObject ColonRAII(*this);
  696. DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
  697. Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
  698. DepLoc = Tok.getLocation();
  699. if (DepKind == OMPC_DEPEND_unknown) {
  700. SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
  701. StopBeforeMatch);
  702. } else {
  703. ConsumeToken();
  704. }
  705. if (Tok.is(tok::colon)) {
  706. ColonLoc = ConsumeToken();
  707. } else {
  708. Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type";
  709. }
  710. }
  711. SmallVector<Expr *, 5> Vars;
  712. bool IsComma = ((Kind != OMPC_reduction) && (Kind != OMPC_depend)) ||
  713. ((Kind == OMPC_reduction) && !InvalidReductionId) ||
  714. ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
  715. const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
  716. while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
  717. Tok.isNot(tok::annot_pragma_openmp_end))) {
  718. ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
  719. // Parse variable
  720. ExprResult VarExpr =
  721. Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
  722. if (VarExpr.isUsable()) {
  723. Vars.push_back(VarExpr.get());
  724. } else {
  725. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  726. StopBeforeMatch);
  727. }
  728. // Skip ',' if any
  729. IsComma = Tok.is(tok::comma);
  730. if (IsComma)
  731. ConsumeToken();
  732. else if (Tok.isNot(tok::r_paren) &&
  733. Tok.isNot(tok::annot_pragma_openmp_end) &&
  734. (!MayHaveTail || Tok.isNot(tok::colon)))
  735. Diag(Tok, diag::err_omp_expected_punc)
  736. << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
  737. : getOpenMPClauseName(Kind))
  738. << (Kind == OMPC_flush);
  739. }
  740. // Parse ':' linear-step (or ':' alignment).
  741. Expr *TailExpr = nullptr;
  742. const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
  743. if (MustHaveTail) {
  744. ColonLoc = Tok.getLocation();
  745. ConsumeToken();
  746. ExprResult Tail =
  747. Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
  748. if (Tail.isUsable())
  749. TailExpr = Tail.get();
  750. else
  751. SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
  752. StopBeforeMatch);
  753. }
  754. // Parse ')'.
  755. T.consumeClose();
  756. if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
  757. (Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
  758. InvalidReductionId)
  759. return nullptr;
  760. return Actions.ActOnOpenMPVarListClause(
  761. Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
  762. ReductionIdScopeSpec,
  763. ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
  764. : DeclarationNameInfo(),
  765. DepKind, DepLoc);
  766. }