1 //===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the language specific #pragma handlers.
12 //===----------------------------------------------------------------------===//
14 #include "RAIIObjectsForParser.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "clang/Parse/ParseDiagnostic.h"
19 #include "clang/Parse/Parser.h"
20 #include "clang/Sema/LoopHint.h"
21 #include "clang/Sema/Scope.h"
22 #include "llvm/ADT/StringSwitch.h"
23 using namespace clang;
27 struct PragmaAlignHandler : public PragmaHandler {
28 explicit PragmaAlignHandler() : PragmaHandler("align") {}
29 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
30 Token &FirstToken) override;
33 struct PragmaGCCVisibilityHandler : public PragmaHandler {
34 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
35 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
36 Token &FirstToken) override;
39 struct PragmaOptionsHandler : public PragmaHandler {
40 explicit PragmaOptionsHandler() : PragmaHandler("options") {}
41 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
42 Token &FirstToken) override;
45 struct PragmaPackHandler : public PragmaHandler {
46 explicit PragmaPackHandler() : PragmaHandler("pack") {}
47 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
48 Token &FirstToken) override;
51 struct PragmaMSStructHandler : public PragmaHandler {
52 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
53 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
54 Token &FirstToken) override;
57 struct PragmaUnusedHandler : public PragmaHandler {
58 PragmaUnusedHandler() : PragmaHandler("unused") {}
59 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
60 Token &FirstToken) override;
63 struct PragmaWeakHandler : public PragmaHandler {
64 explicit PragmaWeakHandler() : PragmaHandler("weak") {}
65 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
66 Token &FirstToken) override;
69 struct PragmaRedefineExtnameHandler : public PragmaHandler {
70 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
71 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
72 Token &FirstToken) override;
75 struct PragmaOpenCLExtensionHandler : public PragmaHandler {
76 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
77 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
78 Token &FirstToken) override;
82 struct PragmaFPContractHandler : public PragmaHandler {
83 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
84 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
85 Token &FirstToken) override;
88 struct PragmaNoOpenMPHandler : public PragmaHandler {
89 PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
90 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
91 Token &FirstToken) override;
94 struct PragmaOpenMPHandler : public PragmaHandler {
95 PragmaOpenMPHandler() : PragmaHandler("omp") { }
96 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
97 Token &FirstToken) override;
100 /// PragmaCommentHandler - "\#pragma comment ...".
101 struct PragmaCommentHandler : public PragmaHandler {
102 PragmaCommentHandler(Sema &Actions)
103 : PragmaHandler("comment"), Actions(Actions) {}
104 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
105 Token &FirstToken) override;
110 struct PragmaDetectMismatchHandler : public PragmaHandler {
111 PragmaDetectMismatchHandler(Sema &Actions)
112 : PragmaHandler("detect_mismatch"), Actions(Actions) {}
113 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
114 Token &FirstToken) override;
119 struct PragmaMSPointersToMembers : public PragmaHandler {
120 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
121 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
122 Token &FirstToken) override;
125 struct PragmaMSVtorDisp : public PragmaHandler {
126 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
127 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
128 Token &FirstToken) override;
131 struct PragmaMSPragma : public PragmaHandler {
132 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
133 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
134 Token &FirstToken) override;
137 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
138 struct PragmaOptimizeHandler : public PragmaHandler {
139 PragmaOptimizeHandler(Sema &S)
140 : PragmaHandler("optimize"), Actions(S) {}
141 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
142 Token &FirstToken) override;
147 struct PragmaLoopHintHandler : public PragmaHandler {
148 PragmaLoopHintHandler() : PragmaHandler("loop") {}
149 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
150 Token &FirstToken) override;
153 struct PragmaUnrollHintHandler : public PragmaHandler {
154 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
155 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
156 Token &FirstToken) override;
159 struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
160 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
165 void Parser::initializePragmaHandlers() {
166 AlignHandler.reset(new PragmaAlignHandler());
167 PP.AddPragmaHandler(AlignHandler.get());
169 GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
170 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
172 OptionsHandler.reset(new PragmaOptionsHandler());
173 PP.AddPragmaHandler(OptionsHandler.get());
175 PackHandler.reset(new PragmaPackHandler());
176 PP.AddPragmaHandler(PackHandler.get());
178 MSStructHandler.reset(new PragmaMSStructHandler());
179 PP.AddPragmaHandler(MSStructHandler.get());
181 UnusedHandler.reset(new PragmaUnusedHandler());
182 PP.AddPragmaHandler(UnusedHandler.get());
184 WeakHandler.reset(new PragmaWeakHandler());
185 PP.AddPragmaHandler(WeakHandler.get());
187 RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
188 PP.AddPragmaHandler(RedefineExtnameHandler.get());
190 FPContractHandler.reset(new PragmaFPContractHandler());
191 PP.AddPragmaHandler("STDC", FPContractHandler.get());
193 if (getLangOpts().OpenCL) {
194 OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
195 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
197 PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
199 if (getLangOpts().OpenMP)
200 OpenMPHandler.reset(new PragmaOpenMPHandler());
202 OpenMPHandler.reset(new PragmaNoOpenMPHandler());
203 PP.AddPragmaHandler(OpenMPHandler.get());
205 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
206 MSCommentHandler.reset(new PragmaCommentHandler(Actions));
207 PP.AddPragmaHandler(MSCommentHandler.get());
210 if (getLangOpts().MicrosoftExt) {
211 MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
212 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
213 MSPointersToMembers.reset(new PragmaMSPointersToMembers());
214 PP.AddPragmaHandler(MSPointersToMembers.get());
215 MSVtorDisp.reset(new PragmaMSVtorDisp());
216 PP.AddPragmaHandler(MSVtorDisp.get());
217 MSInitSeg.reset(new PragmaMSPragma("init_seg"));
218 PP.AddPragmaHandler(MSInitSeg.get());
219 MSDataSeg.reset(new PragmaMSPragma("data_seg"));
220 PP.AddPragmaHandler(MSDataSeg.get());
221 MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
222 PP.AddPragmaHandler(MSBSSSeg.get());
223 MSConstSeg.reset(new PragmaMSPragma("const_seg"));
224 PP.AddPragmaHandler(MSConstSeg.get());
225 MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
226 PP.AddPragmaHandler(MSCodeSeg.get());
227 MSSection.reset(new PragmaMSPragma("section"));
228 PP.AddPragmaHandler(MSSection.get());
229 MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler());
230 PP.AddPragmaHandler(MSRuntimeChecks.get());
233 OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
234 PP.AddPragmaHandler("clang", OptimizeHandler.get());
236 LoopHintHandler.reset(new PragmaLoopHintHandler());
237 PP.AddPragmaHandler("clang", LoopHintHandler.get());
239 UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
240 PP.AddPragmaHandler(UnrollHintHandler.get());
242 NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
243 PP.AddPragmaHandler(NoUnrollHintHandler.get());
246 void Parser::resetPragmaHandlers() {
247 // Remove the pragma handlers we installed.
248 PP.RemovePragmaHandler(AlignHandler.get());
249 AlignHandler.reset();
250 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
251 GCCVisibilityHandler.reset();
252 PP.RemovePragmaHandler(OptionsHandler.get());
253 OptionsHandler.reset();
254 PP.RemovePragmaHandler(PackHandler.get());
256 PP.RemovePragmaHandler(MSStructHandler.get());
257 MSStructHandler.reset();
258 PP.RemovePragmaHandler(UnusedHandler.get());
259 UnusedHandler.reset();
260 PP.RemovePragmaHandler(WeakHandler.get());
262 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
263 RedefineExtnameHandler.reset();
265 if (getLangOpts().OpenCL) {
266 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
267 OpenCLExtensionHandler.reset();
268 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
270 PP.RemovePragmaHandler(OpenMPHandler.get());
271 OpenMPHandler.reset();
273 if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
274 PP.RemovePragmaHandler(MSCommentHandler.get());
275 MSCommentHandler.reset();
278 if (getLangOpts().MicrosoftExt) {
279 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
280 MSDetectMismatchHandler.reset();
281 PP.RemovePragmaHandler(MSPointersToMembers.get());
282 MSPointersToMembers.reset();
283 PP.RemovePragmaHandler(MSVtorDisp.get());
285 PP.RemovePragmaHandler(MSInitSeg.get());
287 PP.RemovePragmaHandler(MSDataSeg.get());
289 PP.RemovePragmaHandler(MSBSSSeg.get());
291 PP.RemovePragmaHandler(MSConstSeg.get());
293 PP.RemovePragmaHandler(MSCodeSeg.get());
295 PP.RemovePragmaHandler(MSSection.get());
297 PP.RemovePragmaHandler(MSRuntimeChecks.get());
298 MSRuntimeChecks.reset();
301 PP.RemovePragmaHandler("STDC", FPContractHandler.get());
302 FPContractHandler.reset();
304 PP.RemovePragmaHandler("clang", OptimizeHandler.get());
305 OptimizeHandler.reset();
307 PP.RemovePragmaHandler("clang", LoopHintHandler.get());
308 LoopHintHandler.reset();
310 PP.RemovePragmaHandler(UnrollHintHandler.get());
311 UnrollHintHandler.reset();
313 PP.RemovePragmaHandler(NoUnrollHintHandler.get());
314 NoUnrollHintHandler.reset();
317 /// \brief Handle the annotation token produced for #pragma unused(...)
319 /// Each annot_pragma_unused is followed by the argument token so e.g.
320 /// "#pragma unused(x,y)" becomes:
321 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
322 void Parser::HandlePragmaUnused() {
323 assert(Tok.is(tok::annot_pragma_unused));
324 SourceLocation UnusedLoc = ConsumeToken();
325 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
326 ConsumeToken(); // The argument token.
329 void Parser::HandlePragmaVisibility() {
330 assert(Tok.is(tok::annot_pragma_vis));
331 const IdentifierInfo *VisType =
332 static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
333 SourceLocation VisLoc = ConsumeToken();
334 Actions.ActOnPragmaVisibility(VisType, VisLoc);
338 struct PragmaPackInfo {
339 Sema::PragmaPackKind Kind;
340 IdentifierInfo *Name;
342 SourceLocation LParenLoc;
343 SourceLocation RParenLoc;
345 } // end anonymous namespace
347 void Parser::HandlePragmaPack() {
348 assert(Tok.is(tok::annot_pragma_pack));
349 PragmaPackInfo *Info =
350 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
351 SourceLocation PragmaLoc = ConsumeToken();
352 ExprResult Alignment;
353 if (Info->Alignment.is(tok::numeric_constant)) {
354 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
355 if (Alignment.isInvalid())
358 Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
359 Info->LParenLoc, Info->RParenLoc);
362 void Parser::HandlePragmaMSStruct() {
363 assert(Tok.is(tok::annot_pragma_msstruct));
364 Sema::PragmaMSStructKind Kind =
365 static_cast<Sema::PragmaMSStructKind>(
366 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
367 Actions.ActOnPragmaMSStruct(Kind);
368 ConsumeToken(); // The annotation token.
371 void Parser::HandlePragmaAlign() {
372 assert(Tok.is(tok::annot_pragma_align));
373 Sema::PragmaOptionsAlignKind Kind =
374 static_cast<Sema::PragmaOptionsAlignKind>(
375 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
376 SourceLocation PragmaLoc = ConsumeToken();
377 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
380 void Parser::HandlePragmaWeak() {
381 assert(Tok.is(tok::annot_pragma_weak));
382 SourceLocation PragmaLoc = ConsumeToken();
383 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
385 ConsumeToken(); // The weak name.
388 void Parser::HandlePragmaWeakAlias() {
389 assert(Tok.is(tok::annot_pragma_weakalias));
390 SourceLocation PragmaLoc = ConsumeToken();
391 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
392 SourceLocation WeakNameLoc = Tok.getLocation();
394 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
395 SourceLocation AliasNameLoc = Tok.getLocation();
397 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
398 WeakNameLoc, AliasNameLoc);
402 void Parser::HandlePragmaRedefineExtname() {
403 assert(Tok.is(tok::annot_pragma_redefine_extname));
404 SourceLocation RedefLoc = ConsumeToken();
405 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
406 SourceLocation RedefNameLoc = Tok.getLocation();
408 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
409 SourceLocation AliasNameLoc = Tok.getLocation();
411 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
412 RedefNameLoc, AliasNameLoc);
415 void Parser::HandlePragmaFPContract() {
416 assert(Tok.is(tok::annot_pragma_fp_contract));
417 tok::OnOffSwitch OOS =
418 static_cast<tok::OnOffSwitch>(
419 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
420 Actions.ActOnPragmaFPContract(OOS);
421 ConsumeToken(); // The annotation token.
424 StmtResult Parser::HandlePragmaCaptured()
426 assert(Tok.is(tok::annot_pragma_captured));
429 if (Tok.isNot(tok::l_brace)) {
430 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
434 SourceLocation Loc = Tok.getLocation();
436 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
437 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
440 StmtResult R = ParseCompoundStatement();
441 CapturedRegionScope.Exit();
444 Actions.ActOnCapturedRegionError();
448 return Actions.ActOnCapturedRegionEnd(R.get());
452 typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
455 void Parser::HandlePragmaOpenCLExtension() {
456 assert(Tok.is(tok::annot_pragma_opencl_extension));
458 OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
459 unsigned state = data.getInt();
460 IdentifierInfo *ename = data.getPointer();
461 SourceLocation NameLoc = Tok.getLocation();
462 ConsumeToken(); // The annotation token.
464 OpenCLOptions &f = Actions.getOpenCLOptions();
465 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
466 // overriding all previously issued extension directives, but only if the
467 // behavior is set to disable."
468 if (state == 0 && ename->isStr("all")) {
469 #define OPENCLEXT(nm) f.nm = 0;
470 #include "clang/Basic/OpenCLExtensions.def"
472 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
473 #include "clang/Basic/OpenCLExtensions.def"
475 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
480 void Parser::HandlePragmaMSPointersToMembers() {
481 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
482 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
483 static_cast<LangOptions::PragmaMSPointersToMembersKind>(
484 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
485 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
486 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
489 void Parser::HandlePragmaMSVtorDisp() {
490 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
491 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
492 Sema::PragmaVtorDispKind Kind =
493 static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
494 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
495 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
496 Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
499 void Parser::HandlePragmaMSPragma() {
500 assert(Tok.is(tok::annot_pragma_ms_pragma));
501 // Grab the tokens out of the annotation and enter them into the stream.
502 auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
503 PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
504 SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
505 assert(Tok.isAnyIdentifier());
506 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
507 PP.Lex(Tok); // pragma kind
509 // Figure out which #pragma we're dealing with. The switch has no default
510 // because lex shouldn't emit the annotation token for unrecognized pragmas.
511 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
512 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
513 .Case("data_seg", &Parser::HandlePragmaMSSegment)
514 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
515 .Case("const_seg", &Parser::HandlePragmaMSSegment)
516 .Case("code_seg", &Parser::HandlePragmaMSSegment)
517 .Case("section", &Parser::HandlePragmaMSSection)
518 .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
520 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
521 // Pragma handling failed, and has been diagnosed. Slurp up the tokens
522 // until eof (really end of line) to prevent follow-on errors.
523 while (Tok.isNot(tok::eof))
529 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
530 SourceLocation PragmaLocation) {
531 if (Tok.isNot(tok::l_paren)) {
532 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
536 // Parsing code for pragma section
537 if (Tok.isNot(tok::string_literal)) {
538 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
542 ExprResult StringResult = ParseStringLiteralExpression();
543 if (StringResult.isInvalid())
544 return false; // Already diagnosed.
545 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
546 if (SegmentName->getCharByteWidth() != 1) {
547 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
551 int SectionFlags = ASTContext::PSF_Read;
552 bool SectionFlagsAreDefault = true;
553 while (Tok.is(tok::comma)) {
555 // Ignore "long" and "short".
556 // They are undocumented, but widely used, section attributes which appear
558 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
559 PP.Lex(Tok); // long/short
563 if (!Tok.isAnyIdentifier()) {
564 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
568 ASTContext::PragmaSectionFlag Flag =
569 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
570 Tok.getIdentifierInfo()->getName())
571 .Case("read", ASTContext::PSF_Read)
572 .Case("write", ASTContext::PSF_Write)
573 .Case("execute", ASTContext::PSF_Execute)
574 .Case("shared", ASTContext::PSF_Invalid)
575 .Case("nopage", ASTContext::PSF_Invalid)
576 .Case("nocache", ASTContext::PSF_Invalid)
577 .Case("discard", ASTContext::PSF_Invalid)
578 .Case("remove", ASTContext::PSF_Invalid)
579 .Default(ASTContext::PSF_None);
580 if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
581 PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
582 ? diag::warn_pragma_invalid_specific_action
583 : diag::warn_pragma_unsupported_action)
584 << PragmaName << Tok.getIdentifierInfo()->getName();
587 SectionFlags |= Flag;
588 SectionFlagsAreDefault = false;
589 PP.Lex(Tok); // Identifier
591 // If no section attributes are specified, the section will be marked as
593 if (SectionFlagsAreDefault)
594 SectionFlags |= ASTContext::PSF_Write;
595 if (Tok.isNot(tok::r_paren)) {
596 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
600 if (Tok.isNot(tok::eof)) {
601 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
606 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
610 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
611 SourceLocation PragmaLocation) {
612 if (Tok.isNot(tok::l_paren)) {
613 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
617 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
619 if (Tok.isAnyIdentifier()) {
620 StringRef PushPop = Tok.getIdentifierInfo()->getName();
621 if (PushPop == "push")
622 Action = Sema::PSK_Push;
623 else if (PushPop == "pop")
624 Action = Sema::PSK_Pop;
626 PP.Diag(PragmaLocation,
627 diag::warn_pragma_expected_section_push_pop_or_name)
631 if (Action != Sema::PSK_Reset) {
632 PP.Lex(Tok); // push | pop
633 if (Tok.is(tok::comma)) {
635 // If we've got a comma, we either need a label or a string.
636 if (Tok.isAnyIdentifier()) {
637 SlotLabel = Tok.getIdentifierInfo()->getName();
638 PP.Lex(Tok); // identifier
639 if (Tok.is(tok::comma))
641 else if (Tok.isNot(tok::r_paren)) {
642 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
647 } else if (Tok.isNot(tok::r_paren)) {
648 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
653 // Grab the string literal for our section name.
654 StringLiteral *SegmentName = nullptr;
655 if (Tok.isNot(tok::r_paren)) {
656 if (Tok.isNot(tok::string_literal)) {
657 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
658 diag::warn_pragma_expected_section_name :
659 diag::warn_pragma_expected_section_label_or_name :
660 diag::warn_pragma_expected_section_push_pop_or_name;
661 PP.Diag(PragmaLocation, DiagID) << PragmaName;
664 ExprResult StringResult = ParseStringLiteralExpression();
665 if (StringResult.isInvalid())
666 return false; // Already diagnosed.
667 SegmentName = cast<StringLiteral>(StringResult.get());
668 if (SegmentName->getCharByteWidth() != 1) {
669 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
673 // Setting section "" has no effect
674 if (SegmentName->getLength())
675 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
677 if (Tok.isNot(tok::r_paren)) {
678 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
682 if (Tok.isNot(tok::eof)) {
683 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
688 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
689 SegmentName, PragmaName);
693 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
694 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
695 SourceLocation PragmaLocation) {
696 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
697 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
701 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
705 // Parse either the known section names or the string section name.
706 StringLiteral *SegmentName = nullptr;
707 if (Tok.isAnyIdentifier()) {
708 auto *II = Tok.getIdentifierInfo();
709 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
710 .Case("compiler", "\".CRT$XCC\"")
711 .Case("lib", "\".CRT$XCL\"")
712 .Case("user", "\".CRT$XCU\"")
715 if (!Section.empty()) {
716 // Pretend the user wrote the appropriate string literal here.
718 Toks[0].startToken();
719 Toks[0].setKind(tok::string_literal);
720 Toks[0].setLocation(Tok.getLocation());
721 Toks[0].setLiteralData(Section.data());
722 Toks[0].setLength(Section.size());
724 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
727 } else if (Tok.is(tok::string_literal)) {
728 ExprResult StringResult = ParseStringLiteralExpression();
729 if (StringResult.isInvalid())
731 SegmentName = cast<StringLiteral>(StringResult.get());
732 if (SegmentName->getCharByteWidth() != 1) {
733 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
737 // FIXME: Add support for the '[, func-name]' part of the pragma.
741 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
745 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
747 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
751 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
756 struct PragmaLoopHintInfo {
759 ArrayRef<Token> Toks;
761 } // end anonymous namespace
763 static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
764 std::string PragmaString;
765 if (PragmaName.getIdentifierInfo()->getName() == "loop") {
766 PragmaString = "clang loop ";
767 PragmaString += Option.getIdentifierInfo()->getName();
769 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
770 "Unexpected pragma name");
771 PragmaString = "unroll";
776 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
777 assert(Tok.is(tok::annot_pragma_loop_hint));
778 PragmaLoopHintInfo *Info =
779 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
781 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
782 Hint.PragmaNameLoc = IdentifierLoc::create(
783 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
785 // It is possible that the loop hint has no option identifier, such as
786 // #pragma unroll(4).
787 IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
788 ? Info->Option.getIdentifierInfo()
790 Hint.OptionLoc = IdentifierLoc::create(
791 Actions.Context, Info->Option.getLocation(), OptionInfo);
793 const Token *Toks = Info->Toks.data();
794 size_t TokSize = Info->Toks.size();
796 // Return a valid hint if pragma unroll or nounroll were specified
797 // without an argument.
798 bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
799 bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
800 if (TokSize == 0 && (PragmaUnroll || PragmaNoUnroll)) {
801 ConsumeToken(); // The annotation token.
802 Hint.Range = Info->PragmaName.getLocation();
806 // The constant expression is always followed by an eof token, which increases
808 assert(TokSize > 0 &&
809 "PragmaLoopHintInfo::Toks must contain at least one token.");
811 // If no option is specified the argument is assumed to be a constant expr.
812 bool OptionUnroll = false;
813 bool StateOption = false;
814 if (OptionInfo) { // Pragma Unroll does not specify an option.
815 OptionUnroll = OptionInfo->isStr("unroll");
816 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
817 .Case("vectorize", true)
818 .Case("interleave", true)
819 .Case("unroll", true)
823 // Verify loop hint has an argument.
824 if (Toks[0].is(tok::eof)) {
825 ConsumeToken(); // The annotation token.
826 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
827 << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll;
831 // Validate the argument.
833 ConsumeToken(); // The annotation token.
834 SourceLocation StateLoc = Toks[0].getLocation();
835 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
837 (!StateInfo->isStr("enable") && !StateInfo->isStr("disable") &&
838 ((OptionUnroll && !StateInfo->isStr("full")) ||
839 (!OptionUnroll && !StateInfo->isStr("assume_safety"))))) {
840 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
841 << /*FullKeyword=*/OptionUnroll;
845 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
846 << PragmaLoopHintString(Info->PragmaName, Info->Option);
847 Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
849 // Enter constant expression including eof terminator into token stream.
850 PP.EnterTokenStream(Toks, TokSize, /*DisableMacroExpansion=*/false,
851 /*OwnsTokens=*/false);
852 ConsumeToken(); // The annotation token.
854 ExprResult R = ParseConstantExpression();
856 // Tokens following an error in an ill-formed constant expression will
857 // remain in the token stream and must be removed.
858 if (Tok.isNot(tok::eof)) {
859 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
860 << PragmaLoopHintString(Info->PragmaName, Info->Option);
861 while (Tok.isNot(tok::eof))
865 ConsumeToken(); // Consume the constant expression eof terminator.
868 Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
871 // Argument is a constant expression with an integer type.
872 Hint.ValueExpr = R.get();
875 Hint.Range = SourceRange(Info->PragmaName.getLocation(),
876 Info->Toks[TokSize - 1].getLocation());
880 // #pragma GCC visibility comes in two variants:
881 // 'push' '(' [visibility] ')'
883 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
884 PragmaIntroducerKind Introducer,
886 SourceLocation VisLoc = VisTok.getLocation();
889 PP.LexUnexpandedToken(Tok);
891 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
893 const IdentifierInfo *VisType;
894 if (PushPop && PushPop->isStr("pop")) {
896 } else if (PushPop && PushPop->isStr("push")) {
897 PP.LexUnexpandedToken(Tok);
898 if (Tok.isNot(tok::l_paren)) {
899 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
903 PP.LexUnexpandedToken(Tok);
904 VisType = Tok.getIdentifierInfo();
906 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
910 PP.LexUnexpandedToken(Tok);
911 if (Tok.isNot(tok::r_paren)) {
912 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
917 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
921 SourceLocation EndLoc = Tok.getLocation();
922 PP.LexUnexpandedToken(Tok);
923 if (Tok.isNot(tok::eod)) {
924 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
929 Token *Toks = new Token[1];
930 Toks[0].startToken();
931 Toks[0].setKind(tok::annot_pragma_vis);
932 Toks[0].setLocation(VisLoc);
933 Toks[0].setAnnotationEndLoc(EndLoc);
934 Toks[0].setAnnotationValue(
935 const_cast<void*>(static_cast<const void*>(VisType)));
936 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
937 /*OwnsTokens=*/true);
940 // #pragma pack(...) comes in the following delicious flavors:
941 // pack '(' [integer] ')'
942 // pack '(' 'show' ')'
943 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
944 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
945 PragmaIntroducerKind Introducer,
947 SourceLocation PackLoc = PackTok.getLocation();
951 if (Tok.isNot(tok::l_paren)) {
952 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
956 Sema::PragmaPackKind Kind = Sema::PPK_Default;
957 IdentifierInfo *Name = nullptr;
959 Alignment.startToken();
960 SourceLocation LParenLoc = Tok.getLocation();
962 if (Tok.is(tok::numeric_constant)) {
967 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
968 // the push/pop stack.
969 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
970 if (PP.getLangOpts().ApplePragmaPack)
971 Kind = Sema::PPK_Push;
972 } else if (Tok.is(tok::identifier)) {
973 const IdentifierInfo *II = Tok.getIdentifierInfo();
974 if (II->isStr("show")) {
975 Kind = Sema::PPK_Show;
978 if (II->isStr("push")) {
979 Kind = Sema::PPK_Push;
980 } else if (II->isStr("pop")) {
981 Kind = Sema::PPK_Pop;
983 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
988 if (Tok.is(tok::comma)) {
991 if (Tok.is(tok::numeric_constant)) {
995 } else if (Tok.is(tok::identifier)) {
996 Name = Tok.getIdentifierInfo();
999 if (Tok.is(tok::comma)) {
1002 if (Tok.isNot(tok::numeric_constant)) {
1003 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1012 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1017 } else if (PP.getLangOpts().ApplePragmaPack) {
1018 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1019 // the push/pop stack.
1020 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1021 Kind = Sema::PPK_Pop;
1024 if (Tok.isNot(tok::r_paren)) {
1025 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1029 SourceLocation RParenLoc = Tok.getLocation();
1031 if (Tok.isNot(tok::eod)) {
1032 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1036 PragmaPackInfo *Info =
1037 (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
1038 sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
1039 new (Info) PragmaPackInfo();
1042 Info->Alignment = Alignment;
1043 Info->LParenLoc = LParenLoc;
1044 Info->RParenLoc = RParenLoc;
1047 (Token*) PP.getPreprocessorAllocator().Allocate(
1048 sizeof(Token) * 1, llvm::alignOf<Token>());
1050 Toks[0].startToken();
1051 Toks[0].setKind(tok::annot_pragma_pack);
1052 Toks[0].setLocation(PackLoc);
1053 Toks[0].setAnnotationEndLoc(RParenLoc);
1054 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1055 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1056 /*OwnsTokens=*/false);
1059 // #pragma ms_struct on
1060 // #pragma ms_struct off
1061 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1062 PragmaIntroducerKind Introducer,
1063 Token &MSStructTok) {
1064 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
1068 if (Tok.isNot(tok::identifier)) {
1069 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1072 SourceLocation EndLoc = Tok.getLocation();
1073 const IdentifierInfo *II = Tok.getIdentifierInfo();
1074 if (II->isStr("on")) {
1075 Kind = Sema::PMSST_ON;
1078 else if (II->isStr("off") || II->isStr("reset"))
1081 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1085 if (Tok.isNot(tok::eod)) {
1086 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1092 (Token*) PP.getPreprocessorAllocator().Allocate(
1093 sizeof(Token) * 1, llvm::alignOf<Token>());
1095 Toks[0].startToken();
1096 Toks[0].setKind(tok::annot_pragma_msstruct);
1097 Toks[0].setLocation(MSStructTok.getLocation());
1098 Toks[0].setAnnotationEndLoc(EndLoc);
1099 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1100 static_cast<uintptr_t>(Kind)));
1101 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1102 /*OwnsTokens=*/false);
1105 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1106 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1107 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1113 if (Tok.isNot(tok::identifier) ||
1114 !Tok.getIdentifierInfo()->isStr("align")) {
1115 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1121 if (Tok.isNot(tok::equal)) {
1122 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1128 if (Tok.isNot(tok::identifier)) {
1129 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1130 << (IsOptions ? "options" : "align");
1134 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1135 const IdentifierInfo *II = Tok.getIdentifierInfo();
1136 if (II->isStr("native"))
1137 Kind = Sema::POAK_Native;
1138 else if (II->isStr("natural"))
1139 Kind = Sema::POAK_Natural;
1140 else if (II->isStr("packed"))
1141 Kind = Sema::POAK_Packed;
1142 else if (II->isStr("power"))
1143 Kind = Sema::POAK_Power;
1144 else if (II->isStr("mac68k"))
1145 Kind = Sema::POAK_Mac68k;
1146 else if (II->isStr("reset"))
1147 Kind = Sema::POAK_Reset;
1149 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1154 SourceLocation EndLoc = Tok.getLocation();
1156 if (Tok.isNot(tok::eod)) {
1157 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1158 << (IsOptions ? "options" : "align");
1163 (Token*) PP.getPreprocessorAllocator().Allocate(
1164 sizeof(Token) * 1, llvm::alignOf<Token>());
1166 Toks[0].startToken();
1167 Toks[0].setKind(tok::annot_pragma_align);
1168 Toks[0].setLocation(FirstTok.getLocation());
1169 Toks[0].setAnnotationEndLoc(EndLoc);
1170 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1171 static_cast<uintptr_t>(Kind)));
1172 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1173 /*OwnsTokens=*/false);
1176 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1177 PragmaIntroducerKind Introducer,
1179 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1182 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1183 PragmaIntroducerKind Introducer,
1184 Token &OptionsTok) {
1185 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1188 // #pragma unused(identifier)
1189 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1190 PragmaIntroducerKind Introducer,
1192 // FIXME: Should we be expanding macros here? My guess is no.
1193 SourceLocation UnusedLoc = UnusedTok.getLocation();
1195 // Lex the left '('.
1198 if (Tok.isNot(tok::l_paren)) {
1199 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1203 // Lex the declaration reference(s).
1204 SmallVector<Token, 5> Identifiers;
1205 SourceLocation RParenLoc;
1212 if (Tok.is(tok::identifier)) {
1213 Identifiers.push_back(Tok);
1219 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1223 // We are execting a ')' or a ','.
1224 if (Tok.is(tok::comma)) {
1229 if (Tok.is(tok::r_paren)) {
1230 RParenLoc = Tok.getLocation();
1235 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1240 if (Tok.isNot(tok::eod)) {
1241 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1246 // Verify that we have a location for the right parenthesis.
1247 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1248 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1250 // For each identifier token, insert into the token stream a
1251 // annot_pragma_unused token followed by the identifier token.
1252 // This allows us to cache a "#pragma unused" that occurs inside an inline
1253 // C++ member function.
1256 (Token*) PP.getPreprocessorAllocator().Allocate(
1257 sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
1258 for (unsigned i=0; i != Identifiers.size(); i++) {
1259 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1260 pragmaUnusedTok.startToken();
1261 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1262 pragmaUnusedTok.setLocation(UnusedLoc);
1263 idTok = Identifiers[i];
1265 PP.EnterTokenStream(Toks, 2*Identifiers.size(),
1266 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1269 // #pragma weak identifier
1270 // #pragma weak identifier '=' identifier
1271 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1272 PragmaIntroducerKind Introducer,
1274 SourceLocation WeakLoc = WeakTok.getLocation();
1278 if (Tok.isNot(tok::identifier)) {
1279 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1283 Token WeakName = Tok;
1284 bool HasAlias = false;
1288 if (Tok.is(tok::equal)) {
1291 if (Tok.isNot(tok::identifier)) {
1292 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1300 if (Tok.isNot(tok::eod)) {
1301 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1307 (Token*) PP.getPreprocessorAllocator().Allocate(
1308 sizeof(Token) * 3, llvm::alignOf<Token>());
1309 Token &pragmaUnusedTok = Toks[0];
1310 pragmaUnusedTok.startToken();
1311 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1312 pragmaUnusedTok.setLocation(WeakLoc);
1313 pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
1315 Toks[2] = AliasName;
1316 PP.EnterTokenStream(Toks, 3,
1317 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1320 (Token*) PP.getPreprocessorAllocator().Allocate(
1321 sizeof(Token) * 2, llvm::alignOf<Token>());
1322 Token &pragmaUnusedTok = Toks[0];
1323 pragmaUnusedTok.startToken();
1324 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1325 pragmaUnusedTok.setLocation(WeakLoc);
1326 pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
1328 PP.EnterTokenStream(Toks, 2,
1329 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1333 // #pragma redefine_extname identifier identifier
1334 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
1335 PragmaIntroducerKind Introducer,
1336 Token &RedefToken) {
1337 SourceLocation RedefLoc = RedefToken.getLocation();
1341 if (Tok.isNot(tok::identifier)) {
1342 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1347 Token RedefName = Tok;
1350 if (Tok.isNot(tok::identifier)) {
1351 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1352 << "redefine_extname";
1356 Token AliasName = Tok;
1359 if (Tok.isNot(tok::eod)) {
1360 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1366 (Token*) PP.getPreprocessorAllocator().Allocate(
1367 sizeof(Token) * 3, llvm::alignOf<Token>());
1368 Token &pragmaRedefTok = Toks[0];
1369 pragmaRedefTok.startToken();
1370 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
1371 pragmaRedefTok.setLocation(RedefLoc);
1372 pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
1373 Toks[1] = RedefName;
1374 Toks[2] = AliasName;
1375 PP.EnterTokenStream(Toks, 3,
1376 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1381 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
1382 PragmaIntroducerKind Introducer,
1384 tok::OnOffSwitch OOS;
1385 if (PP.LexOnOffSwitch(OOS))
1389 (Token*) PP.getPreprocessorAllocator().Allocate(
1390 sizeof(Token) * 1, llvm::alignOf<Token>());
1392 Toks[0].startToken();
1393 Toks[0].setKind(tok::annot_pragma_fp_contract);
1394 Toks[0].setLocation(Tok.getLocation());
1395 Toks[0].setAnnotationEndLoc(Tok.getLocation());
1396 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1397 static_cast<uintptr_t>(OOS)));
1398 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1399 /*OwnsTokens=*/false);
1403 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
1404 PragmaIntroducerKind Introducer,
1406 PP.LexUnexpandedToken(Tok);
1407 if (Tok.isNot(tok::identifier)) {
1408 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1412 IdentifierInfo *ename = Tok.getIdentifierInfo();
1413 SourceLocation NameLoc = Tok.getLocation();
1416 if (Tok.isNot(tok::colon)) {
1417 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
1422 if (Tok.isNot(tok::identifier)) {
1423 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
1426 IdentifierInfo *op = Tok.getIdentifierInfo();
1429 if (op->isStr("enable")) {
1431 } else if (op->isStr("disable")) {
1434 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
1437 SourceLocation StateLoc = Tok.getLocation();
1440 if (Tok.isNot(tok::eod)) {
1441 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1446 OpenCLExtData data(ename, state);
1448 (Token*) PP.getPreprocessorAllocator().Allocate(
1449 sizeof(Token) * 1, llvm::alignOf<Token>());
1451 Toks[0].startToken();
1452 Toks[0].setKind(tok::annot_pragma_opencl_extension);
1453 Toks[0].setLocation(NameLoc);
1454 Toks[0].setAnnotationValue(data.getOpaqueValue());
1455 Toks[0].setAnnotationEndLoc(StateLoc);
1456 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1457 /*OwnsTokens=*/false);
1459 if (PP.getPPCallbacks())
1460 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename,
1464 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
1467 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
1468 PragmaIntroducerKind Introducer,
1470 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
1471 FirstTok.getLocation())) {
1472 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
1473 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
1474 diag::Severity::Ignored, SourceLocation());
1476 PP.DiscardUntilEndOfDirective();
1479 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
1482 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
1483 PragmaIntroducerKind Introducer,
1485 SmallVector<Token, 16> Pragma;
1488 Tok.setKind(tok::annot_pragma_openmp);
1489 Tok.setLocation(FirstTok.getLocation());
1491 while (Tok.isNot(tok::eod)) {
1492 Pragma.push_back(Tok);
1495 SourceLocation EodLoc = Tok.getLocation();
1497 Tok.setKind(tok::annot_pragma_openmp_end);
1498 Tok.setLocation(EodLoc);
1499 Pragma.push_back(Tok);
1501 Token *Toks = new Token[Pragma.size()];
1502 std::copy(Pragma.begin(), Pragma.end(), Toks);
1503 PP.EnterTokenStream(Toks, Pragma.size(),
1504 /*DisableMacroExpansion=*/false, /*OwnsTokens=*/true);
1507 /// \brief Handle '#pragma pointers_to_members'
1508 // The grammar for this pragma is as follows:
1510 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
1512 // #pragma pointers_to_members '(' 'best_case' ')'
1513 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
1514 // #pragma pointers_to_members '(' inheritance-model ')'
1515 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
1516 PragmaIntroducerKind Introducer,
1518 SourceLocation PointersToMembersLoc = Tok.getLocation();
1520 if (Tok.isNot(tok::l_paren)) {
1521 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
1522 << "pointers_to_members";
1526 const IdentifierInfo *Arg = Tok.getIdentifierInfo();
1528 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1529 << "pointers_to_members";
1534 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
1535 if (Arg->isStr("best_case")) {
1536 RepresentationMethod = LangOptions::PPTMK_BestCase;
1538 if (Arg->isStr("full_generality")) {
1539 if (Tok.is(tok::comma)) {
1542 Arg = Tok.getIdentifierInfo();
1544 PP.Diag(Tok.getLocation(),
1545 diag::err_pragma_pointers_to_members_unknown_kind)
1546 << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
1550 } else if (Tok.is(tok::r_paren)) {
1551 // #pragma pointers_to_members(full_generality) implicitly specifies
1552 // virtual_inheritance.
1554 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1556 PP.Diag(Tok.getLocation(), diag::err_expected_punc)
1557 << "full_generality";
1563 if (Arg->isStr("single_inheritance")) {
1564 RepresentationMethod =
1565 LangOptions::PPTMK_FullGeneralitySingleInheritance;
1566 } else if (Arg->isStr("multiple_inheritance")) {
1567 RepresentationMethod =
1568 LangOptions::PPTMK_FullGeneralityMultipleInheritance;
1569 } else if (Arg->isStr("virtual_inheritance")) {
1570 RepresentationMethod =
1571 LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1573 PP.Diag(Tok.getLocation(),
1574 diag::err_pragma_pointers_to_members_unknown_kind)
1575 << Arg << /*HasPointerDeclaration*/ 1;
1581 if (Tok.isNot(tok::r_paren)) {
1582 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
1583 << (Arg ? Arg->getName() : "full_generality");
1587 SourceLocation EndLoc = Tok.getLocation();
1589 if (Tok.isNot(tok::eod)) {
1590 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1591 << "pointers_to_members";
1596 AnnotTok.startToken();
1597 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
1598 AnnotTok.setLocation(PointersToMembersLoc);
1599 AnnotTok.setAnnotationEndLoc(EndLoc);
1600 AnnotTok.setAnnotationValue(
1601 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
1602 PP.EnterToken(AnnotTok);
1605 /// \brief Handle '#pragma vtordisp'
1606 // The grammar for this pragma is as follows:
1608 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
1610 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
1611 // #pragma vtordisp '(' 'pop' ')'
1612 // #pragma vtordisp '(' ')'
1613 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
1614 PragmaIntroducerKind Introducer,
1616 SourceLocation VtorDispLoc = Tok.getLocation();
1618 if (Tok.isNot(tok::l_paren)) {
1619 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
1624 Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
1625 const IdentifierInfo *II = Tok.getIdentifierInfo();
1627 if (II->isStr("push")) {
1628 // #pragma vtordisp(push, mode)
1630 if (Tok.isNot(tok::comma)) {
1631 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
1635 Kind = Sema::PVDK_Push;
1636 // not push, could be on/off
1637 } else if (II->isStr("pop")) {
1638 // #pragma vtordisp(pop)
1640 Kind = Sema::PVDK_Pop;
1642 // not push or pop, could be on/off
1644 if (Tok.is(tok::r_paren)) {
1645 // #pragma vtordisp()
1646 Kind = Sema::PVDK_Reset;
1652 if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
1653 const IdentifierInfo *II = Tok.getIdentifierInfo();
1654 if (II && II->isStr("off")) {
1657 } else if (II && II->isStr("on")) {
1660 } else if (Tok.is(tok::numeric_constant) &&
1661 PP.parseSimpleIntegerLiteral(Tok, Value)) {
1663 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
1664 << 0 << 2 << "vtordisp";
1668 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1674 // Finish the pragma: ')' $
1675 if (Tok.isNot(tok::r_paren)) {
1676 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
1679 SourceLocation EndLoc = Tok.getLocation();
1681 if (Tok.isNot(tok::eod)) {
1682 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1687 // Enter the annotation.
1689 AnnotTok.startToken();
1690 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
1691 AnnotTok.setLocation(VtorDispLoc);
1692 AnnotTok.setAnnotationEndLoc(EndLoc);
1693 AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
1694 static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
1695 PP.EnterToken(AnnotTok);
1698 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting
1699 /// an annotation token.
1700 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
1701 PragmaIntroducerKind Introducer,
1703 Token EoF, AnnotTok;
1705 EoF.setKind(tok::eof);
1706 AnnotTok.startToken();
1707 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
1708 AnnotTok.setLocation(Tok.getLocation());
1709 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1710 SmallVector<Token, 8> TokenVector;
1711 // Suck up all of the tokens before the eod.
1712 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
1713 TokenVector.push_back(Tok);
1714 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1716 // Add a sentinal EoF token to the end of the list.
1717 TokenVector.push_back(EoF);
1718 // We must allocate this array with new because EnterTokenStream is going to
1720 Token *TokenArray = new Token[TokenVector.size()];
1721 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray);
1722 auto Value = new (PP.getPreprocessorAllocator())
1723 std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
1724 AnnotTok.setAnnotationValue(Value);
1725 PP.EnterToken(AnnotTok);
1728 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
1732 /// #pragma detect_mismatch("name", "value")
1734 /// Where 'name' and 'value' are quoted strings. The values are embedded in
1735 /// the object file and passed along to the linker. If the linker detects a
1736 /// mismatch in the object file's values for the given name, a LNK2038 error
1737 /// is emitted. See MSDN for more details.
1738 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
1739 PragmaIntroducerKind Introducer,
1741 SourceLocation CommentLoc = Tok.getLocation();
1743 if (Tok.isNot(tok::l_paren)) {
1744 PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
1748 // Read the name to embed, which must be a string literal.
1749 std::string NameString;
1750 if (!PP.LexStringLiteral(Tok, NameString,
1751 "pragma detect_mismatch",
1752 /*MacroExpansion=*/true))
1755 // Read the comma followed by a second string literal.
1756 std::string ValueString;
1757 if (Tok.isNot(tok::comma)) {
1758 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1762 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
1763 /*MacroExpansion=*/true))
1766 if (Tok.isNot(tok::r_paren)) {
1767 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1770 PP.Lex(Tok); // Eat the r_paren.
1772 if (Tok.isNot(tok::eod)) {
1773 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1777 // If the pragma is lexically sound, notify any interested PPCallbacks.
1778 if (PP.getPPCallbacks())
1779 PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString,
1782 Actions.ActOnPragmaDetectMismatch(NameString, ValueString);
1785 /// \brief Handle the microsoft \#pragma comment extension.
1789 /// #pragma comment(linker, "foo")
1791 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
1792 /// "foo" is a string, which is fully macro expanded, and permits string
1793 /// concatenation, embedded escape characters etc. See MSDN for more details.
1794 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
1795 PragmaIntroducerKind Introducer,
1797 SourceLocation CommentLoc = Tok.getLocation();
1799 if (Tok.isNot(tok::l_paren)) {
1800 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1804 // Read the identifier.
1806 if (Tok.isNot(tok::identifier)) {
1807 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1811 // Verify that this is one of the 5 whitelisted options.
1812 IdentifierInfo *II = Tok.getIdentifierInfo();
1813 Sema::PragmaMSCommentKind Kind =
1814 llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())
1815 .Case("linker", Sema::PCK_Linker)
1816 .Case("lib", Sema::PCK_Lib)
1817 .Case("compiler", Sema::PCK_Compiler)
1818 .Case("exestr", Sema::PCK_ExeStr)
1819 .Case("user", Sema::PCK_User)
1820 .Default(Sema::PCK_Unknown);
1821 if (Kind == Sema::PCK_Unknown) {
1822 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
1826 // On PS4, issue a warning about any pragma comments other than
1827 // #pragma comment lib.
1828 if (PP.getTargetInfo().getTriple().isPS4() && Kind != Sema::PCK_Lib) {
1829 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
1834 // Read the optional string if present.
1836 std::string ArgumentString;
1837 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
1839 /*MacroExpansion=*/true))
1842 // FIXME: warn that 'exestr' is deprecated.
1843 // FIXME: If the kind is "compiler" warn if the string is present (it is
1845 // The MSDN docs say that "lib" and "linker" require a string and have a short
1846 // whitelist of linker options they support, but in practice MSVC doesn't
1847 // issue a diagnostic. Therefore neither does clang.
1849 if (Tok.isNot(tok::r_paren)) {
1850 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1853 PP.Lex(Tok); // eat the r_paren.
1855 if (Tok.isNot(tok::eod)) {
1856 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1860 // If the pragma is lexically sound, notify any interested PPCallbacks.
1861 if (PP.getPPCallbacks())
1862 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
1864 Actions.ActOnPragmaMSComment(Kind, ArgumentString);
1867 // #pragma clang optimize off
1868 // #pragma clang optimize on
1869 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
1870 PragmaIntroducerKind Introducer,
1871 Token &FirstToken) {
1874 if (Tok.is(tok::eod)) {
1875 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
1876 << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
1879 if (Tok.isNot(tok::identifier)) {
1880 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1881 << PP.getSpelling(Tok);
1884 const IdentifierInfo *II = Tok.getIdentifierInfo();
1885 // The only accepted values are 'on' or 'off'.
1887 if (II->isStr("on")) {
1889 } else if (!II->isStr("off")) {
1890 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1891 << PP.getSpelling(Tok);
1896 if (Tok.isNot(tok::eod)) {
1897 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
1898 << PP.getSpelling(Tok);
1902 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
1905 /// \brief Parses loop or unroll pragma hint value and fills in Info.
1906 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
1907 Token Option, bool ValueInParens,
1908 PragmaLoopHintInfo &Info) {
1909 SmallVector<Token, 1> ValueList;
1910 int OpenParens = ValueInParens ? 1 : 0;
1911 // Read constant expression.
1912 while (Tok.isNot(tok::eod)) {
1913 if (Tok.is(tok::l_paren))
1915 else if (Tok.is(tok::r_paren)) {
1917 if (OpenParens == 0 && ValueInParens)
1921 ValueList.push_back(Tok);
1925 if (ValueInParens) {
1927 if (Tok.isNot(tok::r_paren)) {
1928 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1935 EOFTok.startToken();
1936 EOFTok.setKind(tok::eof);
1937 EOFTok.setLocation(Tok.getLocation());
1938 ValueList.push_back(EOFTok); // Terminates expression for parsing.
1940 Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
1942 Info.PragmaName = PragmaName;
1943 Info.Option = Option;
1947 /// \brief Handle the \#pragma clang loop directive.
1948 /// #pragma clang 'loop' loop-hints
1951 /// loop-hint loop-hints[opt]
1954 /// 'vectorize' '(' loop-hint-keyword ')'
1955 /// 'interleave' '(' loop-hint-keyword ')'
1956 /// 'unroll' '(' unroll-hint-keyword ')'
1957 /// 'vectorize_width' '(' loop-hint-value ')'
1958 /// 'interleave_count' '(' loop-hint-value ')'
1959 /// 'unroll_count' '(' loop-hint-value ')'
1961 /// loop-hint-keyword:
1966 /// unroll-hint-keyword:
1971 /// loop-hint-value:
1972 /// constant-expression
1974 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
1975 /// try vectorizing the instructions of the loop it precedes. Specifying
1976 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
1977 /// interleaving multiple iterations of the loop it precedes. The width of the
1978 /// vector instructions is specified by vectorize_width() and the number of
1979 /// interleaved loop iterations is specified by interleave_count(). Specifying a
1980 /// value of 1 effectively disables vectorization/interleaving, even if it is
1981 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
1982 /// only works on inner loops.
1984 /// The unroll and unroll_count directives control the concatenation
1985 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
1986 /// completely if the trip count is known at compile time and unroll partially
1987 /// if the trip count is not known. Specifying unroll(full) is similar to
1988 /// unroll(enable) but will unroll the loop only if the trip count is known at
1989 /// compile time. Specifying unroll(disable) disables unrolling for the
1990 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
1991 /// loop the number of times indicated by the value.
1992 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
1993 PragmaIntroducerKind Introducer,
1995 // Incoming token is "loop" from "#pragma clang loop".
1996 Token PragmaName = Tok;
1997 SmallVector<Token, 1> TokenList;
1999 // Lex the optimization option and verify it is an identifier.
2001 if (Tok.isNot(tok::identifier)) {
2002 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2003 << /*MissingOption=*/true << "";
2007 while (Tok.is(tok::identifier)) {
2009 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2011 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2012 .Case("vectorize", true)
2013 .Case("interleave", true)
2014 .Case("unroll", true)
2015 .Case("vectorize_width", true)
2016 .Case("interleave_count", true)
2017 .Case("unroll_count", true)
2020 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2021 << /*MissingOption=*/false << OptionInfo;
2027 if (Tok.isNot(tok::l_paren)) {
2028 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2033 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2034 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2038 // Generate the loop hint token.
2040 LoopHintTok.startToken();
2041 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2042 LoopHintTok.setLocation(PragmaName.getLocation());
2043 LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2044 LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2045 TokenList.push_back(LoopHintTok);
2048 if (Tok.isNot(tok::eod)) {
2049 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2054 Token *TokenArray = new Token[TokenList.size()];
2055 std::copy(TokenList.begin(), TokenList.end(), TokenArray);
2057 PP.EnterTokenStream(TokenArray, TokenList.size(),
2058 /*DisableMacroExpansion=*/false,
2059 /*OwnsTokens=*/true);
2062 /// \brief Handle the loop unroll optimization pragmas.
2064 /// #pragma unroll unroll-hint-value
2065 /// #pragma unroll '(' unroll-hint-value ')'
2066 /// #pragma nounroll
2068 /// unroll-hint-value:
2069 /// constant-expression
2071 /// Loop unrolling hints can be specified with '#pragma unroll' or
2072 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2073 /// contained in parentheses. With no argument the directive instructs llvm to
2074 /// try to unroll the loop completely. A positive integer argument can be
2075 /// specified to indicate the number of times the loop should be unrolled. To
2076 /// maximize compatibility with other compilers the unroll count argument can be
2077 /// specified with or without parentheses. Specifying, '#pragma nounroll'
2078 /// disables unrolling of the loop.
2079 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2080 PragmaIntroducerKind Introducer,
2082 // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2083 // "#pragma nounroll".
2084 Token PragmaName = Tok;
2086 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2087 if (Tok.is(tok::eod)) {
2088 // nounroll or unroll pragma without an argument.
2089 Info->PragmaName = PragmaName;
2090 Info->Option.startToken();
2091 } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
2092 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2096 // Unroll pragma with an argument: "#pragma unroll N" or
2097 // "#pragma unroll(N)".
2098 // Read '(' if it exists.
2099 bool ValueInParens = Tok.is(tok::l_paren);
2104 Option.startToken();
2105 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2108 // In CUDA, the argument to '#pragma unroll' should not be contained in
2110 if (PP.getLangOpts().CUDA && ValueInParens)
2111 PP.Diag(Info->Toks[0].getLocation(),
2112 diag::warn_pragma_unroll_cuda_value_in_parens);
2114 if (Tok.isNot(tok::eod)) {
2115 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2121 // Generate the hint token.
2122 Token *TokenArray = new Token[1];
2123 TokenArray[0].startToken();
2124 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2125 TokenArray[0].setLocation(PragmaName.getLocation());
2126 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2127 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2128 PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false,
2129 /*OwnsTokens=*/true);