ParseOpenMP.cpp 101 KB

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