Home | History | Annotate | Download | only in Parse
      1 //===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the language specific #pragma handlers.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "ParsePragma.h"
     15 #include "clang/Lex/Preprocessor.h"
     16 #include "clang/Parse/ParseDiagnostic.h"
     17 #include "clang/Parse/Parser.h"
     18 using namespace clang;
     19 
     20 /// \brief Handle the annotation token produced for #pragma unused(...)
     21 ///
     22 /// Each annot_pragma_unused is followed by the argument token so e.g.
     23 /// "#pragma unused(x,y)" becomes:
     24 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
     25 void Parser::HandlePragmaUnused() {
     26   assert(Tok.is(tok::annot_pragma_unused));
     27   SourceLocation UnusedLoc = ConsumeToken();
     28   Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
     29   ConsumeToken(); // The argument token.
     30 }
     31 
     32 void Parser::HandlePragmaVisibility() {
     33   assert(Tok.is(tok::annot_pragma_vis));
     34   const IdentifierInfo *VisType =
     35     static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
     36   SourceLocation VisLoc = ConsumeToken();
     37   Actions.ActOnPragmaVisibility(VisType, VisLoc);
     38 }
     39 
     40 struct PragmaPackInfo {
     41   Sema::PragmaPackKind Kind;
     42   IdentifierInfo *Name;
     43   Token Alignment;
     44   SourceLocation LParenLoc;
     45   SourceLocation RParenLoc;
     46 };
     47 
     48 void Parser::HandlePragmaPack() {
     49   assert(Tok.is(tok::annot_pragma_pack));
     50   PragmaPackInfo *Info =
     51     static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
     52   SourceLocation PragmaLoc = ConsumeToken();
     53   ExprResult Alignment;
     54   if (Info->Alignment.is(tok::numeric_constant)) {
     55     Alignment = Actions.ActOnNumericConstant(Info->Alignment);
     56     if (Alignment.isInvalid())
     57       return;
     58   }
     59   Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
     60                           Info->LParenLoc, Info->RParenLoc);
     61 }
     62 
     63 void Parser::HandlePragmaMSStruct() {
     64   assert(Tok.is(tok::annot_pragma_msstruct));
     65   Sema::PragmaMSStructKind Kind =
     66     static_cast<Sema::PragmaMSStructKind>(
     67     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
     68   Actions.ActOnPragmaMSStruct(Kind);
     69   ConsumeToken(); // The annotation token.
     70 }
     71 
     72 void Parser::HandlePragmaAlign() {
     73   assert(Tok.is(tok::annot_pragma_align));
     74   Sema::PragmaOptionsAlignKind Kind =
     75     static_cast<Sema::PragmaOptionsAlignKind>(
     76     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
     77   SourceLocation PragmaLoc = ConsumeToken();
     78   Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
     79 }
     80 
     81 void Parser::HandlePragmaWeak() {
     82   assert(Tok.is(tok::annot_pragma_weak));
     83   SourceLocation PragmaLoc = ConsumeToken();
     84   Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
     85                             Tok.getLocation());
     86   ConsumeToken(); // The weak name.
     87 }
     88 
     89 void Parser::HandlePragmaWeakAlias() {
     90   assert(Tok.is(tok::annot_pragma_weakalias));
     91   SourceLocation PragmaLoc = ConsumeToken();
     92   IdentifierInfo *WeakName = Tok.getIdentifierInfo();
     93   SourceLocation WeakNameLoc = Tok.getLocation();
     94   ConsumeToken();
     95   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
     96   SourceLocation AliasNameLoc = Tok.getLocation();
     97   ConsumeToken();
     98   Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
     99                                WeakNameLoc, AliasNameLoc);
    100 
    101 }
    102 
    103 void Parser::HandlePragmaRedefineExtname() {
    104   assert(Tok.is(tok::annot_pragma_redefine_extname));
    105   SourceLocation RedefLoc = ConsumeToken();
    106   IdentifierInfo *RedefName = Tok.getIdentifierInfo();
    107   SourceLocation RedefNameLoc = Tok.getLocation();
    108   ConsumeToken();
    109   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
    110   SourceLocation AliasNameLoc = Tok.getLocation();
    111   ConsumeToken();
    112   Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
    113                                      RedefNameLoc, AliasNameLoc);
    114 }
    115 
    116 void Parser::HandlePragmaFPContract() {
    117   assert(Tok.is(tok::annot_pragma_fp_contract));
    118   tok::OnOffSwitch OOS =
    119     static_cast<tok::OnOffSwitch>(
    120     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
    121   Actions.ActOnPragmaFPContract(OOS);
    122   ConsumeToken(); // The annotation token.
    123 }
    124 
    125 namespace {
    126   typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
    127 }
    128 
    129 void Parser::HandlePragmaOpenCLExtension() {
    130   assert(Tok.is(tok::annot_pragma_opencl_extension));
    131   OpenCLExtData data =
    132       OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
    133   unsigned state = data.getInt();
    134   IdentifierInfo *ename = data.getPointer();
    135   SourceLocation NameLoc = Tok.getLocation();
    136   ConsumeToken(); // The annotation token.
    137 
    138   OpenCLOptions &f = Actions.getOpenCLOptions();
    139   // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
    140   // overriding all previously issued extension directives, but only if the
    141   // behavior is set to disable."
    142   if (state == 0 && ename->isStr("all")) {
    143 #define OPENCLEXT(nm)   f.nm = 0;
    144 #include "clang/Basic/OpenCLExtensions.def"
    145   }
    146 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
    147 #include "clang/Basic/OpenCLExtensions.def"
    148   else {
    149     PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
    150     return;
    151   }
    152 }
    153 
    154 // #pragma GCC visibility comes in two variants:
    155 //   'push' '(' [visibility] ')'
    156 //   'pop'
    157 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
    158                                               PragmaIntroducerKind Introducer,
    159                                               Token &VisTok) {
    160   SourceLocation VisLoc = VisTok.getLocation();
    161 
    162   Token Tok;
    163   PP.LexUnexpandedToken(Tok);
    164 
    165   const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
    166 
    167   const IdentifierInfo *VisType;
    168   if (PushPop && PushPop->isStr("pop")) {
    169     VisType = 0;
    170   } else if (PushPop && PushPop->isStr("push")) {
    171     PP.LexUnexpandedToken(Tok);
    172     if (Tok.isNot(tok::l_paren)) {
    173       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
    174         << "visibility";
    175       return;
    176     }
    177     PP.LexUnexpandedToken(Tok);
    178     VisType = Tok.getIdentifierInfo();
    179     if (!VisType) {
    180       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    181         << "visibility";
    182       return;
    183     }
    184     PP.LexUnexpandedToken(Tok);
    185     if (Tok.isNot(tok::r_paren)) {
    186       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
    187         << "visibility";
    188       return;
    189     }
    190   } else {
    191     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    192       << "visibility";
    193     return;
    194   }
    195   PP.LexUnexpandedToken(Tok);
    196   if (Tok.isNot(tok::eod)) {
    197     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
    198       << "visibility";
    199     return;
    200   }
    201 
    202   Token *Toks = new Token[1];
    203   Toks[0].startToken();
    204   Toks[0].setKind(tok::annot_pragma_vis);
    205   Toks[0].setLocation(VisLoc);
    206   Toks[0].setAnnotationValue(
    207                           const_cast<void*>(static_cast<const void*>(VisType)));
    208   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    209                       /*OwnsTokens=*/true);
    210 }
    211 
    212 // #pragma pack(...) comes in the following delicious flavors:
    213 //   pack '(' [integer] ')'
    214 //   pack '(' 'show' ')'
    215 //   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
    216 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
    217                                      PragmaIntroducerKind Introducer,
    218                                      Token &PackTok) {
    219   SourceLocation PackLoc = PackTok.getLocation();
    220 
    221   Token Tok;
    222   PP.Lex(Tok);
    223   if (Tok.isNot(tok::l_paren)) {
    224     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
    225     return;
    226   }
    227 
    228   Sema::PragmaPackKind Kind = Sema::PPK_Default;
    229   IdentifierInfo *Name = 0;
    230   Token Alignment;
    231   Alignment.startToken();
    232   SourceLocation LParenLoc = Tok.getLocation();
    233   PP.Lex(Tok);
    234   if (Tok.is(tok::numeric_constant)) {
    235     Alignment = Tok;
    236 
    237     PP.Lex(Tok);
    238 
    239     // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
    240     // the push/pop stack.
    241     // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
    242     if (PP.getLangOpts().ApplePragmaPack)
    243       Kind = Sema::PPK_Push;
    244   } else if (Tok.is(tok::identifier)) {
    245     const IdentifierInfo *II = Tok.getIdentifierInfo();
    246     if (II->isStr("show")) {
    247       Kind = Sema::PPK_Show;
    248       PP.Lex(Tok);
    249     } else {
    250       if (II->isStr("push")) {
    251         Kind = Sema::PPK_Push;
    252       } else if (II->isStr("pop")) {
    253         Kind = Sema::PPK_Pop;
    254       } else {
    255         PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
    256         return;
    257       }
    258       PP.Lex(Tok);
    259 
    260       if (Tok.is(tok::comma)) {
    261         PP.Lex(Tok);
    262 
    263         if (Tok.is(tok::numeric_constant)) {
    264           Alignment = Tok;
    265 
    266           PP.Lex(Tok);
    267         } else if (Tok.is(tok::identifier)) {
    268           Name = Tok.getIdentifierInfo();
    269           PP.Lex(Tok);
    270 
    271           if (Tok.is(tok::comma)) {
    272             PP.Lex(Tok);
    273 
    274             if (Tok.isNot(tok::numeric_constant)) {
    275               PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
    276               return;
    277             }
    278 
    279             Alignment = Tok;
    280 
    281             PP.Lex(Tok);
    282           }
    283         } else {
    284           PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
    285           return;
    286         }
    287       }
    288     }
    289   } else if (PP.getLangOpts().ApplePragmaPack) {
    290     // In MSVC/gcc, #pragma pack() resets the alignment without affecting
    291     // the push/pop stack.
    292     // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
    293     Kind = Sema::PPK_Pop;
    294   }
    295 
    296   if (Tok.isNot(tok::r_paren)) {
    297     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
    298     return;
    299   }
    300 
    301   SourceLocation RParenLoc = Tok.getLocation();
    302   PP.Lex(Tok);
    303   if (Tok.isNot(tok::eod)) {
    304     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
    305     return;
    306   }
    307 
    308   PragmaPackInfo *Info =
    309     (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
    310       sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
    311   new (Info) PragmaPackInfo();
    312   Info->Kind = Kind;
    313   Info->Name = Name;
    314   Info->Alignment = Alignment;
    315   Info->LParenLoc = LParenLoc;
    316   Info->RParenLoc = RParenLoc;
    317 
    318   Token *Toks =
    319     (Token*) PP.getPreprocessorAllocator().Allocate(
    320       sizeof(Token) * 1, llvm::alignOf<Token>());
    321   new (Toks) Token();
    322   Toks[0].startToken();
    323   Toks[0].setKind(tok::annot_pragma_pack);
    324   Toks[0].setLocation(PackLoc);
    325   Toks[0].setAnnotationValue(static_cast<void*>(Info));
    326   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    327                       /*OwnsTokens=*/false);
    328 }
    329 
    330 // #pragma ms_struct on
    331 // #pragma ms_struct off
    332 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
    333                                          PragmaIntroducerKind Introducer,
    334                                          Token &MSStructTok) {
    335   Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
    336 
    337   Token Tok;
    338   PP.Lex(Tok);
    339   if (Tok.isNot(tok::identifier)) {
    340     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
    341     return;
    342   }
    343   const IdentifierInfo *II = Tok.getIdentifierInfo();
    344   if (II->isStr("on")) {
    345     Kind = Sema::PMSST_ON;
    346     PP.Lex(Tok);
    347   }
    348   else if (II->isStr("off") || II->isStr("reset"))
    349     PP.Lex(Tok);
    350   else {
    351     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
    352     return;
    353   }
    354 
    355   if (Tok.isNot(tok::eod)) {
    356     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
    357       << "ms_struct";
    358     return;
    359   }
    360 
    361   Token *Toks =
    362     (Token*) PP.getPreprocessorAllocator().Allocate(
    363       sizeof(Token) * 1, llvm::alignOf<Token>());
    364   new (Toks) Token();
    365   Toks[0].startToken();
    366   Toks[0].setKind(tok::annot_pragma_msstruct);
    367   Toks[0].setLocation(MSStructTok.getLocation());
    368   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
    369                              static_cast<uintptr_t>(Kind)));
    370   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    371                       /*OwnsTokens=*/false);
    372 }
    373 
    374 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
    375 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
    376 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
    377                              bool IsOptions) {
    378   Token Tok;
    379 
    380   if (IsOptions) {
    381     PP.Lex(Tok);
    382     if (Tok.isNot(tok::identifier) ||
    383         !Tok.getIdentifierInfo()->isStr("align")) {
    384       PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
    385       return;
    386     }
    387   }
    388 
    389   PP.Lex(Tok);
    390   if (Tok.isNot(tok::equal)) {
    391     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
    392       << IsOptions;
    393     return;
    394   }
    395 
    396   PP.Lex(Tok);
    397   if (Tok.isNot(tok::identifier)) {
    398     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    399       << (IsOptions ? "options" : "align");
    400     return;
    401   }
    402 
    403   Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
    404   const IdentifierInfo *II = Tok.getIdentifierInfo();
    405   if (II->isStr("native"))
    406     Kind = Sema::POAK_Native;
    407   else if (II->isStr("natural"))
    408     Kind = Sema::POAK_Natural;
    409   else if (II->isStr("packed"))
    410     Kind = Sema::POAK_Packed;
    411   else if (II->isStr("power"))
    412     Kind = Sema::POAK_Power;
    413   else if (II->isStr("mac68k"))
    414     Kind = Sema::POAK_Mac68k;
    415   else if (II->isStr("reset"))
    416     Kind = Sema::POAK_Reset;
    417   else {
    418     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
    419       << IsOptions;
    420     return;
    421   }
    422 
    423   PP.Lex(Tok);
    424   if (Tok.isNot(tok::eod)) {
    425     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
    426       << (IsOptions ? "options" : "align");
    427     return;
    428   }
    429 
    430   Token *Toks =
    431     (Token*) PP.getPreprocessorAllocator().Allocate(
    432       sizeof(Token) * 1, llvm::alignOf<Token>());
    433   new (Toks) Token();
    434   Toks[0].startToken();
    435   Toks[0].setKind(tok::annot_pragma_align);
    436   Toks[0].setLocation(FirstTok.getLocation());
    437   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
    438                              static_cast<uintptr_t>(Kind)));
    439   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    440                       /*OwnsTokens=*/false);
    441 }
    442 
    443 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
    444                                       PragmaIntroducerKind Introducer,
    445                                       Token &AlignTok) {
    446   ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
    447 }
    448 
    449 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
    450                                         PragmaIntroducerKind Introducer,
    451                                         Token &OptionsTok) {
    452   ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
    453 }
    454 
    455 // #pragma unused(identifier)
    456 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
    457                                        PragmaIntroducerKind Introducer,
    458                                        Token &UnusedTok) {
    459   // FIXME: Should we be expanding macros here? My guess is no.
    460   SourceLocation UnusedLoc = UnusedTok.getLocation();
    461 
    462   // Lex the left '('.
    463   Token Tok;
    464   PP.Lex(Tok);
    465   if (Tok.isNot(tok::l_paren)) {
    466     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
    467     return;
    468   }
    469 
    470   // Lex the declaration reference(s).
    471   SmallVector<Token, 5> Identifiers;
    472   SourceLocation RParenLoc;
    473   bool LexID = true;
    474 
    475   while (true) {
    476     PP.Lex(Tok);
    477 
    478     if (LexID) {
    479       if (Tok.is(tok::identifier)) {
    480         Identifiers.push_back(Tok);
    481         LexID = false;
    482         continue;
    483       }
    484 
    485       // Illegal token!
    486       PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
    487       return;
    488     }
    489 
    490     // We are execting a ')' or a ','.
    491     if (Tok.is(tok::comma)) {
    492       LexID = true;
    493       continue;
    494     }
    495 
    496     if (Tok.is(tok::r_paren)) {
    497       RParenLoc = Tok.getLocation();
    498       break;
    499     }
    500 
    501     // Illegal token!
    502     PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
    503     return;
    504   }
    505 
    506   PP.Lex(Tok);
    507   if (Tok.isNot(tok::eod)) {
    508     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
    509         "unused";
    510     return;
    511   }
    512 
    513   // Verify that we have a location for the right parenthesis.
    514   assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
    515   assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
    516 
    517   // For each identifier token, insert into the token stream a
    518   // annot_pragma_unused token followed by the identifier token.
    519   // This allows us to cache a "#pragma unused" that occurs inside an inline
    520   // C++ member function.
    521 
    522   Token *Toks =
    523     (Token*) PP.getPreprocessorAllocator().Allocate(
    524       sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
    525   for (unsigned i=0; i != Identifiers.size(); i++) {
    526     Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
    527     pragmaUnusedTok.startToken();
    528     pragmaUnusedTok.setKind(tok::annot_pragma_unused);
    529     pragmaUnusedTok.setLocation(UnusedLoc);
    530     idTok = Identifiers[i];
    531   }
    532   PP.EnterTokenStream(Toks, 2*Identifiers.size(),
    533                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
    534 }
    535 
    536 // #pragma weak identifier
    537 // #pragma weak identifier '=' identifier
    538 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
    539                                      PragmaIntroducerKind Introducer,
    540                                      Token &WeakTok) {
    541   SourceLocation WeakLoc = WeakTok.getLocation();
    542 
    543   Token Tok;
    544   PP.Lex(Tok);
    545   if (Tok.isNot(tok::identifier)) {
    546     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
    547     return;
    548   }
    549 
    550   Token WeakName = Tok;
    551   bool HasAlias = false;
    552   Token AliasName;
    553 
    554   PP.Lex(Tok);
    555   if (Tok.is(tok::equal)) {
    556     HasAlias = true;
    557     PP.Lex(Tok);
    558     if (Tok.isNot(tok::identifier)) {
    559       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    560           << "weak";
    561       return;
    562     }
    563     AliasName = Tok;
    564     PP.Lex(Tok);
    565   }
    566 
    567   if (Tok.isNot(tok::eod)) {
    568     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
    569     return;
    570   }
    571 
    572   if (HasAlias) {
    573     Token *Toks =
    574       (Token*) PP.getPreprocessorAllocator().Allocate(
    575         sizeof(Token) * 3, llvm::alignOf<Token>());
    576     Token &pragmaUnusedTok = Toks[0];
    577     pragmaUnusedTok.startToken();
    578     pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
    579     pragmaUnusedTok.setLocation(WeakLoc);
    580     Toks[1] = WeakName;
    581     Toks[2] = AliasName;
    582     PP.EnterTokenStream(Toks, 3,
    583                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
    584   } else {
    585     Token *Toks =
    586       (Token*) PP.getPreprocessorAllocator().Allocate(
    587         sizeof(Token) * 2, llvm::alignOf<Token>());
    588     Token &pragmaUnusedTok = Toks[0];
    589     pragmaUnusedTok.startToken();
    590     pragmaUnusedTok.setKind(tok::annot_pragma_weak);
    591     pragmaUnusedTok.setLocation(WeakLoc);
    592     Toks[1] = WeakName;
    593     PP.EnterTokenStream(Toks, 2,
    594                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
    595   }
    596 }
    597 
    598 // #pragma redefine_extname identifier identifier
    599 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
    600                                                PragmaIntroducerKind Introducer,
    601                                                 Token &RedefToken) {
    602   SourceLocation RedefLoc = RedefToken.getLocation();
    603 
    604   Token Tok;
    605   PP.Lex(Tok);
    606   if (Tok.isNot(tok::identifier)) {
    607     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
    608       "redefine_extname";
    609     return;
    610   }
    611 
    612   Token RedefName = Tok;
    613   PP.Lex(Tok);
    614 
    615   if (Tok.isNot(tok::identifier)) {
    616     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    617         << "redefine_extname";
    618     return;
    619   }
    620 
    621   Token AliasName = Tok;
    622   PP.Lex(Tok);
    623 
    624   if (Tok.isNot(tok::eod)) {
    625     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
    626       "redefine_extname";
    627     return;
    628   }
    629 
    630   Token *Toks =
    631     (Token*) PP.getPreprocessorAllocator().Allocate(
    632       sizeof(Token) * 3, llvm::alignOf<Token>());
    633   Token &pragmaRedefTok = Toks[0];
    634   pragmaRedefTok.startToken();
    635   pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
    636   pragmaRedefTok.setLocation(RedefLoc);
    637   Toks[1] = RedefName;
    638   Toks[2] = AliasName;
    639   PP.EnterTokenStream(Toks, 3,
    640                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
    641 }
    642 
    643 
    644 void
    645 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
    646                                       PragmaIntroducerKind Introducer,
    647                                       Token &Tok) {
    648   tok::OnOffSwitch OOS;
    649   if (PP.LexOnOffSwitch(OOS))
    650     return;
    651 
    652   Token *Toks =
    653     (Token*) PP.getPreprocessorAllocator().Allocate(
    654       sizeof(Token) * 1, llvm::alignOf<Token>());
    655   new (Toks) Token();
    656   Toks[0].startToken();
    657   Toks[0].setKind(tok::annot_pragma_fp_contract);
    658   Toks[0].setLocation(Tok.getLocation());
    659   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
    660                              static_cast<uintptr_t>(OOS)));
    661   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    662                       /*OwnsTokens=*/false);
    663 }
    664 
    665 void
    666 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
    667                                            PragmaIntroducerKind Introducer,
    668                                            Token &Tok) {
    669   PP.LexUnexpandedToken(Tok);
    670   if (Tok.isNot(tok::identifier)) {
    671     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
    672       "OPENCL";
    673     return;
    674   }
    675   IdentifierInfo *ename = Tok.getIdentifierInfo();
    676   SourceLocation NameLoc = Tok.getLocation();
    677 
    678   PP.Lex(Tok);
    679   if (Tok.isNot(tok::colon)) {
    680     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
    681     return;
    682   }
    683 
    684   PP.Lex(Tok);
    685   if (Tok.isNot(tok::identifier)) {
    686     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
    687     return;
    688   }
    689   IdentifierInfo *op = Tok.getIdentifierInfo();
    690 
    691   unsigned state;
    692   if (op->isStr("enable")) {
    693     state = 1;
    694   } else if (op->isStr("disable")) {
    695     state = 0;
    696   } else {
    697     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
    698     return;
    699   }
    700 
    701   PP.Lex(Tok);
    702   if (Tok.isNot(tok::eod)) {
    703     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
    704       "OPENCL EXTENSION";
    705     return;
    706   }
    707 
    708   OpenCLExtData data(ename, state);
    709   Token *Toks =
    710     (Token*) PP.getPreprocessorAllocator().Allocate(
    711       sizeof(Token) * 1, llvm::alignOf<Token>());
    712   new (Toks) Token();
    713   Toks[0].startToken();
    714   Toks[0].setKind(tok::annot_pragma_opencl_extension);
    715   Toks[0].setLocation(NameLoc);
    716   Toks[0].setAnnotationValue(data.getOpaqueValue());
    717   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    718                       /*OwnsTokens=*/false);
    719 }
    720 
    721