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 "ParsePragma.h"
15 #include "clang/Lex/Preprocessor.h"
16 #include "clang/Parse/ParseDiagnostic.h"
17 #include "clang/Parse/Parser.h"
18 #include "clang/Sema/Scope.h"
19 #include "llvm/ADT/StringSwitch.h"
20 using namespace clang;
22 /// \brief Handle the annotation token produced for #pragma unused(...)
24 /// Each annot_pragma_unused is followed by the argument token so e.g.
25 /// "#pragma unused(x,y)" becomes:
26 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
27 void Parser::HandlePragmaUnused() {
28 assert(Tok.is(tok::annot_pragma_unused));
29 SourceLocation UnusedLoc = ConsumeToken();
30 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
31 ConsumeToken(); // The argument token.
34 void Parser::HandlePragmaVisibility() {
35 assert(Tok.is(tok::annot_pragma_vis));
36 const IdentifierInfo *VisType =
37 static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
38 SourceLocation VisLoc = ConsumeToken();
39 Actions.ActOnPragmaVisibility(VisType, VisLoc);
42 struct PragmaPackInfo {
43 Sema::PragmaPackKind Kind;
46 SourceLocation LParenLoc;
47 SourceLocation RParenLoc;
50 void Parser::HandlePragmaPack() {
51 assert(Tok.is(tok::annot_pragma_pack));
52 PragmaPackInfo *Info =
53 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
54 SourceLocation PragmaLoc = ConsumeToken();
56 if (Info->Alignment.is(tok::numeric_constant)) {
57 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
58 if (Alignment.isInvalid())
61 Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
62 Info->LParenLoc, Info->RParenLoc);
65 void Parser::HandlePragmaMSStruct() {
66 assert(Tok.is(tok::annot_pragma_msstruct));
67 Sema::PragmaMSStructKind Kind =
68 static_cast<Sema::PragmaMSStructKind>(
69 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
70 Actions.ActOnPragmaMSStruct(Kind);
71 ConsumeToken(); // The annotation token.
74 void Parser::HandlePragmaAlign() {
75 assert(Tok.is(tok::annot_pragma_align));
76 Sema::PragmaOptionsAlignKind Kind =
77 static_cast<Sema::PragmaOptionsAlignKind>(
78 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
79 SourceLocation PragmaLoc = ConsumeToken();
80 Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
83 void Parser::HandlePragmaWeak() {
84 assert(Tok.is(tok::annot_pragma_weak));
85 SourceLocation PragmaLoc = ConsumeToken();
86 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
88 ConsumeToken(); // The weak name.
91 void Parser::HandlePragmaWeakAlias() {
92 assert(Tok.is(tok::annot_pragma_weakalias));
93 SourceLocation PragmaLoc = ConsumeToken();
94 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
95 SourceLocation WeakNameLoc = Tok.getLocation();
97 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
98 SourceLocation AliasNameLoc = Tok.getLocation();
100 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
101 WeakNameLoc, AliasNameLoc);
105 void Parser::HandlePragmaRedefineExtname() {
106 assert(Tok.is(tok::annot_pragma_redefine_extname));
107 SourceLocation RedefLoc = ConsumeToken();
108 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
109 SourceLocation RedefNameLoc = Tok.getLocation();
111 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
112 SourceLocation AliasNameLoc = Tok.getLocation();
114 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
115 RedefNameLoc, AliasNameLoc);
118 void Parser::HandlePragmaFPContract() {
119 assert(Tok.is(tok::annot_pragma_fp_contract));
120 tok::OnOffSwitch OOS =
121 static_cast<tok::OnOffSwitch>(
122 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
123 Actions.ActOnPragmaFPContract(OOS);
124 ConsumeToken(); // The annotation token.
127 StmtResult Parser::HandlePragmaCaptured()
129 assert(Tok.is(tok::annot_pragma_captured));
132 if (Tok.isNot(tok::l_brace)) {
133 PP.Diag(Tok, diag::err_expected_lbrace);
137 SourceLocation Loc = Tok.getLocation();
139 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
140 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
143 StmtResult R = ParseCompoundStatement();
144 CapturedRegionScope.Exit();
147 Actions.ActOnCapturedRegionError();
151 return Actions.ActOnCapturedRegionEnd(R.get());
155 typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
158 void Parser::HandlePragmaOpenCLExtension() {
159 assert(Tok.is(tok::annot_pragma_opencl_extension));
161 OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
162 unsigned state = data.getInt();
163 IdentifierInfo *ename = data.getPointer();
164 SourceLocation NameLoc = Tok.getLocation();
165 ConsumeToken(); // The annotation token.
167 OpenCLOptions &f = Actions.getOpenCLOptions();
168 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
169 // overriding all previously issued extension directives, but only if the
170 // behavior is set to disable."
171 if (state == 0 && ename->isStr("all")) {
172 #define OPENCLEXT(nm) f.nm = 0;
173 #include "clang/Basic/OpenCLExtensions.def"
175 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
176 #include "clang/Basic/OpenCLExtensions.def"
178 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
185 // #pragma GCC visibility comes in two variants:
186 // 'push' '(' [visibility] ')'
188 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
189 PragmaIntroducerKind Introducer,
191 SourceLocation VisLoc = VisTok.getLocation();
194 PP.LexUnexpandedToken(Tok);
196 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
198 const IdentifierInfo *VisType;
199 if (PushPop && PushPop->isStr("pop")) {
201 } else if (PushPop && PushPop->isStr("push")) {
202 PP.LexUnexpandedToken(Tok);
203 if (Tok.isNot(tok::l_paren)) {
204 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
208 PP.LexUnexpandedToken(Tok);
209 VisType = Tok.getIdentifierInfo();
211 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
215 PP.LexUnexpandedToken(Tok);
216 if (Tok.isNot(tok::r_paren)) {
217 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
222 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
226 PP.LexUnexpandedToken(Tok);
227 if (Tok.isNot(tok::eod)) {
228 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
233 Token *Toks = new Token[1];
234 Toks[0].startToken();
235 Toks[0].setKind(tok::annot_pragma_vis);
236 Toks[0].setLocation(VisLoc);
237 Toks[0].setAnnotationValue(
238 const_cast<void*>(static_cast<const void*>(VisType)));
239 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
240 /*OwnsTokens=*/true);
243 // #pragma pack(...) comes in the following delicious flavors:
244 // pack '(' [integer] ')'
245 // pack '(' 'show' ')'
246 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
247 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
248 PragmaIntroducerKind Introducer,
250 SourceLocation PackLoc = PackTok.getLocation();
254 if (Tok.isNot(tok::l_paren)) {
255 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
259 Sema::PragmaPackKind Kind = Sema::PPK_Default;
260 IdentifierInfo *Name = 0;
262 Alignment.startToken();
263 SourceLocation LParenLoc = Tok.getLocation();
265 if (Tok.is(tok::numeric_constant)) {
270 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
271 // the push/pop stack.
272 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
273 if (PP.getLangOpts().ApplePragmaPack)
274 Kind = Sema::PPK_Push;
275 } else if (Tok.is(tok::identifier)) {
276 const IdentifierInfo *II = Tok.getIdentifierInfo();
277 if (II->isStr("show")) {
278 Kind = Sema::PPK_Show;
281 if (II->isStr("push")) {
282 Kind = Sema::PPK_Push;
283 } else if (II->isStr("pop")) {
284 Kind = Sema::PPK_Pop;
286 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
291 if (Tok.is(tok::comma)) {
294 if (Tok.is(tok::numeric_constant)) {
298 } else if (Tok.is(tok::identifier)) {
299 Name = Tok.getIdentifierInfo();
302 if (Tok.is(tok::comma)) {
305 if (Tok.isNot(tok::numeric_constant)) {
306 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
315 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
320 } else if (PP.getLangOpts().ApplePragmaPack) {
321 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
322 // the push/pop stack.
323 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
324 Kind = Sema::PPK_Pop;
327 if (Tok.isNot(tok::r_paren)) {
328 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
332 SourceLocation RParenLoc = Tok.getLocation();
334 if (Tok.isNot(tok::eod)) {
335 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
339 PragmaPackInfo *Info =
340 (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
341 sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
342 new (Info) PragmaPackInfo();
345 Info->Alignment = Alignment;
346 Info->LParenLoc = LParenLoc;
347 Info->RParenLoc = RParenLoc;
350 (Token*) PP.getPreprocessorAllocator().Allocate(
351 sizeof(Token) * 1, llvm::alignOf<Token>());
353 Toks[0].startToken();
354 Toks[0].setKind(tok::annot_pragma_pack);
355 Toks[0].setLocation(PackLoc);
356 Toks[0].setAnnotationValue(static_cast<void*>(Info));
357 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
358 /*OwnsTokens=*/false);
361 // #pragma ms_struct on
362 // #pragma ms_struct off
363 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
364 PragmaIntroducerKind Introducer,
365 Token &MSStructTok) {
366 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
370 if (Tok.isNot(tok::identifier)) {
371 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
374 const IdentifierInfo *II = Tok.getIdentifierInfo();
375 if (II->isStr("on")) {
376 Kind = Sema::PMSST_ON;
379 else if (II->isStr("off") || II->isStr("reset"))
382 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
386 if (Tok.isNot(tok::eod)) {
387 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
393 (Token*) PP.getPreprocessorAllocator().Allocate(
394 sizeof(Token) * 1, llvm::alignOf<Token>());
396 Toks[0].startToken();
397 Toks[0].setKind(tok::annot_pragma_msstruct);
398 Toks[0].setLocation(MSStructTok.getLocation());
399 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
400 static_cast<uintptr_t>(Kind)));
401 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
402 /*OwnsTokens=*/false);
405 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
406 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
407 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
413 if (Tok.isNot(tok::identifier) ||
414 !Tok.getIdentifierInfo()->isStr("align")) {
415 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
421 if (Tok.isNot(tok::equal)) {
422 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
428 if (Tok.isNot(tok::identifier)) {
429 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
430 << (IsOptions ? "options" : "align");
434 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
435 const IdentifierInfo *II = Tok.getIdentifierInfo();
436 if (II->isStr("native"))
437 Kind = Sema::POAK_Native;
438 else if (II->isStr("natural"))
439 Kind = Sema::POAK_Natural;
440 else if (II->isStr("packed"))
441 Kind = Sema::POAK_Packed;
442 else if (II->isStr("power"))
443 Kind = Sema::POAK_Power;
444 else if (II->isStr("mac68k"))
445 Kind = Sema::POAK_Mac68k;
446 else if (II->isStr("reset"))
447 Kind = Sema::POAK_Reset;
449 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
455 if (Tok.isNot(tok::eod)) {
456 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
457 << (IsOptions ? "options" : "align");
462 (Token*) PP.getPreprocessorAllocator().Allocate(
463 sizeof(Token) * 1, llvm::alignOf<Token>());
465 Toks[0].startToken();
466 Toks[0].setKind(tok::annot_pragma_align);
467 Toks[0].setLocation(FirstTok.getLocation());
468 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
469 static_cast<uintptr_t>(Kind)));
470 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
471 /*OwnsTokens=*/false);
474 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
475 PragmaIntroducerKind Introducer,
477 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
480 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
481 PragmaIntroducerKind Introducer,
483 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
486 // #pragma unused(identifier)
487 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
488 PragmaIntroducerKind Introducer,
490 // FIXME: Should we be expanding macros here? My guess is no.
491 SourceLocation UnusedLoc = UnusedTok.getLocation();
496 if (Tok.isNot(tok::l_paren)) {
497 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
501 // Lex the declaration reference(s).
502 SmallVector<Token, 5> Identifiers;
503 SourceLocation RParenLoc;
510 if (Tok.is(tok::identifier)) {
511 Identifiers.push_back(Tok);
517 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
521 // We are execting a ')' or a ','.
522 if (Tok.is(tok::comma)) {
527 if (Tok.is(tok::r_paren)) {
528 RParenLoc = Tok.getLocation();
533 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
538 if (Tok.isNot(tok::eod)) {
539 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
544 // Verify that we have a location for the right parenthesis.
545 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
546 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
548 // For each identifier token, insert into the token stream a
549 // annot_pragma_unused token followed by the identifier token.
550 // This allows us to cache a "#pragma unused" that occurs inside an inline
551 // C++ member function.
554 (Token*) PP.getPreprocessorAllocator().Allocate(
555 sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
556 for (unsigned i=0; i != Identifiers.size(); i++) {
557 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
558 pragmaUnusedTok.startToken();
559 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
560 pragmaUnusedTok.setLocation(UnusedLoc);
561 idTok = Identifiers[i];
563 PP.EnterTokenStream(Toks, 2*Identifiers.size(),
564 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
567 // #pragma weak identifier
568 // #pragma weak identifier '=' identifier
569 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
570 PragmaIntroducerKind Introducer,
572 SourceLocation WeakLoc = WeakTok.getLocation();
576 if (Tok.isNot(tok::identifier)) {
577 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
581 Token WeakName = Tok;
582 bool HasAlias = false;
586 if (Tok.is(tok::equal)) {
589 if (Tok.isNot(tok::identifier)) {
590 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
598 if (Tok.isNot(tok::eod)) {
599 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
605 (Token*) PP.getPreprocessorAllocator().Allocate(
606 sizeof(Token) * 3, llvm::alignOf<Token>());
607 Token &pragmaUnusedTok = Toks[0];
608 pragmaUnusedTok.startToken();
609 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
610 pragmaUnusedTok.setLocation(WeakLoc);
613 PP.EnterTokenStream(Toks, 3,
614 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
617 (Token*) PP.getPreprocessorAllocator().Allocate(
618 sizeof(Token) * 2, llvm::alignOf<Token>());
619 Token &pragmaUnusedTok = Toks[0];
620 pragmaUnusedTok.startToken();
621 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
622 pragmaUnusedTok.setLocation(WeakLoc);
624 PP.EnterTokenStream(Toks, 2,
625 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
629 // #pragma redefine_extname identifier identifier
630 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
631 PragmaIntroducerKind Introducer,
633 SourceLocation RedefLoc = RedefToken.getLocation();
637 if (Tok.isNot(tok::identifier)) {
638 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
643 Token RedefName = Tok;
646 if (Tok.isNot(tok::identifier)) {
647 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
648 << "redefine_extname";
652 Token AliasName = Tok;
655 if (Tok.isNot(tok::eod)) {
656 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
662 (Token*) PP.getPreprocessorAllocator().Allocate(
663 sizeof(Token) * 3, llvm::alignOf<Token>());
664 Token &pragmaRedefTok = Toks[0];
665 pragmaRedefTok.startToken();
666 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
667 pragmaRedefTok.setLocation(RedefLoc);
670 PP.EnterTokenStream(Toks, 3,
671 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
676 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
677 PragmaIntroducerKind Introducer,
679 tok::OnOffSwitch OOS;
680 if (PP.LexOnOffSwitch(OOS))
684 (Token*) PP.getPreprocessorAllocator().Allocate(
685 sizeof(Token) * 1, llvm::alignOf<Token>());
687 Toks[0].startToken();
688 Toks[0].setKind(tok::annot_pragma_fp_contract);
689 Toks[0].setLocation(Tok.getLocation());
690 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
691 static_cast<uintptr_t>(OOS)));
692 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
693 /*OwnsTokens=*/false);
697 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
698 PragmaIntroducerKind Introducer,
700 PP.LexUnexpandedToken(Tok);
701 if (Tok.isNot(tok::identifier)) {
702 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
706 IdentifierInfo *ename = Tok.getIdentifierInfo();
707 SourceLocation NameLoc = Tok.getLocation();
710 if (Tok.isNot(tok::colon)) {
711 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
716 if (Tok.isNot(tok::identifier)) {
717 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
720 IdentifierInfo *op = Tok.getIdentifierInfo();
723 if (op->isStr("enable")) {
725 } else if (op->isStr("disable")) {
728 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
731 SourceLocation StateLoc = Tok.getLocation();
734 if (Tok.isNot(tok::eod)) {
735 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
740 OpenCLExtData data(ename, state);
742 (Token*) PP.getPreprocessorAllocator().Allocate(
743 sizeof(Token) * 1, llvm::alignOf<Token>());
745 Toks[0].startToken();
746 Toks[0].setKind(tok::annot_pragma_opencl_extension);
747 Toks[0].setLocation(NameLoc);
748 Toks[0].setAnnotationValue(data.getOpaqueValue());
749 PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
750 /*OwnsTokens=*/false);
752 if (PP.getPPCallbacks())
753 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename,
757 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
760 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
761 PragmaIntroducerKind Introducer,
763 if (PP.getDiagnostics().getDiagnosticLevel(diag::warn_pragma_omp_ignored,
764 FirstTok.getLocation()) !=
765 DiagnosticsEngine::Ignored) {
766 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
767 PP.getDiagnostics().setDiagnosticMapping(diag::warn_pragma_omp_ignored,
771 PP.DiscardUntilEndOfDirective();
774 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
777 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
778 PragmaIntroducerKind Introducer,
780 SmallVector<Token, 16> Pragma;
783 Tok.setKind(tok::annot_pragma_openmp);
784 Tok.setLocation(FirstTok.getLocation());
786 while (Tok.isNot(tok::eod)) {
787 Pragma.push_back(Tok);
790 SourceLocation EodLoc = Tok.getLocation();
792 Tok.setKind(tok::annot_pragma_openmp_end);
793 Tok.setLocation(EodLoc);
794 Pragma.push_back(Tok);
796 Token *Toks = new Token[Pragma.size()];
797 std::copy(Pragma.begin(), Pragma.end(), Toks);
798 PP.EnterTokenStream(Toks, Pragma.size(),
799 /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
802 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
806 /// #pragma detect_mismatch("name", "value")
808 /// Where 'name' and 'value' are quoted strings. The values are embedded in
809 /// the object file and passed along to the linker. If the linker detects a
810 /// mismatch in the object file's values for the given name, a LNK2038 error
811 /// is emitted. See MSDN for more details.
812 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
813 PragmaIntroducerKind Introducer,
815 SourceLocation CommentLoc = Tok.getLocation();
817 if (Tok.isNot(tok::l_paren)) {
818 PP.Diag(CommentLoc, diag::err_expected_lparen);
822 // Read the name to embed, which must be a string literal.
823 std::string NameString;
824 if (!PP.LexStringLiteral(Tok, NameString,
825 "pragma detect_mismatch",
826 /*MacroExpansion=*/true))
829 // Read the comma followed by a second string literal.
830 std::string ValueString;
831 if (Tok.isNot(tok::comma)) {
832 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
836 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
837 /*MacroExpansion=*/true))
840 if (Tok.isNot(tok::r_paren)) {
841 PP.Diag(Tok.getLocation(), diag::err_expected_rparen);
844 PP.Lex(Tok); // Eat the r_paren.
846 if (Tok.isNot(tok::eod)) {
847 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
851 // If the pragma is lexically sound, notify any interested PPCallbacks.
852 if (PP.getPPCallbacks())
853 PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString,
856 Actions.ActOnPragmaDetectMismatch(NameString, ValueString);
859 /// \brief Handle the microsoft \#pragma comment extension.
863 /// #pragma comment(linker, "foo")
865 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
866 /// "foo" is a string, which is fully macro expanded, and permits string
867 /// concatenation, embedded escape characters etc. See MSDN for more details.
868 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
869 PragmaIntroducerKind Introducer,
871 SourceLocation CommentLoc = Tok.getLocation();
873 if (Tok.isNot(tok::l_paren)) {
874 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
878 // Read the identifier.
880 if (Tok.isNot(tok::identifier)) {
881 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
885 // Verify that this is one of the 5 whitelisted options.
886 IdentifierInfo *II = Tok.getIdentifierInfo();
887 Sema::PragmaMSCommentKind Kind =
888 llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())
889 .Case("linker", Sema::PCK_Linker)
890 .Case("lib", Sema::PCK_Lib)
891 .Case("compiler", Sema::PCK_Compiler)
892 .Case("exestr", Sema::PCK_ExeStr)
893 .Case("user", Sema::PCK_User)
894 .Default(Sema::PCK_Unknown);
895 if (Kind == Sema::PCK_Unknown) {
896 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
900 // Read the optional string if present.
902 std::string ArgumentString;
903 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
905 /*MacroExpansion=*/true))
908 // FIXME: warn that 'exestr' is deprecated.
909 // FIXME: If the kind is "compiler" warn if the string is present (it is
911 // The MSDN docs say that "lib" and "linker" require a string and have a short
912 // whitelist of linker options they support, but in practice MSVC doesn't
913 // issue a diagnostic. Therefore neither does clang.
915 if (Tok.isNot(tok::r_paren)) {
916 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
919 PP.Lex(Tok); // eat the r_paren.
921 if (Tok.isNot(tok::eod)) {
922 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
926 // If the pragma is lexically sound, notify any interested PPCallbacks.
927 if (PP.getPPCallbacks())
928 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
930 Actions.ActOnPragmaMSComment(Kind, ArgumentString);