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/Basic/TargetInfo.h"
16 #include "clang/Lex/Preprocessor.h"
17 #include "clang/Parse/ParseDiagnostic.h"
18 #include "clang/Parse/Parser.h"
19 #include "clang/Sema/LoopHint.h"
20 #include "clang/Sema/Scope.h"
21 #include "llvm/ADT/StringSwitch.h"
22 using namespace clang;
26 struct PragmaAlignHandler : public PragmaHandler {
27 explicit PragmaAlignHandler() : PragmaHandler("align") {}
28 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
29 Token &FirstToken) override;
32 struct PragmaGCCVisibilityHandler : public PragmaHandler {
33 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
34 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
35 Token &FirstToken) override;
38 struct PragmaOptionsHandler : public PragmaHandler {
39 explicit PragmaOptionsHandler() : PragmaHandler("options") {}
40 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
41 Token &FirstToken) override;
44 struct PragmaPackHandler : public PragmaHandler {
45 explicit PragmaPackHandler() : PragmaHandler("pack") {}
46 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
47 Token &FirstToken) override;
50 struct PragmaMSStructHandler : public PragmaHandler {
51 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
52 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
53 Token &FirstToken) override;
56 struct PragmaUnusedHandler : public PragmaHandler {
57 PragmaUnusedHandler() : PragmaHandler("unused") {}
58 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
59 Token &FirstToken) override;
62 struct PragmaWeakHandler : public PragmaHandler {
63 explicit PragmaWeakHandler() : PragmaHandler("weak") {}
64 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
65 Token &FirstToken) override;
68 struct PragmaRedefineExtnameHandler : public PragmaHandler {
69 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
70 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
71 Token &FirstToken) override;
74 struct PragmaOpenCLExtensionHandler : public PragmaHandler {
75 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
76 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
77 Token &FirstToken) override;
81 struct PragmaFPContractHandler : public PragmaHandler {
82 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
83 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
84 Token &FirstToken) override;
87 struct PragmaNoOpenMPHandler : public PragmaHandler {
88 PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
89 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
90 Token &FirstToken) override;
93 struct PragmaOpenMPHandler : public PragmaHandler {
94 PragmaOpenMPHandler() : PragmaHandler("omp") { }
95 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
96 Token &FirstToken) override;
99 /// PragmaCommentHandler - "\#pragma comment ...".
100 struct PragmaCommentHandler : public PragmaHandler {
101 PragmaCommentHandler(Sema &Actions)
102 : PragmaHandler("comment"), Actions(Actions) {}
103 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
104 Token &FirstToken) override;
109 struct PragmaDetectMismatchHandler : public PragmaHandler {
110 PragmaDetectMismatchHandler(Sema &Actions)
111 : PragmaHandler("detect_mismatch"), Actions(Actions) {}
112 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
113 Token &FirstToken) override;
118 struct PragmaMSPointersToMembers : public PragmaHandler {
119 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
120 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
121 Token &FirstToken) override;
124 struct PragmaMSVtorDisp : public PragmaHandler {
125 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
126 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
127 Token &FirstToken) override;
130 struct PragmaMSPragma : public PragmaHandler {
131 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
132 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
133 Token &FirstToken) override;
136 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
137 struct PragmaOptimizeHandler : public PragmaHandler {
138 PragmaOptimizeHandler(Sema &S)
139 : PragmaHandler("optimize"), Actions(S) {}
140 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
141 Token &FirstToken) override;
146 struct PragmaLoopHintHandler : public PragmaHandler {
147 PragmaLoopHintHandler() : PragmaHandler("loop") {}
148 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
149 Token &FirstToken) override;
152 struct PragmaUnrollHintHandler : public PragmaHandler {
153 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
154 void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
155 Token &FirstToken) override;
160 void Parser::initializePragmaHandlers() {
161 AlignHandler.reset(new PragmaAlignHandler());
162 PP.AddPragmaHandler(AlignHandler.get());
164 GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
165 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
167 OptionsHandler.reset(new PragmaOptionsHandler());
168 PP.AddPragmaHandler(OptionsHandler.get());
170 PackHandler.reset(new PragmaPackHandler());
171 PP.AddPragmaHandler(PackHandler.get());
173 MSStructHandler.reset(new PragmaMSStructHandler());
174 PP.AddPragmaHandler(MSStructHandler.get());
176 UnusedHandler.reset(new PragmaUnusedHandler());
177 PP.AddPragmaHandler(UnusedHandler.get());
179 WeakHandler.reset(new PragmaWeakHandler());
180 PP.AddPragmaHandler(WeakHandler.get());
182 RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
183 PP.AddPragmaHandler(RedefineExtnameHandler.get());
185 FPContractHandler.reset(new PragmaFPContractHandler());
186 PP.AddPragmaHandler("STDC", FPContractHandler.get());
188 if (getLangOpts().OpenCL) {
189 OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
190 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
192 PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
194 if (getLangOpts().OpenMP)
195 OpenMPHandler.reset(new PragmaOpenMPHandler());
197 OpenMPHandler.reset(new PragmaNoOpenMPHandler());
198 PP.AddPragmaHandler(OpenMPHandler.get());
200 if (getLangOpts().MicrosoftExt) {
201 MSCommentHandler.reset(new PragmaCommentHandler(Actions));
202 PP.AddPragmaHandler(MSCommentHandler.get());
203 MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
204 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
205 MSPointersToMembers.reset(new PragmaMSPointersToMembers());
206 PP.AddPragmaHandler(MSPointersToMembers.get());
207 MSVtorDisp.reset(new PragmaMSVtorDisp());
208 PP.AddPragmaHandler(MSVtorDisp.get());
209 MSInitSeg.reset(new PragmaMSPragma("init_seg"));
210 PP.AddPragmaHandler(MSInitSeg.get());
211 MSDataSeg.reset(new PragmaMSPragma("data_seg"));
212 PP.AddPragmaHandler(MSDataSeg.get());
213 MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
214 PP.AddPragmaHandler(MSBSSSeg.get());
215 MSConstSeg.reset(new PragmaMSPragma("const_seg"));
216 PP.AddPragmaHandler(MSConstSeg.get());
217 MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
218 PP.AddPragmaHandler(MSCodeSeg.get());
219 MSSection.reset(new PragmaMSPragma("section"));
220 PP.AddPragmaHandler(MSSection.get());
223 OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
224 PP.AddPragmaHandler("clang", OptimizeHandler.get());
226 LoopHintHandler.reset(new PragmaLoopHintHandler());
227 PP.AddPragmaHandler("clang", LoopHintHandler.get());
229 UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
230 PP.AddPragmaHandler(UnrollHintHandler.get());
233 void Parser::resetPragmaHandlers() {
234 // Remove the pragma handlers we installed.
235 PP.RemovePragmaHandler(AlignHandler.get());
236 AlignHandler.reset();
237 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
238 GCCVisibilityHandler.reset();
239 PP.RemovePragmaHandler(OptionsHandler.get());
240 OptionsHandler.reset();
241 PP.RemovePragmaHandler(PackHandler.get());
243 PP.RemovePragmaHandler(MSStructHandler.get());
244 MSStructHandler.reset();
245 PP.RemovePragmaHandler(UnusedHandler.get());
246 UnusedHandler.reset();
247 PP.RemovePragmaHandler(WeakHandler.get());
249 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
250 RedefineExtnameHandler.reset();
252 if (getLangOpts().OpenCL) {
253 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
254 OpenCLExtensionHandler.reset();
255 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
257 PP.RemovePragmaHandler(OpenMPHandler.get());
258 OpenMPHandler.reset();
260 if (getLangOpts().MicrosoftExt) {
261 PP.RemovePragmaHandler(MSCommentHandler.get());
262 MSCommentHandler.reset();
263 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
264 MSDetectMismatchHandler.reset();
265 PP.RemovePragmaHandler(MSPointersToMembers.get());
266 MSPointersToMembers.reset();
267 PP.RemovePragmaHandler(MSVtorDisp.get());
269 PP.RemovePragmaHandler(MSInitSeg.get());
271 PP.RemovePragmaHandler(MSDataSeg.get());
273 PP.RemovePragmaHandler(MSBSSSeg.get());
275 PP.RemovePragmaHandler(MSConstSeg.get());
277 PP.RemovePragmaHandler(MSCodeSeg.get());
279 PP.RemovePragmaHandler(MSSection.get());
283 PP.RemovePragmaHandler("STDC", FPContractHandler.get());
284 FPContractHandler.reset();
286 PP.RemovePragmaHandler("clang", OptimizeHandler.get());
287 OptimizeHandler.reset();
289 PP.RemovePragmaHandler("clang", LoopHintHandler.get());
290 LoopHintHandler.reset();
292 PP.RemovePragmaHandler(UnrollHintHandler.get());
293 UnrollHintHandler.reset();
296 /// \brief Handle the annotation token produced for #pragma unused(...)
298 /// Each annot_pragma_unused is followed by the argument token so e.g.
299 /// "#pragma unused(x,y)" becomes:
300 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
301 void Parser::HandlePragmaUnused() {
302 assert(Tok.is(tok::annot_pragma_unused));
303 SourceLocation UnusedLoc = ConsumeToken();
304 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
305 ConsumeToken(); // The argument token.
308 void Parser::HandlePragmaVisibility() {
309 assert(Tok.is(tok::annot_pragma_vis));
310 const IdentifierInfo *VisType =
311 static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
312 SourceLocation VisLoc = ConsumeToken();
313 Actions.ActOnPragmaVisibility(VisType, VisLoc);
316 struct PragmaPackInfo {
317 Sema::PragmaPackKind Kind;
318 IdentifierInfo *Name;
320 SourceLocation LParenLoc;
321 SourceLocation RParenLoc;
324 void Parser::HandlePragmaPack() {
325 assert(Tok.is(tok::annot_pragma_pack));
326 PragmaPackInfo *Info =
327 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
328 SourceLocation PragmaLoc = ConsumeToken();
329 ExprResult Alignment;
330 if (Info->Alignment.is(tok::numeric_constant)) {
331 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
332 if (Alignment.isInvalid())
335 Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
336 Info->LParenLoc, Info->RParenLoc);
339 void Parser::HandlePragmaMSStruct() {
340 assert(Tok.is(tok::annot_pragma_msstruct));
341 Sema::PragmaMSStructKind Kind =
342 static_cast<Sema::PragmaMSStructKind>(
343 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
344 Actions.ActOnPragmaMSStruct(Kind);
345 ConsumeToken(); // The annotation token.
348 void Parser::HandlePragmaAlign() {
349 assert(Tok.is(tok::annot_pragma_align));
350 Sema::PragmaOptionsAlignKind Kind =
351 static_cast<Sema::PragmaOptionsAlignKind>(
352 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
353 SourceLocation PragmaLoc = ConsumeToken();
354 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
357 void Parser::HandlePragmaWeak() {
358 assert(Tok.is(tok::annot_pragma_weak));
359 SourceLocation PragmaLoc = ConsumeToken();
360 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
362 ConsumeToken(); // The weak name.
365 void Parser::HandlePragmaWeakAlias() {
366 assert(Tok.is(tok::annot_pragma_weakalias));
367 SourceLocation PragmaLoc = ConsumeToken();
368 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
369 SourceLocation WeakNameLoc = Tok.getLocation();
371 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
372 SourceLocation AliasNameLoc = Tok.getLocation();
374 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
375 WeakNameLoc, AliasNameLoc);
379 void Parser::HandlePragmaRedefineExtname() {
380 assert(Tok.is(tok::annot_pragma_redefine_extname));
381 SourceLocation RedefLoc = ConsumeToken();
382 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
383 SourceLocation RedefNameLoc = Tok.getLocation();
385 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
386 SourceLocation AliasNameLoc = Tok.getLocation();
388 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
389 RedefNameLoc, AliasNameLoc);
392 void Parser::HandlePragmaFPContract() {
393 assert(Tok.is(tok::annot_pragma_fp_contract));
394 tok::OnOffSwitch OOS =
395 static_cast<tok::OnOffSwitch>(
396 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
397 Actions.ActOnPragmaFPContract(OOS);
398 ConsumeToken(); // The annotation token.
401 StmtResult Parser::HandlePragmaCaptured()
403 assert(Tok.is(tok::annot_pragma_captured));
406 if (Tok.isNot(tok::l_brace)) {
407 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
411 SourceLocation Loc = Tok.getLocation();
413 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
414 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
417 StmtResult R = ParseCompoundStatement();
418 CapturedRegionScope.Exit();
421 Actions.ActOnCapturedRegionError();
425 return Actions.ActOnCapturedRegionEnd(R.get());
429 typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
432 void Parser::HandlePragmaOpenCLExtension() {
433 assert(Tok.is(tok::annot_pragma_opencl_extension));
435 OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
436 unsigned state = data.getInt();
437 IdentifierInfo *ename = data.getPointer();
438 SourceLocation NameLoc = Tok.getLocation();
439 ConsumeToken(); // The annotation token.
441 OpenCLOptions &f = Actions.getOpenCLOptions();
442 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
443 // overriding all previously issued extension directives, but only if the
444 // behavior is set to disable."
445 if (state == 0 && ename->isStr("all")) {
446 #define OPENCLEXT(nm) f.nm = 0;
447 #include "clang/Basic/OpenCLExtensions.def"
449 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
450 #include "clang/Basic/OpenCLExtensions.def"
452 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
457 void Parser::HandlePragmaMSPointersToMembers() {
458 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
459 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
460 static_cast<LangOptions::PragmaMSPointersToMembersKind>(
461 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
462 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
463 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
466 void Parser::HandlePragmaMSVtorDisp() {
467 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
468 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
469 Sema::PragmaVtorDispKind Kind =
470 static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
471 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
472 SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
473 Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
476 void Parser::HandlePragmaMSPragma() {
477 assert(Tok.is(tok::annot_pragma_ms_pragma));
478 // Grab the tokens out of the annotation and enter them into the stream.
479 auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
480 PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
481 SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
482 assert(Tok.isAnyIdentifier());
483 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
484 PP.Lex(Tok); // pragma kind
486 // Figure out which #pragma we're dealing with. The switch has no default
487 // because lex shouldn't emit the annotation token for unrecognized pragmas.
488 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
489 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
490 .Case("data_seg", &Parser::HandlePragmaMSSegment)
491 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
492 .Case("const_seg", &Parser::HandlePragmaMSSegment)
493 .Case("code_seg", &Parser::HandlePragmaMSSegment)
494 .Case("section", &Parser::HandlePragmaMSSection)
495 .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
497 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
498 // Pragma handling failed, and has been diagnosed. Slurp up the tokens
499 // until eof (really end of line) to prevent follow-on errors.
500 while (Tok.isNot(tok::eof))
506 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
507 SourceLocation PragmaLocation) {
508 if (Tok.isNot(tok::l_paren)) {
509 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
513 // Parsing code for pragma section
514 if (Tok.isNot(tok::string_literal)) {
515 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
519 ExprResult StringResult = ParseStringLiteralExpression();
520 if (StringResult.isInvalid())
521 return false; // Already diagnosed.
522 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
523 if (SegmentName->getCharByteWidth() != 1) {
524 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
528 int SectionFlags = 0;
529 while (Tok.is(tok::comma)) {
531 if (!Tok.isAnyIdentifier()) {
532 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
536 Sema::PragmaSectionFlag Flag =
537 llvm::StringSwitch<Sema::PragmaSectionFlag>(
538 Tok.getIdentifierInfo()->getName())
539 .Case("read", Sema::PSF_Read)
540 .Case("write", Sema::PSF_Write)
541 .Case("execute", Sema::PSF_Execute)
542 .Case("shared", Sema::PSF_Invalid)
543 .Case("nopage", Sema::PSF_Invalid)
544 .Case("nocache", Sema::PSF_Invalid)
545 .Case("discard", Sema::PSF_Invalid)
546 .Case("remove", Sema::PSF_Invalid)
547 .Default(Sema::PSF_None);
548 if (Flag == Sema::PSF_None || Flag == Sema::PSF_Invalid) {
549 PP.Diag(PragmaLocation, Flag == Sema::PSF_None
550 ? diag::warn_pragma_invalid_specific_action
551 : diag::warn_pragma_unsupported_action)
552 << PragmaName << Tok.getIdentifierInfo()->getName();
555 SectionFlags |= Flag;
556 PP.Lex(Tok); // Identifier
558 if (Tok.isNot(tok::r_paren)) {
559 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
563 if (Tok.isNot(tok::eof)) {
564 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
569 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
573 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
574 SourceLocation PragmaLocation) {
575 if (Tok.isNot(tok::l_paren)) {
576 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
580 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
582 if (Tok.isAnyIdentifier()) {
583 StringRef PushPop = Tok.getIdentifierInfo()->getName();
584 if (PushPop == "push")
585 Action = Sema::PSK_Push;
586 else if (PushPop == "pop")
587 Action = Sema::PSK_Pop;
589 PP.Diag(PragmaLocation,
590 diag::warn_pragma_expected_section_push_pop_or_name)
594 if (Action != Sema::PSK_Reset) {
595 PP.Lex(Tok); // push | pop
596 if (Tok.is(tok::comma)) {
598 // If we've got a comma, we either need a label or a string.
599 if (Tok.isAnyIdentifier()) {
600 SlotLabel = Tok.getIdentifierInfo()->getName();
601 PP.Lex(Tok); // identifier
602 if (Tok.is(tok::comma))
604 else if (Tok.isNot(tok::r_paren)) {
605 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
610 } else if (Tok.isNot(tok::r_paren)) {
611 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
616 // Grab the string literal for our section name.
617 StringLiteral *SegmentName = nullptr;
618 if (Tok.isNot(tok::r_paren)) {
619 if (Tok.isNot(tok::string_literal)) {
620 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
621 diag::warn_pragma_expected_section_name :
622 diag::warn_pragma_expected_section_label_or_name :
623 diag::warn_pragma_expected_section_push_pop_or_name;
624 PP.Diag(PragmaLocation, DiagID) << PragmaName;
627 ExprResult StringResult = ParseStringLiteralExpression();
628 if (StringResult.isInvalid())
629 return false; // Already diagnosed.
630 SegmentName = cast<StringLiteral>(StringResult.get());
631 if (SegmentName->getCharByteWidth() != 1) {
632 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
636 // Setting section "" has no effect
637 if (SegmentName->getLength())
638 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
640 if (Tok.isNot(tok::r_paren)) {
641 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
645 if (Tok.isNot(tok::eof)) {
646 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
651 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
652 SegmentName, PragmaName);
656 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
657 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
658 SourceLocation PragmaLocation) {
659 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
660 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
664 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
668 // Parse either the known section names or the string section name.
669 StringLiteral *SegmentName = nullptr;
670 if (Tok.isAnyIdentifier()) {
671 auto *II = Tok.getIdentifierInfo();
672 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
673 .Case("compiler", "\".CRT$XCC\"")
674 .Case("lib", "\".CRT$XCL\"")
675 .Case("user", "\".CRT$XCU\"")
678 if (!Section.empty()) {
679 // Pretend the user wrote the appropriate string literal here.
681 Toks[0].startToken();
682 Toks[0].setKind(tok::string_literal);
683 Toks[0].setLocation(Tok.getLocation());
684 Toks[0].setLiteralData(Section.data());
685 Toks[0].setLength(Section.size());
687 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
690 } else if (Tok.is(tok::string_literal)) {
691 ExprResult StringResult = ParseStringLiteralExpression();
692 if (StringResult.isInvalid())
694 SegmentName = cast<StringLiteral>(StringResult.get());
695 if (SegmentName->getCharByteWidth() != 1) {
696 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
700 // FIXME: Add support for the '[, func-name]' part of the pragma.
704 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
708 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
710 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
714 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
718 struct PragmaLoopHintInfo {
725 LoopHint Parser::HandlePragmaLoopHint() {
726 assert(Tok.is(tok::annot_pragma_loop_hint));
727 PragmaLoopHintInfo *Info =
728 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
732 IdentifierLoc::create(Actions.Context, Info->PragmaName.getLocation(),
733 Info->PragmaName.getIdentifierInfo());
735 IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),
736 Info->Option.getIdentifierInfo());
737 if (Info->HasValue) {
739 SourceRange(Info->Option.getLocation(), Info->Value.getLocation());
741 IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),
742 Info->Value.getIdentifierInfo());
744 // FIXME: We should allow non-type template parameters for the loop hint
745 // value. See bug report #19610
746 if (Info->Value.is(tok::numeric_constant))
747 Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();
749 Hint.ValueExpr = nullptr;
751 Hint.Range = SourceRange(Info->PragmaName.getLocation());
752 Hint.ValueLoc = nullptr;
753 Hint.ValueExpr = nullptr;
759 // #pragma GCC visibility comes in two variants:
760 // 'push' '(' [visibility] ')'
762 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
763 PragmaIntroducerKind Introducer,
765 SourceLocation VisLoc = VisTok.getLocation();
768 PP.LexUnexpandedToken(Tok);
770 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
772 const IdentifierInfo *VisType;
773 if (PushPop && PushPop->isStr("pop")) {
775 } else if (PushPop && PushPop->isStr("push")) {
776 PP.LexUnexpandedToken(Tok);
777 if (Tok.isNot(tok::l_paren)) {
778 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
782 PP.LexUnexpandedToken(Tok);
783 VisType = Tok.getIdentifierInfo();
785 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
789 PP.LexUnexpandedToken(Tok);
790 if (Tok.isNot(tok::r_paren)) {
791 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
796 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
800 PP.LexUnexpandedToken(Tok);
801 if (Tok.isNot(tok::eod)) {
802 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
807 Token *Toks = new Token[1];
808 Toks[0].startToken();
809 Toks[0].setKind(tok::annot_pragma_vis);
810 Toks[0].setLocation(VisLoc);
811 Toks[0].setAnnotationValue(
812 const_cast<void*>(static_cast<const void*>(VisType)));
813 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
814 /*OwnsTokens=*/true);
817 // #pragma pack(...) comes in the following delicious flavors:
818 // pack '(' [integer] ')'
819 // pack '(' 'show' ')'
820 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
821 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
822 PragmaIntroducerKind Introducer,
824 SourceLocation PackLoc = PackTok.getLocation();
828 if (Tok.isNot(tok::l_paren)) {
829 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
833 Sema::PragmaPackKind Kind = Sema::PPK_Default;
834 IdentifierInfo *Name = nullptr;
836 Alignment.startToken();
837 SourceLocation LParenLoc = Tok.getLocation();
839 if (Tok.is(tok::numeric_constant)) {
844 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
845 // the push/pop stack.
846 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
847 if (PP.getLangOpts().ApplePragmaPack)
848 Kind = Sema::PPK_Push;
849 } else if (Tok.is(tok::identifier)) {
850 const IdentifierInfo *II = Tok.getIdentifierInfo();
851 if (II->isStr("show")) {
852 Kind = Sema::PPK_Show;
855 if (II->isStr("push")) {
856 Kind = Sema::PPK_Push;
857 } else if (II->isStr("pop")) {
858 Kind = Sema::PPK_Pop;
860 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
865 if (Tok.is(tok::comma)) {
868 if (Tok.is(tok::numeric_constant)) {
872 } else if (Tok.is(tok::identifier)) {
873 Name = Tok.getIdentifierInfo();
876 if (Tok.is(tok::comma)) {
879 if (Tok.isNot(tok::numeric_constant)) {
880 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
889 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
894 } else if (PP.getLangOpts().ApplePragmaPack) {
895 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
896 // the push/pop stack.
897 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
898 Kind = Sema::PPK_Pop;
901 if (Tok.isNot(tok::r_paren)) {
902 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
906 SourceLocation RParenLoc = Tok.getLocation();
908 if (Tok.isNot(tok::eod)) {
909 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
913 PragmaPackInfo *Info =
914 (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
915 sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
916 new (Info) PragmaPackInfo();
919 Info->Alignment = Alignment;
920 Info->LParenLoc = LParenLoc;
921 Info->RParenLoc = RParenLoc;
924 (Token*) PP.getPreprocessorAllocator().Allocate(
925 sizeof(Token) * 1, llvm::alignOf<Token>());
927 Toks[0].startToken();
928 Toks[0].setKind(tok::annot_pragma_pack);
929 Toks[0].setLocation(PackLoc);
930 Toks[0].setAnnotationValue(static_cast<void*>(Info));
931 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
932 /*OwnsTokens=*/false);
935 // #pragma ms_struct on
936 // #pragma ms_struct off
937 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
938 PragmaIntroducerKind Introducer,
939 Token &MSStructTok) {
940 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
944 if (Tok.isNot(tok::identifier)) {
945 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
948 const IdentifierInfo *II = Tok.getIdentifierInfo();
949 if (II->isStr("on")) {
950 Kind = Sema::PMSST_ON;
953 else if (II->isStr("off") || II->isStr("reset"))
956 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
960 if (Tok.isNot(tok::eod)) {
961 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
967 (Token*) PP.getPreprocessorAllocator().Allocate(
968 sizeof(Token) * 1, llvm::alignOf<Token>());
970 Toks[0].startToken();
971 Toks[0].setKind(tok::annot_pragma_msstruct);
972 Toks[0].setLocation(MSStructTok.getLocation());
973 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
974 static_cast<uintptr_t>(Kind)));
975 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
976 /*OwnsTokens=*/false);
979 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
980 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
981 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
987 if (Tok.isNot(tok::identifier) ||
988 !Tok.getIdentifierInfo()->isStr("align")) {
989 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
995 if (Tok.isNot(tok::equal)) {
996 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1002 if (Tok.isNot(tok::identifier)) {
1003 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1004 << (IsOptions ? "options" : "align");
1008 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1009 const IdentifierInfo *II = Tok.getIdentifierInfo();
1010 if (II->isStr("native"))
1011 Kind = Sema::POAK_Native;
1012 else if (II->isStr("natural"))
1013 Kind = Sema::POAK_Natural;
1014 else if (II->isStr("packed"))
1015 Kind = Sema::POAK_Packed;
1016 else if (II->isStr("power"))
1017 Kind = Sema::POAK_Power;
1018 else if (II->isStr("mac68k"))
1019 Kind = Sema::POAK_Mac68k;
1020 else if (II->isStr("reset"))
1021 Kind = Sema::POAK_Reset;
1023 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1029 if (Tok.isNot(tok::eod)) {
1030 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1031 << (IsOptions ? "options" : "align");
1036 (Token*) PP.getPreprocessorAllocator().Allocate(
1037 sizeof(Token) * 1, llvm::alignOf<Token>());
1039 Toks[0].startToken();
1040 Toks[0].setKind(tok::annot_pragma_align);
1041 Toks[0].setLocation(FirstTok.getLocation());
1042 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1043 static_cast<uintptr_t>(Kind)));
1044 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1045 /*OwnsTokens=*/false);
1048 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1049 PragmaIntroducerKind Introducer,
1051 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1054 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1055 PragmaIntroducerKind Introducer,
1056 Token &OptionsTok) {
1057 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1060 // #pragma unused(identifier)
1061 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1062 PragmaIntroducerKind Introducer,
1064 // FIXME: Should we be expanding macros here? My guess is no.
1065 SourceLocation UnusedLoc = UnusedTok.getLocation();
1067 // Lex the left '('.
1070 if (Tok.isNot(tok::l_paren)) {
1071 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1075 // Lex the declaration reference(s).
1076 SmallVector<Token, 5> Identifiers;
1077 SourceLocation RParenLoc;
1084 if (Tok.is(tok::identifier)) {
1085 Identifiers.push_back(Tok);
1091 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1095 // We are execting a ')' or a ','.
1096 if (Tok.is(tok::comma)) {
1101 if (Tok.is(tok::r_paren)) {
1102 RParenLoc = Tok.getLocation();
1107 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1112 if (Tok.isNot(tok::eod)) {
1113 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1118 // Verify that we have a location for the right parenthesis.
1119 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1120 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1122 // For each identifier token, insert into the token stream a
1123 // annot_pragma_unused token followed by the identifier token.
1124 // This allows us to cache a "#pragma unused" that occurs inside an inline
1125 // C++ member function.
1128 (Token*) PP.getPreprocessorAllocator().Allocate(
1129 sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
1130 for (unsigned i=0; i != Identifiers.size(); i++) {
1131 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1132 pragmaUnusedTok.startToken();
1133 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1134 pragmaUnusedTok.setLocation(UnusedLoc);
1135 idTok = Identifiers[i];
1137 PP.EnterTokenStream(Toks, 2*Identifiers.size(),
1138 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1141 // #pragma weak identifier
1142 // #pragma weak identifier '=' identifier
1143 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1144 PragmaIntroducerKind Introducer,
1146 SourceLocation WeakLoc = WeakTok.getLocation();
1150 if (Tok.isNot(tok::identifier)) {
1151 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1155 Token WeakName = Tok;
1156 bool HasAlias = false;
1160 if (Tok.is(tok::equal)) {
1163 if (Tok.isNot(tok::identifier)) {
1164 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1172 if (Tok.isNot(tok::eod)) {
1173 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1179 (Token*) PP.getPreprocessorAllocator().Allocate(
1180 sizeof(Token) * 3, llvm::alignOf<Token>());
1181 Token &pragmaUnusedTok = Toks[0];
1182 pragmaUnusedTok.startToken();
1183 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1184 pragmaUnusedTok.setLocation(WeakLoc);
1186 Toks[2] = AliasName;
1187 PP.EnterTokenStream(Toks, 3,
1188 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1191 (Token*) PP.getPreprocessorAllocator().Allocate(
1192 sizeof(Token) * 2, llvm::alignOf<Token>());
1193 Token &pragmaUnusedTok = Toks[0];
1194 pragmaUnusedTok.startToken();
1195 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1196 pragmaUnusedTok.setLocation(WeakLoc);
1198 PP.EnterTokenStream(Toks, 2,
1199 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1203 // #pragma redefine_extname identifier identifier
1204 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
1205 PragmaIntroducerKind Introducer,
1206 Token &RedefToken) {
1207 SourceLocation RedefLoc = RedefToken.getLocation();
1211 if (Tok.isNot(tok::identifier)) {
1212 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1217 Token RedefName = Tok;
1220 if (Tok.isNot(tok::identifier)) {
1221 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1222 << "redefine_extname";
1226 Token AliasName = Tok;
1229 if (Tok.isNot(tok::eod)) {
1230 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1236 (Token*) PP.getPreprocessorAllocator().Allocate(
1237 sizeof(Token) * 3, llvm::alignOf<Token>());
1238 Token &pragmaRedefTok = Toks[0];
1239 pragmaRedefTok.startToken();
1240 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
1241 pragmaRedefTok.setLocation(RedefLoc);
1242 Toks[1] = RedefName;
1243 Toks[2] = AliasName;
1244 PP.EnterTokenStream(Toks, 3,
1245 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1250 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
1251 PragmaIntroducerKind Introducer,
1253 tok::OnOffSwitch OOS;
1254 if (PP.LexOnOffSwitch(OOS))
1258 (Token*) PP.getPreprocessorAllocator().Allocate(
1259 sizeof(Token) * 1, llvm::alignOf<Token>());
1261 Toks[0].startToken();
1262 Toks[0].setKind(tok::annot_pragma_fp_contract);
1263 Toks[0].setLocation(Tok.getLocation());
1264 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1265 static_cast<uintptr_t>(OOS)));
1266 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1267 /*OwnsTokens=*/false);
1271 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
1272 PragmaIntroducerKind Introducer,
1274 PP.LexUnexpandedToken(Tok);
1275 if (Tok.isNot(tok::identifier)) {
1276 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1280 IdentifierInfo *ename = Tok.getIdentifierInfo();
1281 SourceLocation NameLoc = Tok.getLocation();
1284 if (Tok.isNot(tok::colon)) {
1285 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
1290 if (Tok.isNot(tok::identifier)) {
1291 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
1294 IdentifierInfo *op = Tok.getIdentifierInfo();
1297 if (op->isStr("enable")) {
1299 } else if (op->isStr("disable")) {
1302 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
1305 SourceLocation StateLoc = Tok.getLocation();
1308 if (Tok.isNot(tok::eod)) {
1309 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1314 OpenCLExtData data(ename, state);
1316 (Token*) PP.getPreprocessorAllocator().Allocate(
1317 sizeof(Token) * 1, llvm::alignOf<Token>());
1319 Toks[0].startToken();
1320 Toks[0].setKind(tok::annot_pragma_opencl_extension);
1321 Toks[0].setLocation(NameLoc);
1322 Toks[0].setAnnotationValue(data.getOpaqueValue());
1323 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1324 /*OwnsTokens=*/false);
1326 if (PP.getPPCallbacks())
1327 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename,
1331 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
1334 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
1335 PragmaIntroducerKind Introducer,
1337 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
1338 FirstTok.getLocation())) {
1339 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
1340 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
1341 diag::Severity::Ignored, SourceLocation());
1343 PP.DiscardUntilEndOfDirective();
1346 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
1349 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
1350 PragmaIntroducerKind Introducer,
1352 SmallVector<Token, 16> Pragma;
1355 Tok.setKind(tok::annot_pragma_openmp);
1356 Tok.setLocation(FirstTok.getLocation());
1358 while (Tok.isNot(tok::eod)) {
1359 Pragma.push_back(Tok);
1362 SourceLocation EodLoc = Tok.getLocation();
1364 Tok.setKind(tok::annot_pragma_openmp_end);
1365 Tok.setLocation(EodLoc);
1366 Pragma.push_back(Tok);
1368 Token *Toks = new Token[Pragma.size()];
1369 std::copy(Pragma.begin(), Pragma.end(), Toks);
1370 PP.EnterTokenStream(Toks, Pragma.size(),
1371 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
1374 /// \brief Handle '#pragma pointers_to_members'
1375 // The grammar for this pragma is as follows:
1377 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
1379 // #pragma pointers_to_members '(' 'best_case' ')'
1380 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
1381 // #pragma pointers_to_members '(' inheritance-model ')'
1382 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
1383 PragmaIntroducerKind Introducer,
1385 SourceLocation PointersToMembersLoc = Tok.getLocation();
1387 if (Tok.isNot(tok::l_paren)) {
1388 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
1389 << "pointers_to_members";
1393 const IdentifierInfo *Arg = Tok.getIdentifierInfo();
1395 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1396 << "pointers_to_members";
1401 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
1402 if (Arg->isStr("best_case")) {
1403 RepresentationMethod = LangOptions::PPTMK_BestCase;
1405 if (Arg->isStr("full_generality")) {
1406 if (Tok.is(tok::comma)) {
1409 Arg = Tok.getIdentifierInfo();
1411 PP.Diag(Tok.getLocation(),
1412 diag::err_pragma_pointers_to_members_unknown_kind)
1413 << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
1417 } else if (Tok.is(tok::r_paren)) {
1418 // #pragma pointers_to_members(full_generality) implicitly specifies
1419 // virtual_inheritance.
1421 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1423 PP.Diag(Tok.getLocation(), diag::err_expected_punc)
1424 << "full_generality";
1430 if (Arg->isStr("single_inheritance")) {
1431 RepresentationMethod =
1432 LangOptions::PPTMK_FullGeneralitySingleInheritance;
1433 } else if (Arg->isStr("multiple_inheritance")) {
1434 RepresentationMethod =
1435 LangOptions::PPTMK_FullGeneralityMultipleInheritance;
1436 } else if (Arg->isStr("virtual_inheritance")) {
1437 RepresentationMethod =
1438 LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1440 PP.Diag(Tok.getLocation(),
1441 diag::err_pragma_pointers_to_members_unknown_kind)
1442 << Arg << /*HasPointerDeclaration*/ 1;
1448 if (Tok.isNot(tok::r_paren)) {
1449 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
1450 << (Arg ? Arg->getName() : "full_generality");
1455 if (Tok.isNot(tok::eod)) {
1456 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1457 << "pointers_to_members";
1462 AnnotTok.startToken();
1463 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
1464 AnnotTok.setLocation(PointersToMembersLoc);
1465 AnnotTok.setAnnotationValue(
1466 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
1467 PP.EnterToken(AnnotTok);
1470 /// \brief Handle '#pragma vtordisp'
1471 // The grammar for this pragma is as follows:
1473 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
1475 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
1476 // #pragma vtordisp '(' 'pop' ')'
1477 // #pragma vtordisp '(' ')'
1478 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
1479 PragmaIntroducerKind Introducer,
1481 SourceLocation VtorDispLoc = Tok.getLocation();
1483 if (Tok.isNot(tok::l_paren)) {
1484 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
1489 Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
1490 const IdentifierInfo *II = Tok.getIdentifierInfo();
1492 if (II->isStr("push")) {
1493 // #pragma vtordisp(push, mode)
1495 if (Tok.isNot(tok::comma)) {
1496 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
1500 Kind = Sema::PVDK_Push;
1501 // not push, could be on/off
1502 } else if (II->isStr("pop")) {
1503 // #pragma vtordisp(pop)
1505 Kind = Sema::PVDK_Pop;
1507 // not push or pop, could be on/off
1509 if (Tok.is(tok::r_paren)) {
1510 // #pragma vtordisp()
1511 Kind = Sema::PVDK_Reset;
1517 if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
1518 const IdentifierInfo *II = Tok.getIdentifierInfo();
1519 if (II && II->isStr("off")) {
1522 } else if (II && II->isStr("on")) {
1525 } else if (Tok.is(tok::numeric_constant) &&
1526 PP.parseSimpleIntegerLiteral(Tok, Value)) {
1528 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
1529 << 0 << 2 << "vtordisp";
1533 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1539 // Finish the pragma: ')' $
1540 if (Tok.isNot(tok::r_paren)) {
1541 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
1545 if (Tok.isNot(tok::eod)) {
1546 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1551 // Enter the annotation.
1553 AnnotTok.startToken();
1554 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
1555 AnnotTok.setLocation(VtorDispLoc);
1556 AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
1557 static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
1558 PP.EnterToken(AnnotTok);
1561 /// \brief Handle all MS pragmas. Simply forwards the tokens after inserting
1562 /// an annotation token.
1563 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
1564 PragmaIntroducerKind Introducer,
1566 Token EoF, AnnotTok;
1568 EoF.setKind(tok::eof);
1569 AnnotTok.startToken();
1570 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
1571 AnnotTok.setLocation(Tok.getLocation());
1572 SmallVector<Token, 8> TokenVector;
1573 // Suck up all of the tokens before the eod.
1574 for (; Tok.isNot(tok::eod); PP.Lex(Tok))
1575 TokenVector.push_back(Tok);
1576 // Add a sentinal EoF token to the end of the list.
1577 TokenVector.push_back(EoF);
1578 // We must allocate this array with new because EnterTokenStream is going to
1580 Token *TokenArray = new Token[TokenVector.size()];
1581 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray);
1582 auto Value = new (PP.getPreprocessorAllocator())
1583 std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
1584 AnnotTok.setAnnotationValue(Value);
1585 PP.EnterToken(AnnotTok);
1588 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
1592 /// #pragma detect_mismatch("name", "value")
1594 /// Where 'name' and 'value' are quoted strings. The values are embedded in
1595 /// the object file and passed along to the linker. If the linker detects a
1596 /// mismatch in the object file's values for the given name, a LNK2038 error
1597 /// is emitted. See MSDN for more details.
1598 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
1599 PragmaIntroducerKind Introducer,
1601 SourceLocation CommentLoc = Tok.getLocation();
1603 if (Tok.isNot(tok::l_paren)) {
1604 PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
1608 // Read the name to embed, which must be a string literal.
1609 std::string NameString;
1610 if (!PP.LexStringLiteral(Tok, NameString,
1611 "pragma detect_mismatch",
1612 /*MacroExpansion=*/true))
1615 // Read the comma followed by a second string literal.
1616 std::string ValueString;
1617 if (Tok.isNot(tok::comma)) {
1618 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1622 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
1623 /*MacroExpansion=*/true))
1626 if (Tok.isNot(tok::r_paren)) {
1627 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1630 PP.Lex(Tok); // Eat the r_paren.
1632 if (Tok.isNot(tok::eod)) {
1633 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1637 // If the pragma is lexically sound, notify any interested PPCallbacks.
1638 if (PP.getPPCallbacks())
1639 PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString,
1642 Actions.ActOnPragmaDetectMismatch(NameString, ValueString);
1645 /// \brief Handle the microsoft \#pragma comment extension.
1649 /// #pragma comment(linker, "foo")
1651 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
1652 /// "foo" is a string, which is fully macro expanded, and permits string
1653 /// concatenation, embedded escape characters etc. See MSDN for more details.
1654 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
1655 PragmaIntroducerKind Introducer,
1657 SourceLocation CommentLoc = Tok.getLocation();
1659 if (Tok.isNot(tok::l_paren)) {
1660 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1664 // Read the identifier.
1666 if (Tok.isNot(tok::identifier)) {
1667 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1671 // Verify that this is one of the 5 whitelisted options.
1672 IdentifierInfo *II = Tok.getIdentifierInfo();
1673 Sema::PragmaMSCommentKind Kind =
1674 llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())
1675 .Case("linker", Sema::PCK_Linker)
1676 .Case("lib", Sema::PCK_Lib)
1677 .Case("compiler", Sema::PCK_Compiler)
1678 .Case("exestr", Sema::PCK_ExeStr)
1679 .Case("user", Sema::PCK_User)
1680 .Default(Sema::PCK_Unknown);
1681 if (Kind == Sema::PCK_Unknown) {
1682 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
1686 // Read the optional string if present.
1688 std::string ArgumentString;
1689 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
1691 /*MacroExpansion=*/true))
1694 // FIXME: warn that 'exestr' is deprecated.
1695 // FIXME: If the kind is "compiler" warn if the string is present (it is
1697 // The MSDN docs say that "lib" and "linker" require a string and have a short
1698 // whitelist of linker options they support, but in practice MSVC doesn't
1699 // issue a diagnostic. Therefore neither does clang.
1701 if (Tok.isNot(tok::r_paren)) {
1702 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1705 PP.Lex(Tok); // eat the r_paren.
1707 if (Tok.isNot(tok::eod)) {
1708 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1712 // If the pragma is lexically sound, notify any interested PPCallbacks.
1713 if (PP.getPPCallbacks())
1714 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
1716 Actions.ActOnPragmaMSComment(Kind, ArgumentString);
1719 // #pragma clang optimize off
1720 // #pragma clang optimize on
1721 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
1722 PragmaIntroducerKind Introducer,
1723 Token &FirstToken) {
1726 if (Tok.is(tok::eod)) {
1727 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
1732 if (Tok.isNot(tok::identifier)) {
1733 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1734 << PP.getSpelling(Tok);
1737 const IdentifierInfo *II = Tok.getIdentifierInfo();
1738 // The only accepted values are 'on' or 'off'.
1740 if (II->isStr("on")) {
1742 } else if (!II->isStr("off")) {
1743 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1744 << PP.getSpelling(Tok);
1749 if (Tok.isNot(tok::eod)) {
1750 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
1751 << PP.getSpelling(Tok);
1755 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
1758 /// \brief Parses loop or unroll pragma hint value and fills in Info.
1759 static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
1760 Token &Option, bool &ValueInParens,
1761 PragmaLoopHintInfo &Info) {
1762 ValueInParens = Tok.is(tok::l_paren);
1763 if (ValueInParens) {
1765 if (Tok.is(tok::r_paren)) {
1766 // Nothing between the parentheses.
1767 std::string PragmaString;
1768 if (PragmaName.getIdentifierInfo()->getName() == "loop") {
1769 PragmaString = "clang loop ";
1770 PragmaString += Option.getIdentifierInfo()->getName();
1772 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
1773 "Unexpected pragma name");
1774 PragmaString = "unroll";
1776 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
1777 << PragmaString << "a positive integer value";
1782 // FIXME: Value should be stored and parsed as a constant expression.
1785 if (ValueInParens) {
1787 if (Tok.isNot(tok::r_paren)) {
1788 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1793 Info.PragmaName = PragmaName;
1794 Info.Option = Option;
1796 Info.HasValue = true;
1800 /// \brief Handle the \#pragma clang loop directive.
1801 /// #pragma clang 'loop' loop-hints
1804 /// loop-hint loop-hints[opt]
1807 /// 'vectorize' '(' loop-hint-keyword ')'
1808 /// 'interleave' '(' loop-hint-keyword ')'
1809 /// 'unroll' '(' loop-hint-keyword ')'
1810 /// 'vectorize_width' '(' loop-hint-value ')'
1811 /// 'interleave_count' '(' loop-hint-value ')'
1812 /// 'unroll_count' '(' loop-hint-value ')'
1814 /// loop-hint-keyword:
1818 /// loop-hint-value:
1819 /// constant-expression
1821 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
1822 /// try vectorizing the instructions of the loop it precedes. Specifying
1823 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
1824 /// interleaving multiple iterations of the loop it precedes. The width of the
1825 /// vector instructions is specified by vectorize_width() and the number of
1826 /// interleaved loop iterations is specified by interleave_count(). Specifying a
1827 /// value of 1 effectively disables vectorization/interleaving, even if it is
1828 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
1829 /// only works on inner loops.
1831 /// The unroll and unroll_count directives control the concatenation
1832 /// unroller. Specifying unroll(enable) instructs llvm to try to
1833 /// unroll the loop completely, and unroll(disable) disables unrolling
1834 /// for the loop. Specifying unroll_count(_value_) instructs llvm to
1835 /// try to unroll the loop the number of times indicated by the value.
1836 /// If unroll(enable) and unroll_count are both specified only
1837 /// unroll_count takes effect.
1838 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
1839 PragmaIntroducerKind Introducer,
1841 // Incoming token is "loop" from "#pragma clang loop".
1842 Token PragmaName = Tok;
1843 SmallVector<Token, 1> TokenList;
1845 // Lex the optimization option and verify it is an identifier.
1847 if (Tok.isNot(tok::identifier)) {
1848 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
1849 << /*MissingOption=*/true << "";
1853 while (Tok.is(tok::identifier)) {
1855 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
1857 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
1858 .Case("vectorize", true)
1859 .Case("interleave", true)
1860 .Case("unroll", true)
1861 .Case("vectorize_width", true)
1862 .Case("interleave_count", true)
1863 .Case("unroll_count", true)
1866 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
1867 << /*MissingOption=*/false << OptionInfo;
1871 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
1874 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
1877 if (!ValueInParens) {
1878 PP.Diag(Info->Value.getLocation(), diag::err_expected) << tok::l_paren;
1882 // Generate the loop hint token.
1884 LoopHintTok.startToken();
1885 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
1886 LoopHintTok.setLocation(PragmaName.getLocation());
1887 LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
1888 TokenList.push_back(LoopHintTok);
1890 // Get next optimization option.
1894 if (Tok.isNot(tok::eod)) {
1895 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1900 Token *TokenArray = new Token[TokenList.size()];
1901 std::copy(TokenList.begin(), TokenList.end(), TokenArray);
1903 PP.EnterTokenStream(TokenArray, TokenList.size(),
1904 /*DisableMacroExpansion=*/false,
1905 /*OwnsTokens=*/true);
1908 /// \brief Handle the loop unroll optimization pragmas.
1910 /// #pragma unroll unroll-hint-value
1911 /// #pragma unroll '(' unroll-hint-value ')'
1913 /// unroll-hint-value:
1914 /// constant-expression
1916 /// Loop unrolling hints are specified with '#pragma unroll'. '#pragma unroll'
1917 /// can take a numeric argument optionally contained in parentheses. With no
1918 /// argument the directive instructs llvm to try to unroll the loop
1919 /// completely. A positive integer argument can be specified to indicate the
1920 /// number of times the loop should be unrolled. To maximize compatibility with
1921 /// other compilers the unroll count argument can be specified with or without
1923 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
1924 PragmaIntroducerKind Introducer,
1926 // Incoming token is "unroll" of "#pragma unroll".
1927 Token PragmaName = Tok;
1929 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
1930 if (Tok.is(tok::eod)) {
1931 // Unroll pragma without an argument.
1932 Info->PragmaName = PragmaName;
1933 Info->Option = PragmaName;
1934 Info->HasValue = false;
1936 // Unroll pragma with an argument: "#pragma unroll N" or
1937 // "#pragma unroll(N)".
1939 if (ParseLoopHintValue(PP, Tok, PragmaName, PragmaName, ValueInParens,
1943 // In CUDA, the argument to '#pragma unroll' should not be contained in
1945 if (PP.getLangOpts().CUDA && ValueInParens)
1946 PP.Diag(Info->Value.getLocation(),
1947 diag::warn_pragma_unroll_cuda_value_in_parens);
1950 if (Tok.isNot(tok::eod)) {
1951 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1957 // Generate the hint token.
1958 Token *TokenArray = new Token[1];
1959 TokenArray[0].startToken();
1960 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
1961 TokenArray[0].setLocation(PragmaName.getLocation());
1962 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
1963 PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false,
1964 /*OwnsTokens=*/true);