ParseOpenMP.cpp 61 KB

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