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 "RAIIObjectsForParser.h"
     15 #include "clang/Lex/Preprocessor.h"
     16 #include "clang/Parse/ParseDiagnostic.h"
     17 #include "clang/Parse/Parser.h"
     18 #include "clang/Sema/LoopHint.h"
     19 #include "clang/Sema/Scope.h"
     20 #include "llvm/ADT/StringSwitch.h"
     21 using namespace clang;
     22 
     23 namespace {
     24 
     25 struct PragmaAlignHandler : public PragmaHandler {
     26   explicit PragmaAlignHandler() : PragmaHandler("align") {}
     27   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     28                     Token &FirstToken) override;
     29 };
     30 
     31 struct PragmaGCCVisibilityHandler : public PragmaHandler {
     32   explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
     33   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     34                     Token &FirstToken) override;
     35 };
     36 
     37 struct PragmaOptionsHandler : public PragmaHandler {
     38   explicit PragmaOptionsHandler() : PragmaHandler("options") {}
     39   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     40                     Token &FirstToken) override;
     41 };
     42 
     43 struct PragmaPackHandler : public PragmaHandler {
     44   explicit PragmaPackHandler() : PragmaHandler("pack") {}
     45   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     46                     Token &FirstToken) override;
     47 };
     48 
     49 struct PragmaMSStructHandler : public PragmaHandler {
     50   explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
     51   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     52                     Token &FirstToken) override;
     53 };
     54 
     55 struct PragmaUnusedHandler : public PragmaHandler {
     56   PragmaUnusedHandler() : PragmaHandler("unused") {}
     57   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     58                     Token &FirstToken) override;
     59 };
     60 
     61 struct PragmaWeakHandler : public PragmaHandler {
     62   explicit PragmaWeakHandler() : PragmaHandler("weak") {}
     63   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     64                     Token &FirstToken) override;
     65 };
     66 
     67 struct PragmaRedefineExtnameHandler : public PragmaHandler {
     68   explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
     69   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     70                     Token &FirstToken) override;
     71 };
     72 
     73 struct PragmaOpenCLExtensionHandler : public PragmaHandler {
     74   PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
     75   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     76                     Token &FirstToken) override;
     77 };
     78 
     79 
     80 struct PragmaFPContractHandler : public PragmaHandler {
     81   PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
     82   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     83                     Token &FirstToken) override;
     84 };
     85 
     86 struct PragmaNoOpenMPHandler : public PragmaHandler {
     87   PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
     88   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     89                     Token &FirstToken) override;
     90 };
     91 
     92 struct PragmaOpenMPHandler : public PragmaHandler {
     93   PragmaOpenMPHandler() : PragmaHandler("omp") { }
     94   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
     95                     Token &FirstToken) override;
     96 };
     97 
     98 /// PragmaCommentHandler - "\#pragma comment ...".
     99 struct PragmaCommentHandler : public PragmaHandler {
    100   PragmaCommentHandler(Sema &Actions)
    101     : PragmaHandler("comment"), Actions(Actions) {}
    102   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    103                     Token &FirstToken) override;
    104 private:
    105   Sema &Actions;
    106 };
    107 
    108 struct PragmaDetectMismatchHandler : public PragmaHandler {
    109   PragmaDetectMismatchHandler(Sema &Actions)
    110     : PragmaHandler("detect_mismatch"), Actions(Actions) {}
    111   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    112                     Token &FirstToken) override;
    113 private:
    114   Sema &Actions;
    115 };
    116 
    117 struct PragmaMSPointersToMembers : public PragmaHandler {
    118   explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
    119   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    120                     Token &FirstToken) override;
    121 };
    122 
    123 struct PragmaMSVtorDisp : public PragmaHandler {
    124   explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
    125   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    126                     Token &FirstToken) override;
    127 };
    128 
    129 struct PragmaMSPragma : public PragmaHandler {
    130   explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
    131   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    132                     Token &FirstToken) override;
    133 };
    134 
    135 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
    136 struct PragmaOptimizeHandler : public PragmaHandler {
    137   PragmaOptimizeHandler(Sema &S)
    138     : PragmaHandler("optimize"), Actions(S) {}
    139   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    140                     Token &FirstToken) override;
    141 private:
    142   Sema &Actions;
    143 };
    144 
    145 struct PragmaLoopHintHandler : public PragmaHandler {
    146   PragmaLoopHintHandler() : PragmaHandler("loop") {}
    147   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
    148                     Token &FirstToken) override;
    149 };
    150 
    151 }  // end namespace
    152 
    153 void Parser::initializePragmaHandlers() {
    154   AlignHandler.reset(new PragmaAlignHandler());
    155   PP.AddPragmaHandler(AlignHandler.get());
    156 
    157   GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
    158   PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
    159 
    160   OptionsHandler.reset(new PragmaOptionsHandler());
    161   PP.AddPragmaHandler(OptionsHandler.get());
    162 
    163   PackHandler.reset(new PragmaPackHandler());
    164   PP.AddPragmaHandler(PackHandler.get());
    165 
    166   MSStructHandler.reset(new PragmaMSStructHandler());
    167   PP.AddPragmaHandler(MSStructHandler.get());
    168 
    169   UnusedHandler.reset(new PragmaUnusedHandler());
    170   PP.AddPragmaHandler(UnusedHandler.get());
    171 
    172   WeakHandler.reset(new PragmaWeakHandler());
    173   PP.AddPragmaHandler(WeakHandler.get());
    174 
    175   RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
    176   PP.AddPragmaHandler(RedefineExtnameHandler.get());
    177 
    178   FPContractHandler.reset(new PragmaFPContractHandler());
    179   PP.AddPragmaHandler("STDC", FPContractHandler.get());
    180 
    181   if (getLangOpts().OpenCL) {
    182     OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
    183     PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
    184 
    185     PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
    186   }
    187   if (getLangOpts().OpenMP)
    188     OpenMPHandler.reset(new PragmaOpenMPHandler());
    189   else
    190     OpenMPHandler.reset(new PragmaNoOpenMPHandler());
    191   PP.AddPragmaHandler(OpenMPHandler.get());
    192 
    193   if (getLangOpts().MicrosoftExt) {
    194     MSCommentHandler.reset(new PragmaCommentHandler(Actions));
    195     PP.AddPragmaHandler(MSCommentHandler.get());
    196     MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
    197     PP.AddPragmaHandler(MSDetectMismatchHandler.get());
    198     MSPointersToMembers.reset(new PragmaMSPointersToMembers());
    199     PP.AddPragmaHandler(MSPointersToMembers.get());
    200     MSVtorDisp.reset(new PragmaMSVtorDisp());
    201     PP.AddPragmaHandler(MSVtorDisp.get());
    202     MSInitSeg.reset(new PragmaMSPragma("init_seg"));
    203     PP.AddPragmaHandler(MSInitSeg.get());
    204     MSDataSeg.reset(new PragmaMSPragma("data_seg"));
    205     PP.AddPragmaHandler(MSDataSeg.get());
    206     MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
    207     PP.AddPragmaHandler(MSBSSSeg.get());
    208     MSConstSeg.reset(new PragmaMSPragma("const_seg"));
    209     PP.AddPragmaHandler(MSConstSeg.get());
    210     MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
    211     PP.AddPragmaHandler(MSCodeSeg.get());
    212     MSSection.reset(new PragmaMSPragma("section"));
    213     PP.AddPragmaHandler(MSSection.get());
    214   }
    215 
    216   OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
    217   PP.AddPragmaHandler("clang", OptimizeHandler.get());
    218 
    219   LoopHintHandler.reset(new PragmaLoopHintHandler());
    220   PP.AddPragmaHandler("clang", LoopHintHandler.get());
    221 }
    222 
    223 void Parser::resetPragmaHandlers() {
    224   // Remove the pragma handlers we installed.
    225   PP.RemovePragmaHandler(AlignHandler.get());
    226   AlignHandler.reset();
    227   PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
    228   GCCVisibilityHandler.reset();
    229   PP.RemovePragmaHandler(OptionsHandler.get());
    230   OptionsHandler.reset();
    231   PP.RemovePragmaHandler(PackHandler.get());
    232   PackHandler.reset();
    233   PP.RemovePragmaHandler(MSStructHandler.get());
    234   MSStructHandler.reset();
    235   PP.RemovePragmaHandler(UnusedHandler.get());
    236   UnusedHandler.reset();
    237   PP.RemovePragmaHandler(WeakHandler.get());
    238   WeakHandler.reset();
    239   PP.RemovePragmaHandler(RedefineExtnameHandler.get());
    240   RedefineExtnameHandler.reset();
    241 
    242   if (getLangOpts().OpenCL) {
    243     PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
    244     OpenCLExtensionHandler.reset();
    245     PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
    246   }
    247   PP.RemovePragmaHandler(OpenMPHandler.get());
    248   OpenMPHandler.reset();
    249 
    250   if (getLangOpts().MicrosoftExt) {
    251     PP.RemovePragmaHandler(MSCommentHandler.get());
    252     MSCommentHandler.reset();
    253     PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
    254     MSDetectMismatchHandler.reset();
    255     PP.RemovePragmaHandler(MSPointersToMembers.get());
    256     MSPointersToMembers.reset();
    257     PP.RemovePragmaHandler(MSVtorDisp.get());
    258     MSVtorDisp.reset();
    259     PP.RemovePragmaHandler(MSInitSeg.get());
    260     MSInitSeg.reset();
    261     PP.RemovePragmaHandler(MSDataSeg.get());
    262     MSDataSeg.reset();
    263     PP.RemovePragmaHandler(MSBSSSeg.get());
    264     MSBSSSeg.reset();
    265     PP.RemovePragmaHandler(MSConstSeg.get());
    266     MSConstSeg.reset();
    267     PP.RemovePragmaHandler(MSCodeSeg.get());
    268     MSCodeSeg.reset();
    269     PP.RemovePragmaHandler(MSSection.get());
    270     MSSection.reset();
    271   }
    272 
    273   PP.RemovePragmaHandler("STDC", FPContractHandler.get());
    274   FPContractHandler.reset();
    275 
    276   PP.RemovePragmaHandler("clang", OptimizeHandler.get());
    277   OptimizeHandler.reset();
    278 
    279   PP.RemovePragmaHandler("clang", LoopHintHandler.get());
    280   LoopHintHandler.reset();
    281 }
    282 
    283 /// \brief Handle the annotation token produced for #pragma unused(...)
    284 ///
    285 /// Each annot_pragma_unused is followed by the argument token so e.g.
    286 /// "#pragma unused(x,y)" becomes:
    287 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
    288 void Parser::HandlePragmaUnused() {
    289   assert(Tok.is(tok::annot_pragma_unused));
    290   SourceLocation UnusedLoc = ConsumeToken();
    291   Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
    292   ConsumeToken(); // The argument token.
    293 }
    294 
    295 void Parser::HandlePragmaVisibility() {
    296   assert(Tok.is(tok::annot_pragma_vis));
    297   const IdentifierInfo *VisType =
    298     static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
    299   SourceLocation VisLoc = ConsumeToken();
    300   Actions.ActOnPragmaVisibility(VisType, VisLoc);
    301 }
    302 
    303 struct PragmaPackInfo {
    304   Sema::PragmaPackKind Kind;
    305   IdentifierInfo *Name;
    306   Token Alignment;
    307   SourceLocation LParenLoc;
    308   SourceLocation RParenLoc;
    309 };
    310 
    311 void Parser::HandlePragmaPack() {
    312   assert(Tok.is(tok::annot_pragma_pack));
    313   PragmaPackInfo *Info =
    314     static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
    315   SourceLocation PragmaLoc = ConsumeToken();
    316   ExprResult Alignment;
    317   if (Info->Alignment.is(tok::numeric_constant)) {
    318     Alignment = Actions.ActOnNumericConstant(Info->Alignment);
    319     if (Alignment.isInvalid())
    320       return;
    321   }
    322   Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
    323                           Info->LParenLoc, Info->RParenLoc);
    324 }
    325 
    326 void Parser::HandlePragmaMSStruct() {
    327   assert(Tok.is(tok::annot_pragma_msstruct));
    328   Sema::PragmaMSStructKind Kind =
    329     static_cast<Sema::PragmaMSStructKind>(
    330     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
    331   Actions.ActOnPragmaMSStruct(Kind);
    332   ConsumeToken(); // The annotation token.
    333 }
    334 
    335 void Parser::HandlePragmaAlign() {
    336   assert(Tok.is(tok::annot_pragma_align));
    337   Sema::PragmaOptionsAlignKind Kind =
    338     static_cast<Sema::PragmaOptionsAlignKind>(
    339     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
    340   SourceLocation PragmaLoc = ConsumeToken();
    341   Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
    342 }
    343 
    344 void Parser::HandlePragmaWeak() {
    345   assert(Tok.is(tok::annot_pragma_weak));
    346   SourceLocation PragmaLoc = ConsumeToken();
    347   Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
    348                             Tok.getLocation());
    349   ConsumeToken(); // The weak name.
    350 }
    351 
    352 void Parser::HandlePragmaWeakAlias() {
    353   assert(Tok.is(tok::annot_pragma_weakalias));
    354   SourceLocation PragmaLoc = ConsumeToken();
    355   IdentifierInfo *WeakName = Tok.getIdentifierInfo();
    356   SourceLocation WeakNameLoc = Tok.getLocation();
    357   ConsumeToken();
    358   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
    359   SourceLocation AliasNameLoc = Tok.getLocation();
    360   ConsumeToken();
    361   Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
    362                                WeakNameLoc, AliasNameLoc);
    363 
    364 }
    365 
    366 void Parser::HandlePragmaRedefineExtname() {
    367   assert(Tok.is(tok::annot_pragma_redefine_extname));
    368   SourceLocation RedefLoc = ConsumeToken();
    369   IdentifierInfo *RedefName = Tok.getIdentifierInfo();
    370   SourceLocation RedefNameLoc = Tok.getLocation();
    371   ConsumeToken();
    372   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
    373   SourceLocation AliasNameLoc = Tok.getLocation();
    374   ConsumeToken();
    375   Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
    376                                      RedefNameLoc, AliasNameLoc);
    377 }
    378 
    379 void Parser::HandlePragmaFPContract() {
    380   assert(Tok.is(tok::annot_pragma_fp_contract));
    381   tok::OnOffSwitch OOS =
    382     static_cast<tok::OnOffSwitch>(
    383     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
    384   Actions.ActOnPragmaFPContract(OOS);
    385   ConsumeToken(); // The annotation token.
    386 }
    387 
    388 StmtResult Parser::HandlePragmaCaptured()
    389 {
    390   assert(Tok.is(tok::annot_pragma_captured));
    391   ConsumeToken();
    392 
    393   if (Tok.isNot(tok::l_brace)) {
    394     PP.Diag(Tok, diag::err_expected) << tok::l_brace;
    395     return StmtError();
    396   }
    397 
    398   SourceLocation Loc = Tok.getLocation();
    399 
    400   ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
    401   Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
    402                                    /*NumParams=*/1);
    403 
    404   StmtResult R = ParseCompoundStatement();
    405   CapturedRegionScope.Exit();
    406 
    407   if (R.isInvalid()) {
    408     Actions.ActOnCapturedRegionError();
    409     return StmtError();
    410   }
    411 
    412   return Actions.ActOnCapturedRegionEnd(R.get());
    413 }
    414 
    415 namespace {
    416   typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
    417 }
    418 
    419 void Parser::HandlePragmaOpenCLExtension() {
    420   assert(Tok.is(tok::annot_pragma_opencl_extension));
    421   OpenCLExtData data =
    422       OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
    423   unsigned state = data.getInt();
    424   IdentifierInfo *ename = data.getPointer();
    425   SourceLocation NameLoc = Tok.getLocation();
    426   ConsumeToken(); // The annotation token.
    427 
    428   OpenCLOptions &f = Actions.getOpenCLOptions();
    429   // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
    430   // overriding all previously issued extension directives, but only if the
    431   // behavior is set to disable."
    432   if (state == 0 && ename->isStr("all")) {
    433 #define OPENCLEXT(nm)   f.nm = 0;
    434 #include "clang/Basic/OpenCLExtensions.def"
    435   }
    436 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
    437 #include "clang/Basic/OpenCLExtensions.def"
    438   else {
    439     PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
    440     return;
    441   }
    442 }
    443 
    444 void Parser::HandlePragmaMSPointersToMembers() {
    445   assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
    446   LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
    447       static_cast<LangOptions::PragmaMSPointersToMembersKind>(
    448           reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
    449   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
    450   Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
    451 }
    452 
    453 void Parser::HandlePragmaMSVtorDisp() {
    454   assert(Tok.is(tok::annot_pragma_ms_vtordisp));
    455   uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
    456   Sema::PragmaVtorDispKind Kind =
    457       static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
    458   MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
    459   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
    460   Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
    461 }
    462 
    463 void Parser::HandlePragmaMSPragma() {
    464   assert(Tok.is(tok::annot_pragma_ms_pragma));
    465   // Grab the tokens out of the annotation and enter them into the stream.
    466   auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
    467   PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
    468   SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
    469   assert(Tok.isAnyIdentifier());
    470   llvm::StringRef PragmaName = Tok.getIdentifierInfo()->getName();
    471   PP.Lex(Tok); // pragma kind
    472   // Figure out which #pragma we're dealing with.  The switch has no default
    473   // because lex shouldn't emit the annotation token for unrecognized pragmas.
    474   typedef unsigned (Parser::*PragmaHandler)(llvm::StringRef, SourceLocation);
    475   PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
    476     .Case("data_seg", &Parser::HandlePragmaMSSegment)
    477     .Case("bss_seg", &Parser::HandlePragmaMSSegment)
    478     .Case("const_seg", &Parser::HandlePragmaMSSegment)
    479     .Case("code_seg", &Parser::HandlePragmaMSSegment)
    480     .Case("section", &Parser::HandlePragmaMSSection)
    481     .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
    482   if (auto DiagID = (this->*Handler)(PragmaName, PragmaLocation)) {
    483     PP.Diag(PragmaLocation, DiagID) << PragmaName;
    484     while (Tok.isNot(tok::eof))
    485       PP.Lex(Tok);
    486     PP.Lex(Tok);
    487   }
    488 }
    489 
    490 unsigned Parser::HandlePragmaMSSection(llvm::StringRef PragmaName,
    491                                        SourceLocation PragmaLocation) {
    492   if (Tok.isNot(tok::l_paren))
    493     return diag::warn_pragma_expected_lparen;
    494   PP.Lex(Tok); // (
    495   // Parsing code for pragma section
    496   if (Tok.isNot(tok::string_literal))
    497     return diag::warn_pragma_expected_section_name;
    498   StringLiteral *SegmentName =
    499     cast<StringLiteral>(ParseStringLiteralExpression().get());
    500   int SectionFlags = 0;
    501   while (Tok.is(tok::comma)) {
    502     PP.Lex(Tok); // ,
    503     if (!Tok.isAnyIdentifier())
    504       return diag::warn_pragma_expected_action_or_r_paren;
    505     Sema::PragmaSectionFlag Flag =
    506       llvm::StringSwitch<Sema::PragmaSectionFlag>(
    507       Tok.getIdentifierInfo()->getName())
    508       .Case("read", Sema::PSF_Read)
    509       .Case("write", Sema::PSF_Write)
    510       .Case("execute", Sema::PSF_Execute)
    511       .Case("shared", Sema::PSF_Invalid)
    512       .Case("nopage", Sema::PSF_Invalid)
    513       .Case("nocache", Sema::PSF_Invalid)
    514       .Case("discard", Sema::PSF_Invalid)
    515       .Case("remove", Sema::PSF_Invalid)
    516       .Default(Sema::PSF_None);
    517     if (Flag == Sema::PSF_None || Flag == Sema::PSF_Invalid) {
    518       PP.Diag(PragmaLocation, Flag == Sema::PSF_None ?
    519                               diag::warn_pragma_invalid_specific_action :
    520                               diag::warn_pragma_unsupported_action)
    521           << PragmaName << Tok.getIdentifierInfo()->getName();
    522       while (Tok.isNot(tok::eof))
    523         PP.Lex(Tok);
    524       PP.Lex(Tok);
    525       return 0;
    526     }
    527     SectionFlags |= Flag;
    528     PP.Lex(Tok); // Identifier
    529   }
    530   if (Tok.isNot(tok::r_paren))
    531     return diag::warn_pragma_expected_rparen;
    532   PP.Lex(Tok); // )
    533   if (Tok.isNot(tok::eof))
    534     return diag::warn_pragma_extra_tokens_at_eol;
    535   PP.Lex(Tok); // eof
    536   Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
    537   return 0;
    538 }
    539 
    540 unsigned Parser::HandlePragmaMSSegment(llvm::StringRef PragmaName,
    541                                       SourceLocation PragmaLocation) {
    542   if (Tok.isNot(tok::l_paren))
    543     return diag::warn_pragma_expected_lparen;
    544   PP.Lex(Tok); // (
    545   Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
    546   llvm::StringRef SlotLabel;
    547   if (Tok.isAnyIdentifier()) {
    548     llvm::StringRef PushPop = Tok.getIdentifierInfo()->getName();
    549     if (PushPop == "push")
    550       Action = Sema::PSK_Push;
    551     else if (PushPop == "pop")
    552       Action = Sema::PSK_Pop;
    553     else
    554       return diag::warn_pragma_expected_section_push_pop_or_name;
    555     if (Action != Sema::PSK_Reset) {
    556       PP.Lex(Tok); // push | pop
    557       if (Tok.is(tok::comma)) {
    558         PP.Lex(Tok); // ,
    559         // If we've got a comma, we either need a label or a string.
    560         if (Tok.isAnyIdentifier()) {
    561           SlotLabel = Tok.getIdentifierInfo()->getName();
    562           PP.Lex(Tok); // identifier
    563           if (Tok.is(tok::comma))
    564             PP.Lex(Tok);
    565           else if (Tok.isNot(tok::r_paren))
    566             return diag::warn_pragma_expected_punc;
    567         }
    568       } else if (Tok.isNot(tok::r_paren))
    569         return diag::warn_pragma_expected_punc;
    570     }
    571   }
    572   // Grab the string literal for our section name.
    573   StringLiteral *SegmentName = nullptr;
    574   if (Tok.isNot(tok::r_paren)) {
    575     if (Tok.isNot(tok::string_literal))
    576       return Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
    577           diag::warn_pragma_expected_section_name :
    578           diag::warn_pragma_expected_section_label_or_name :
    579           diag::warn_pragma_expected_section_push_pop_or_name;
    580     SegmentName = cast<StringLiteral>(ParseStringLiteralExpression().get());
    581     // Setting section "" has no effect
    582     if (SegmentName->getLength())
    583       Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
    584   }
    585   if (Tok.isNot(tok::r_paren))
    586     return diag::warn_pragma_expected_rparen;
    587   PP.Lex(Tok); // )
    588   if (Tok.isNot(tok::eof))
    589     return diag::warn_pragma_extra_tokens_at_eol;
    590   PP.Lex(Tok); // eof
    591   Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
    592                            SegmentName, PragmaName);
    593   return 0;
    594 }
    595 
    596 unsigned Parser::HandlePragmaMSInitSeg(llvm::StringRef PragmaName,
    597                                        SourceLocation PragmaLocation) {
    598   return PP.getDiagnostics().getCustomDiagID(
    599       DiagnosticsEngine::Error, "'#pragma %0' not implemented.");
    600 }
    601 
    602 struct PragmaLoopHintInfo {
    603   Token Loop;
    604   Token Value;
    605   Token Option;
    606 };
    607 
    608 LoopHint Parser::HandlePragmaLoopHint() {
    609   assert(Tok.is(tok::annot_pragma_loop_hint));
    610   PragmaLoopHintInfo *Info =
    611       static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
    612 
    613   LoopHint Hint;
    614   Hint.LoopLoc =
    615       IdentifierLoc::create(Actions.Context, Info->Loop.getLocation(),
    616                             Info->Loop.getIdentifierInfo());
    617   Hint.OptionLoc =
    618       IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),
    619                             Info->Option.getIdentifierInfo());
    620   Hint.ValueLoc =
    621       IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),
    622                             Info->Value.getIdentifierInfo());
    623   Hint.Range =
    624       SourceRange(Info->Option.getLocation(), Info->Value.getLocation());
    625 
    626   // FIXME: We should allow non-type template parameters for the loop hint
    627   // value. See bug report #19610
    628   if (Info->Value.is(tok::numeric_constant))
    629     Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();
    630   else
    631     Hint.ValueExpr = nullptr;
    632 
    633   return Hint;
    634 }
    635 
    636 // #pragma GCC visibility comes in two variants:
    637 //   'push' '(' [visibility] ')'
    638 //   'pop'
    639 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
    640                                               PragmaIntroducerKind Introducer,
    641                                               Token &VisTok) {
    642   SourceLocation VisLoc = VisTok.getLocation();
    643 
    644   Token Tok;
    645   PP.LexUnexpandedToken(Tok);
    646 
    647   const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
    648 
    649   const IdentifierInfo *VisType;
    650   if (PushPop && PushPop->isStr("pop")) {
    651     VisType = nullptr;
    652   } else if (PushPop && PushPop->isStr("push")) {
    653     PP.LexUnexpandedToken(Tok);
    654     if (Tok.isNot(tok::l_paren)) {
    655       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
    656         << "visibility";
    657       return;
    658     }
    659     PP.LexUnexpandedToken(Tok);
    660     VisType = Tok.getIdentifierInfo();
    661     if (!VisType) {
    662       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    663         << "visibility";
    664       return;
    665     }
    666     PP.LexUnexpandedToken(Tok);
    667     if (Tok.isNot(tok::r_paren)) {
    668       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
    669         << "visibility";
    670       return;
    671     }
    672   } else {
    673     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    674       << "visibility";
    675     return;
    676   }
    677   PP.LexUnexpandedToken(Tok);
    678   if (Tok.isNot(tok::eod)) {
    679     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
    680       << "visibility";
    681     return;
    682   }
    683 
    684   Token *Toks = new Token[1];
    685   Toks[0].startToken();
    686   Toks[0].setKind(tok::annot_pragma_vis);
    687   Toks[0].setLocation(VisLoc);
    688   Toks[0].setAnnotationValue(
    689                           const_cast<void*>(static_cast<const void*>(VisType)));
    690   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    691                       /*OwnsTokens=*/true);
    692 }
    693 
    694 // #pragma pack(...) comes in the following delicious flavors:
    695 //   pack '(' [integer] ')'
    696 //   pack '(' 'show' ')'
    697 //   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
    698 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
    699                                      PragmaIntroducerKind Introducer,
    700                                      Token &PackTok) {
    701   SourceLocation PackLoc = PackTok.getLocation();
    702 
    703   Token Tok;
    704   PP.Lex(Tok);
    705   if (Tok.isNot(tok::l_paren)) {
    706     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
    707     return;
    708   }
    709 
    710   Sema::PragmaPackKind Kind = Sema::PPK_Default;
    711   IdentifierInfo *Name = nullptr;
    712   Token Alignment;
    713   Alignment.startToken();
    714   SourceLocation LParenLoc = Tok.getLocation();
    715   PP.Lex(Tok);
    716   if (Tok.is(tok::numeric_constant)) {
    717     Alignment = Tok;
    718 
    719     PP.Lex(Tok);
    720 
    721     // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
    722     // the push/pop stack.
    723     // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
    724     if (PP.getLangOpts().ApplePragmaPack)
    725       Kind = Sema::PPK_Push;
    726   } else if (Tok.is(tok::identifier)) {
    727     const IdentifierInfo *II = Tok.getIdentifierInfo();
    728     if (II->isStr("show")) {
    729       Kind = Sema::PPK_Show;
    730       PP.Lex(Tok);
    731     } else {
    732       if (II->isStr("push")) {
    733         Kind = Sema::PPK_Push;
    734       } else if (II->isStr("pop")) {
    735         Kind = Sema::PPK_Pop;
    736       } else {
    737         PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
    738         return;
    739       }
    740       PP.Lex(Tok);
    741 
    742       if (Tok.is(tok::comma)) {
    743         PP.Lex(Tok);
    744 
    745         if (Tok.is(tok::numeric_constant)) {
    746           Alignment = Tok;
    747 
    748           PP.Lex(Tok);
    749         } else if (Tok.is(tok::identifier)) {
    750           Name = Tok.getIdentifierInfo();
    751           PP.Lex(Tok);
    752 
    753           if (Tok.is(tok::comma)) {
    754             PP.Lex(Tok);
    755 
    756             if (Tok.isNot(tok::numeric_constant)) {
    757               PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
    758               return;
    759             }
    760 
    761             Alignment = Tok;
    762 
    763             PP.Lex(Tok);
    764           }
    765         } else {
    766           PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
    767           return;
    768         }
    769       }
    770     }
    771   } else if (PP.getLangOpts().ApplePragmaPack) {
    772     // In MSVC/gcc, #pragma pack() resets the alignment without affecting
    773     // the push/pop stack.
    774     // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
    775     Kind = Sema::PPK_Pop;
    776   }
    777 
    778   if (Tok.isNot(tok::r_paren)) {
    779     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
    780     return;
    781   }
    782 
    783   SourceLocation RParenLoc = Tok.getLocation();
    784   PP.Lex(Tok);
    785   if (Tok.isNot(tok::eod)) {
    786     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
    787     return;
    788   }
    789 
    790   PragmaPackInfo *Info =
    791     (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
    792       sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
    793   new (Info) PragmaPackInfo();
    794   Info->Kind = Kind;
    795   Info->Name = Name;
    796   Info->Alignment = Alignment;
    797   Info->LParenLoc = LParenLoc;
    798   Info->RParenLoc = RParenLoc;
    799 
    800   Token *Toks =
    801     (Token*) PP.getPreprocessorAllocator().Allocate(
    802       sizeof(Token) * 1, llvm::alignOf<Token>());
    803   new (Toks) Token();
    804   Toks[0].startToken();
    805   Toks[0].setKind(tok::annot_pragma_pack);
    806   Toks[0].setLocation(PackLoc);
    807   Toks[0].setAnnotationValue(static_cast<void*>(Info));
    808   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    809                       /*OwnsTokens=*/false);
    810 }
    811 
    812 // #pragma ms_struct on
    813 // #pragma ms_struct off
    814 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
    815                                          PragmaIntroducerKind Introducer,
    816                                          Token &MSStructTok) {
    817   Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
    818 
    819   Token Tok;
    820   PP.Lex(Tok);
    821   if (Tok.isNot(tok::identifier)) {
    822     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
    823     return;
    824   }
    825   const IdentifierInfo *II = Tok.getIdentifierInfo();
    826   if (II->isStr("on")) {
    827     Kind = Sema::PMSST_ON;
    828     PP.Lex(Tok);
    829   }
    830   else if (II->isStr("off") || II->isStr("reset"))
    831     PP.Lex(Tok);
    832   else {
    833     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
    834     return;
    835   }
    836 
    837   if (Tok.isNot(tok::eod)) {
    838     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
    839       << "ms_struct";
    840     return;
    841   }
    842 
    843   Token *Toks =
    844     (Token*) PP.getPreprocessorAllocator().Allocate(
    845       sizeof(Token) * 1, llvm::alignOf<Token>());
    846   new (Toks) Token();
    847   Toks[0].startToken();
    848   Toks[0].setKind(tok::annot_pragma_msstruct);
    849   Toks[0].setLocation(MSStructTok.getLocation());
    850   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
    851                              static_cast<uintptr_t>(Kind)));
    852   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    853                       /*OwnsTokens=*/false);
    854 }
    855 
    856 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
    857 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
    858 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
    859                              bool IsOptions) {
    860   Token Tok;
    861 
    862   if (IsOptions) {
    863     PP.Lex(Tok);
    864     if (Tok.isNot(tok::identifier) ||
    865         !Tok.getIdentifierInfo()->isStr("align")) {
    866       PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
    867       return;
    868     }
    869   }
    870 
    871   PP.Lex(Tok);
    872   if (Tok.isNot(tok::equal)) {
    873     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
    874       << IsOptions;
    875     return;
    876   }
    877 
    878   PP.Lex(Tok);
    879   if (Tok.isNot(tok::identifier)) {
    880     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
    881       << (IsOptions ? "options" : "align");
    882     return;
    883   }
    884 
    885   Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
    886   const IdentifierInfo *II = Tok.getIdentifierInfo();
    887   if (II->isStr("native"))
    888     Kind = Sema::POAK_Native;
    889   else if (II->isStr("natural"))
    890     Kind = Sema::POAK_Natural;
    891   else if (II->isStr("packed"))
    892     Kind = Sema::POAK_Packed;
    893   else if (II->isStr("power"))
    894     Kind = Sema::POAK_Power;
    895   else if (II->isStr("mac68k"))
    896     Kind = Sema::POAK_Mac68k;
    897   else if (II->isStr("reset"))
    898     Kind = Sema::POAK_Reset;
    899   else {
    900     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
    901       << IsOptions;
    902     return;
    903   }
    904 
    905   PP.Lex(Tok);
    906   if (Tok.isNot(tok::eod)) {
    907     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
    908       << (IsOptions ? "options" : "align");
    909     return;
    910   }
    911 
    912   Token *Toks =
    913     (Token*) PP.getPreprocessorAllocator().Allocate(
    914       sizeof(Token) * 1, llvm::alignOf<Token>());
    915   new (Toks) Token();
    916   Toks[0].startToken();
    917   Toks[0].setKind(tok::annot_pragma_align);
    918   Toks[0].setLocation(FirstTok.getLocation());
    919   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
    920                              static_cast<uintptr_t>(Kind)));
    921   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
    922                       /*OwnsTokens=*/false);
    923 }
    924 
    925 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
    926                                       PragmaIntroducerKind Introducer,
    927                                       Token &AlignTok) {
    928   ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
    929 }
    930 
    931 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
    932                                         PragmaIntroducerKind Introducer,
    933                                         Token &OptionsTok) {
    934   ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
    935 }
    936 
    937 // #pragma unused(identifier)
    938 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
    939                                        PragmaIntroducerKind Introducer,
    940                                        Token &UnusedTok) {
    941   // FIXME: Should we be expanding macros here? My guess is no.
    942   SourceLocation UnusedLoc = UnusedTok.getLocation();
    943 
    944   // Lex the left '('.
    945   Token Tok;
    946   PP.Lex(Tok);
    947   if (Tok.isNot(tok::l_paren)) {
    948     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
    949     return;
    950   }
    951 
    952   // Lex the declaration reference(s).
    953   SmallVector<Token, 5> Identifiers;
    954   SourceLocation RParenLoc;
    955   bool LexID = true;
    956 
    957   while (true) {
    958     PP.Lex(Tok);
    959 
    960     if (LexID) {
    961       if (Tok.is(tok::identifier)) {
    962         Identifiers.push_back(Tok);
    963         LexID = false;
    964         continue;
    965       }
    966 
    967       // Illegal token!
    968       PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
    969       return;
    970     }
    971 
    972     // We are execting a ')' or a ','.
    973     if (Tok.is(tok::comma)) {
    974       LexID = true;
    975       continue;
    976     }
    977 
    978     if (Tok.is(tok::r_paren)) {
    979       RParenLoc = Tok.getLocation();
    980       break;
    981     }
    982 
    983     // Illegal token!
    984     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
    985     return;
    986   }
    987 
    988   PP.Lex(Tok);
    989   if (Tok.isNot(tok::eod)) {
    990     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
    991         "unused";
    992     return;
    993   }
    994 
    995   // Verify that we have a location for the right parenthesis.
    996   assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
    997   assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
    998 
    999   // For each identifier token, insert into the token stream a
   1000   // annot_pragma_unused token followed by the identifier token.
   1001   // This allows us to cache a "#pragma unused" that occurs inside an inline
   1002   // C++ member function.
   1003 
   1004   Token *Toks =
   1005     (Token*) PP.getPreprocessorAllocator().Allocate(
   1006       sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
   1007   for (unsigned i=0; i != Identifiers.size(); i++) {
   1008     Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
   1009     pragmaUnusedTok.startToken();
   1010     pragmaUnusedTok.setKind(tok::annot_pragma_unused);
   1011     pragmaUnusedTok.setLocation(UnusedLoc);
   1012     idTok = Identifiers[i];
   1013   }
   1014   PP.EnterTokenStream(Toks, 2*Identifiers.size(),
   1015                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
   1016 }
   1017 
   1018 // #pragma weak identifier
   1019 // #pragma weak identifier '=' identifier
   1020 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
   1021                                      PragmaIntroducerKind Introducer,
   1022                                      Token &WeakTok) {
   1023   SourceLocation WeakLoc = WeakTok.getLocation();
   1024 
   1025   Token Tok;
   1026   PP.Lex(Tok);
   1027   if (Tok.isNot(tok::identifier)) {
   1028     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
   1029     return;
   1030   }
   1031 
   1032   Token WeakName = Tok;
   1033   bool HasAlias = false;
   1034   Token AliasName;
   1035 
   1036   PP.Lex(Tok);
   1037   if (Tok.is(tok::equal)) {
   1038     HasAlias = true;
   1039     PP.Lex(Tok);
   1040     if (Tok.isNot(tok::identifier)) {
   1041       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
   1042           << "weak";
   1043       return;
   1044     }
   1045     AliasName = Tok;
   1046     PP.Lex(Tok);
   1047   }
   1048 
   1049   if (Tok.isNot(tok::eod)) {
   1050     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
   1051     return;
   1052   }
   1053 
   1054   if (HasAlias) {
   1055     Token *Toks =
   1056       (Token*) PP.getPreprocessorAllocator().Allocate(
   1057         sizeof(Token) * 3, llvm::alignOf<Token>());
   1058     Token &pragmaUnusedTok = Toks[0];
   1059     pragmaUnusedTok.startToken();
   1060     pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
   1061     pragmaUnusedTok.setLocation(WeakLoc);
   1062     Toks[1] = WeakName;
   1063     Toks[2] = AliasName;
   1064     PP.EnterTokenStream(Toks, 3,
   1065                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
   1066   } else {
   1067     Token *Toks =
   1068       (Token*) PP.getPreprocessorAllocator().Allocate(
   1069         sizeof(Token) * 2, llvm::alignOf<Token>());
   1070     Token &pragmaUnusedTok = Toks[0];
   1071     pragmaUnusedTok.startToken();
   1072     pragmaUnusedTok.setKind(tok::annot_pragma_weak);
   1073     pragmaUnusedTok.setLocation(WeakLoc);
   1074     Toks[1] = WeakName;
   1075     PP.EnterTokenStream(Toks, 2,
   1076                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
   1077   }
   1078 }
   1079 
   1080 // #pragma redefine_extname identifier identifier
   1081 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
   1082                                                PragmaIntroducerKind Introducer,
   1083                                                 Token &RedefToken) {
   1084   SourceLocation RedefLoc = RedefToken.getLocation();
   1085 
   1086   Token Tok;
   1087   PP.Lex(Tok);
   1088   if (Tok.isNot(tok::identifier)) {
   1089     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
   1090       "redefine_extname";
   1091     return;
   1092   }
   1093 
   1094   Token RedefName = Tok;
   1095   PP.Lex(Tok);
   1096 
   1097   if (Tok.isNot(tok::identifier)) {
   1098     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
   1099         << "redefine_extname";
   1100     return;
   1101   }
   1102 
   1103   Token AliasName = Tok;
   1104   PP.Lex(Tok);
   1105 
   1106   if (Tok.isNot(tok::eod)) {
   1107     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
   1108       "redefine_extname";
   1109     return;
   1110   }
   1111 
   1112   Token *Toks =
   1113     (Token*) PP.getPreprocessorAllocator().Allocate(
   1114       sizeof(Token) * 3, llvm::alignOf<Token>());
   1115   Token &pragmaRedefTok = Toks[0];
   1116   pragmaRedefTok.startToken();
   1117   pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
   1118   pragmaRedefTok.setLocation(RedefLoc);
   1119   Toks[1] = RedefName;
   1120   Toks[2] = AliasName;
   1121   PP.EnterTokenStream(Toks, 3,
   1122                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
   1123 }
   1124 
   1125 
   1126 void
   1127 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
   1128                                       PragmaIntroducerKind Introducer,
   1129                                       Token &Tok) {
   1130   tok::OnOffSwitch OOS;
   1131   if (PP.LexOnOffSwitch(OOS))
   1132     return;
   1133 
   1134   Token *Toks =
   1135     (Token*) PP.getPreprocessorAllocator().Allocate(
   1136       sizeof(Token) * 1, llvm::alignOf<Token>());
   1137   new (Toks) Token();
   1138   Toks[0].startToken();
   1139   Toks[0].setKind(tok::annot_pragma_fp_contract);
   1140   Toks[0].setLocation(Tok.getLocation());
   1141   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
   1142                              static_cast<uintptr_t>(OOS)));
   1143   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
   1144                       /*OwnsTokens=*/false);
   1145 }
   1146 
   1147 void
   1148 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
   1149                                            PragmaIntroducerKind Introducer,
   1150                                            Token &Tok) {
   1151   PP.LexUnexpandedToken(Tok);
   1152   if (Tok.isNot(tok::identifier)) {
   1153     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
   1154       "OPENCL";
   1155     return;
   1156   }
   1157   IdentifierInfo *ename = Tok.getIdentifierInfo();
   1158   SourceLocation NameLoc = Tok.getLocation();
   1159 
   1160   PP.Lex(Tok);
   1161   if (Tok.isNot(tok::colon)) {
   1162     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
   1163     return;
   1164   }
   1165 
   1166   PP.Lex(Tok);
   1167   if (Tok.isNot(tok::identifier)) {
   1168     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
   1169     return;
   1170   }
   1171   IdentifierInfo *op = Tok.getIdentifierInfo();
   1172 
   1173   unsigned state;
   1174   if (op->isStr("enable")) {
   1175     state = 1;
   1176   } else if (op->isStr("disable")) {
   1177     state = 0;
   1178   } else {
   1179     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
   1180     return;
   1181   }
   1182   SourceLocation StateLoc = Tok.getLocation();
   1183 
   1184   PP.Lex(Tok);
   1185   if (Tok.isNot(tok::eod)) {
   1186     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
   1187       "OPENCL EXTENSION";
   1188     return;
   1189   }
   1190 
   1191   OpenCLExtData data(ename, state);
   1192   Token *Toks =
   1193     (Token*) PP.getPreprocessorAllocator().Allocate(
   1194       sizeof(Token) * 1, llvm::alignOf<Token>());
   1195   new (Toks) Token();
   1196   Toks[0].startToken();
   1197   Toks[0].setKind(tok::annot_pragma_opencl_extension);
   1198   Toks[0].setLocation(NameLoc);
   1199   Toks[0].setAnnotationValue(data.getOpaqueValue());
   1200   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
   1201                       /*OwnsTokens=*/false);
   1202 
   1203   if (PP.getPPCallbacks())
   1204     PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename,
   1205                                                StateLoc, state);
   1206 }
   1207 
   1208 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
   1209 ///
   1210 void
   1211 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
   1212                                     PragmaIntroducerKind Introducer,
   1213                                     Token &FirstTok) {
   1214   if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
   1215                                      FirstTok.getLocation())) {
   1216     PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
   1217     PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
   1218                                     diag::Severity::Ignored, SourceLocation());
   1219   }
   1220   PP.DiscardUntilEndOfDirective();
   1221 }
   1222 
   1223 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
   1224 ///
   1225 void
   1226 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
   1227                                   PragmaIntroducerKind Introducer,
   1228                                   Token &FirstTok) {
   1229   SmallVector<Token, 16> Pragma;
   1230   Token Tok;
   1231   Tok.startToken();
   1232   Tok.setKind(tok::annot_pragma_openmp);
   1233   Tok.setLocation(FirstTok.getLocation());
   1234 
   1235   while (Tok.isNot(tok::eod)) {
   1236     Pragma.push_back(Tok);
   1237     PP.Lex(Tok);
   1238   }
   1239   SourceLocation EodLoc = Tok.getLocation();
   1240   Tok.startToken();
   1241   Tok.setKind(tok::annot_pragma_openmp_end);
   1242   Tok.setLocation(EodLoc);
   1243   Pragma.push_back(Tok);
   1244 
   1245   Token *Toks = new Token[Pragma.size()];
   1246   std::copy(Pragma.begin(), Pragma.end(), Toks);
   1247   PP.EnterTokenStream(Toks, Pragma.size(),
   1248                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
   1249 }
   1250 
   1251 /// \brief Handle '#pragma pointers_to_members'
   1252 // The grammar for this pragma is as follows:
   1253 //
   1254 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
   1255 //
   1256 // #pragma pointers_to_members '(' 'best_case' ')'
   1257 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
   1258 // #pragma pointers_to_members '(' inheritance-model ')'
   1259 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
   1260                                              PragmaIntroducerKind Introducer,
   1261                                              Token &Tok) {
   1262   SourceLocation PointersToMembersLoc = Tok.getLocation();
   1263   PP.Lex(Tok);
   1264   if (Tok.isNot(tok::l_paren)) {
   1265     PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
   1266       << "pointers_to_members";
   1267     return;
   1268   }
   1269   PP.Lex(Tok);
   1270   const IdentifierInfo *Arg = Tok.getIdentifierInfo();
   1271   if (!Arg) {
   1272     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
   1273       << "pointers_to_members";
   1274     return;
   1275   }
   1276   PP.Lex(Tok);
   1277 
   1278   LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
   1279   if (Arg->isStr("best_case")) {
   1280     RepresentationMethod = LangOptions::PPTMK_BestCase;
   1281   } else {
   1282     if (Arg->isStr("full_generality")) {
   1283       if (Tok.is(tok::comma)) {
   1284         PP.Lex(Tok);
   1285 
   1286         Arg = Tok.getIdentifierInfo();
   1287         if (!Arg) {
   1288           PP.Diag(Tok.getLocation(),
   1289                   diag::err_pragma_pointers_to_members_unknown_kind)
   1290               << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
   1291           return;
   1292         }
   1293         PP.Lex(Tok);
   1294       } else if (Tok.is(tok::r_paren)) {
   1295         // #pragma pointers_to_members(full_generality) implicitly specifies
   1296         // virtual_inheritance.
   1297         Arg = nullptr;
   1298         RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
   1299       } else {
   1300         PP.Diag(Tok.getLocation(), diag::err_expected_punc)
   1301             << "full_generality";
   1302         return;
   1303       }
   1304     }
   1305 
   1306     if (Arg) {
   1307       if (Arg->isStr("single_inheritance")) {
   1308         RepresentationMethod =
   1309             LangOptions::PPTMK_FullGeneralitySingleInheritance;
   1310       } else if (Arg->isStr("multiple_inheritance")) {
   1311         RepresentationMethod =
   1312             LangOptions::PPTMK_FullGeneralityMultipleInheritance;
   1313       } else if (Arg->isStr("virtual_inheritance")) {
   1314         RepresentationMethod =
   1315             LangOptions::PPTMK_FullGeneralityVirtualInheritance;
   1316       } else {
   1317         PP.Diag(Tok.getLocation(),
   1318                 diag::err_pragma_pointers_to_members_unknown_kind)
   1319             << Arg << /*HasPointerDeclaration*/ 1;
   1320         return;
   1321       }
   1322     }
   1323   }
   1324 
   1325   if (Tok.isNot(tok::r_paren)) {
   1326     PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
   1327         << (Arg ? Arg->getName() : "full_generality");
   1328     return;
   1329   }
   1330 
   1331   PP.Lex(Tok);
   1332   if (Tok.isNot(tok::eod)) {
   1333     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
   1334       << "pointers_to_members";
   1335     return;
   1336   }
   1337 
   1338   Token AnnotTok;
   1339   AnnotTok.startToken();
   1340   AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
   1341   AnnotTok.setLocation(PointersToMembersLoc);
   1342   AnnotTok.setAnnotationValue(
   1343       reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
   1344   PP.EnterToken(AnnotTok);
   1345 }
   1346 
   1347 /// \brief Handle '#pragma vtordisp'
   1348 // The grammar for this pragma is as follows:
   1349 //
   1350 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
   1351 //
   1352 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
   1353 // #pragma vtordisp '(' 'pop' ')'
   1354 // #pragma vtordisp '(' ')'
   1355 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
   1356                                     PragmaIntroducerKind Introducer,
   1357                                     Token &Tok) {
   1358   SourceLocation VtorDispLoc = Tok.getLocation();
   1359   PP.Lex(Tok);
   1360   if (Tok.isNot(tok::l_paren)) {
   1361     PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
   1362     return;
   1363   }
   1364   PP.Lex(Tok);
   1365 
   1366   Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
   1367   const IdentifierInfo *II = Tok.getIdentifierInfo();
   1368   if (II) {
   1369     if (II->isStr("push")) {
   1370       // #pragma vtordisp(push, mode)
   1371       PP.Lex(Tok);
   1372       if (Tok.isNot(tok::comma)) {
   1373         PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
   1374         return;
   1375       }
   1376       PP.Lex(Tok);
   1377       Kind = Sema::PVDK_Push;
   1378       // not push, could be on/off
   1379     } else if (II->isStr("pop")) {
   1380       // #pragma vtordisp(pop)
   1381       PP.Lex(Tok);
   1382       Kind = Sema::PVDK_Pop;
   1383     }
   1384     // not push or pop, could be on/off
   1385   } else {
   1386     if (Tok.is(tok::r_paren)) {
   1387       // #pragma vtordisp()
   1388       Kind = Sema::PVDK_Reset;
   1389     }
   1390   }
   1391 
   1392 
   1393   uint64_t Value = 0;
   1394   if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
   1395     const IdentifierInfo *II = Tok.getIdentifierInfo();
   1396     if (II && II->isStr("off")) {
   1397       PP.Lex(Tok);
   1398       Value = 0;
   1399     } else if (II && II->isStr("on")) {
   1400       PP.Lex(Tok);
   1401       Value = 1;
   1402     } else if (Tok.is(tok::numeric_constant) &&
   1403                PP.parseSimpleIntegerLiteral(Tok, Value)) {
   1404       if (Value > 2) {
   1405         PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
   1406             << 0 << 2 << "vtordisp";
   1407         return;
   1408       }
   1409     } else {
   1410       PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
   1411           << "vtordisp";
   1412       return;
   1413     }
   1414   }
   1415 
   1416   // Finish the pragma: ')' $
   1417   if (Tok.isNot(tok::r_paren)) {
   1418     PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
   1419     return;
   1420   }
   1421   PP.Lex(Tok);
   1422   if (Tok.isNot(tok::eod)) {
   1423     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
   1424         << "vtordisp";
   1425     return;
   1426   }
   1427 
   1428   // Enter the annotation.
   1429   Token AnnotTok;
   1430   AnnotTok.startToken();
   1431   AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
   1432   AnnotTok.setLocation(VtorDispLoc);
   1433   AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
   1434       static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
   1435   PP.EnterToken(AnnotTok);
   1436 }
   1437 
   1438 /// \brief Handle all MS pragmas.  Simply forwards the tokens after inserting
   1439 /// an annotation token.
   1440 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
   1441                                   PragmaIntroducerKind Introducer,
   1442                                   Token &Tok) {
   1443   Token EoF, AnnotTok;
   1444   EoF.startToken();
   1445   EoF.setKind(tok::eof);
   1446   AnnotTok.startToken();
   1447   AnnotTok.setKind(tok::annot_pragma_ms_pragma);
   1448   AnnotTok.setLocation(Tok.getLocation());
   1449   SmallVector<Token, 8> TokenVector;
   1450   // Suck up all of the tokens before the eod.
   1451   for (; Tok.isNot(tok::eod); PP.Lex(Tok))
   1452     TokenVector.push_back(Tok);
   1453   // Add a sentinal EoF token to the end of the list.
   1454   TokenVector.push_back(EoF);
   1455   // We must allocate this array with new because EnterTokenStream is going to
   1456   // delete it later.
   1457   Token *TokenArray = new Token[TokenVector.size()];
   1458   std::copy(TokenVector.begin(), TokenVector.end(), TokenArray);
   1459   auto Value = new (PP.getPreprocessorAllocator())
   1460       std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
   1461   AnnotTok.setAnnotationValue(Value);
   1462   PP.EnterToken(AnnotTok);
   1463 }
   1464 
   1465 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
   1466 ///
   1467 /// The syntax is:
   1468 /// \code
   1469 ///   #pragma detect_mismatch("name", "value")
   1470 /// \endcode
   1471 /// Where 'name' and 'value' are quoted strings.  The values are embedded in
   1472 /// the object file and passed along to the linker.  If the linker detects a
   1473 /// mismatch in the object file's values for the given name, a LNK2038 error
   1474 /// is emitted.  See MSDN for more details.
   1475 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
   1476                                                PragmaIntroducerKind Introducer,
   1477                                                Token &Tok) {
   1478   SourceLocation CommentLoc = Tok.getLocation();
   1479   PP.Lex(Tok);
   1480   if (Tok.isNot(tok::l_paren)) {
   1481     PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
   1482     return;
   1483   }
   1484 
   1485   // Read the name to embed, which must be a string literal.
   1486   std::string NameString;
   1487   if (!PP.LexStringLiteral(Tok, NameString,
   1488                            "pragma detect_mismatch",
   1489                            /*MacroExpansion=*/true))
   1490     return;
   1491 
   1492   // Read the comma followed by a second string literal.
   1493   std::string ValueString;
   1494   if (Tok.isNot(tok::comma)) {
   1495     PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
   1496     return;
   1497   }
   1498 
   1499   if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
   1500                            /*MacroExpansion=*/true))
   1501     return;
   1502 
   1503   if (Tok.isNot(tok::r_paren)) {
   1504     PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
   1505     return;
   1506   }
   1507   PP.Lex(Tok);  // Eat the r_paren.
   1508 
   1509   if (Tok.isNot(tok::eod)) {
   1510     PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
   1511     return;
   1512   }
   1513 
   1514   // If the pragma is lexically sound, notify any interested PPCallbacks.
   1515   if (PP.getPPCallbacks())
   1516     PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString,
   1517                                               ValueString);
   1518 
   1519   Actions.ActOnPragmaDetectMismatch(NameString, ValueString);
   1520 }
   1521 
   1522 /// \brief Handle the microsoft \#pragma comment extension.
   1523 ///
   1524 /// The syntax is:
   1525 /// \code
   1526 ///   #pragma comment(linker, "foo")
   1527 /// \endcode
   1528 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
   1529 /// "foo" is a string, which is fully macro expanded, and permits string
   1530 /// concatenation, embedded escape characters etc.  See MSDN for more details.
   1531 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
   1532                                         PragmaIntroducerKind Introducer,
   1533                                         Token &Tok) {
   1534   SourceLocation CommentLoc = Tok.getLocation();
   1535   PP.Lex(Tok);
   1536   if (Tok.isNot(tok::l_paren)) {
   1537     PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
   1538     return;
   1539   }
   1540 
   1541   // Read the identifier.
   1542   PP.Lex(Tok);
   1543   if (Tok.isNot(tok::identifier)) {
   1544     PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
   1545     return;
   1546   }
   1547 
   1548   // Verify that this is one of the 5 whitelisted options.
   1549   IdentifierInfo *II = Tok.getIdentifierInfo();
   1550   Sema::PragmaMSCommentKind Kind =
   1551     llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())
   1552     .Case("linker",   Sema::PCK_Linker)
   1553     .Case("lib",      Sema::PCK_Lib)
   1554     .Case("compiler", Sema::PCK_Compiler)
   1555     .Case("exestr",   Sema::PCK_ExeStr)
   1556     .Case("user",     Sema::PCK_User)
   1557     .Default(Sema::PCK_Unknown);
   1558   if (Kind == Sema::PCK_Unknown) {
   1559     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
   1560     return;
   1561   }
   1562 
   1563   // Read the optional string if present.
   1564   PP.Lex(Tok);
   1565   std::string ArgumentString;
   1566   if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
   1567                                                  "pragma comment",
   1568                                                  /*MacroExpansion=*/true))
   1569     return;
   1570 
   1571   // FIXME: warn that 'exestr' is deprecated.
   1572   // FIXME: If the kind is "compiler" warn if the string is present (it is
   1573   // ignored).
   1574   // The MSDN docs say that "lib" and "linker" require a string and have a short
   1575   // whitelist of linker options they support, but in practice MSVC doesn't
   1576   // issue a diagnostic.  Therefore neither does clang.
   1577 
   1578   if (Tok.isNot(tok::r_paren)) {
   1579     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
   1580     return;
   1581   }
   1582   PP.Lex(Tok);  // eat the r_paren.
   1583 
   1584   if (Tok.isNot(tok::eod)) {
   1585     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
   1586     return;
   1587   }
   1588 
   1589   // If the pragma is lexically sound, notify any interested PPCallbacks.
   1590   if (PP.getPPCallbacks())
   1591     PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
   1592 
   1593   Actions.ActOnPragmaMSComment(Kind, ArgumentString);
   1594 }
   1595 
   1596 // #pragma clang optimize off
   1597 // #pragma clang optimize on
   1598 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
   1599                                         PragmaIntroducerKind Introducer,
   1600                                         Token &FirstToken) {
   1601   Token Tok;
   1602   PP.Lex(Tok);
   1603   if (Tok.is(tok::eod)) {
   1604     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_missing_argument);
   1605     return;
   1606   }
   1607   if (Tok.isNot(tok::identifier)) {
   1608     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
   1609       << PP.getSpelling(Tok);
   1610     return;
   1611   }
   1612   const IdentifierInfo *II = Tok.getIdentifierInfo();
   1613   // The only accepted values are 'on' or 'off'.
   1614   bool IsOn = false;
   1615   if (II->isStr("on")) {
   1616     IsOn = true;
   1617   } else if (!II->isStr("off")) {
   1618     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
   1619       << PP.getSpelling(Tok);
   1620     return;
   1621   }
   1622   PP.Lex(Tok);
   1623 
   1624   if (Tok.isNot(tok::eod)) {
   1625     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
   1626       << PP.getSpelling(Tok);
   1627     return;
   1628   }
   1629 
   1630   Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
   1631 }
   1632 
   1633 /// \brief Handle the \#pragma clang loop directive.
   1634 ///  #pragma clang 'loop' loop-hints
   1635 ///
   1636 ///  loop-hints:
   1637 ///    loop-hint loop-hints[opt]
   1638 ///
   1639 ///  loop-hint:
   1640 ///    'vectorize' '(' loop-hint-keyword ')'
   1641 ///    'interleave' '(' loop-hint-keyword ')'
   1642 ///    'unroll' '(' loop-hint-keyword ')'
   1643 ///    'vectorize_width' '(' loop-hint-value ')'
   1644 ///    'interleave_count' '(' loop-hint-value ')'
   1645 ///    'unroll_count' '(' loop-hint-value ')'
   1646 ///
   1647 ///  loop-hint-keyword:
   1648 ///    'enable'
   1649 ///    'disable'
   1650 ///
   1651 ///  loop-hint-value:
   1652 ///    constant-expression
   1653 ///
   1654 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
   1655 /// try vectorizing the instructions of the loop it precedes. Specifying
   1656 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
   1657 /// interleaving multiple iterations of the loop it precedes. The width of the
   1658 /// vector instructions is specified by vectorize_width() and the number of
   1659 /// interleaved loop iterations is specified by interleave_count(). Specifying a
   1660 /// value of 1 effectively disables vectorization/interleaving, even if it is
   1661 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
   1662 /// only works on inner loops.
   1663 ///
   1664 /// The unroll and unroll_count directives control the concatenation
   1665 /// unroller. Specifying unroll(enable) instructs llvm to try to
   1666 /// unroll the loop completely, and unroll(disable) disables unrolling
   1667 /// for the loop. Specifying unroll_count(_value_) instructs llvm to
   1668 /// try to unroll the loop the number of times indicated by the value.
   1669 /// If unroll(enable) and unroll_count are both specified only
   1670 /// unroll_count takes effect.
   1671 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
   1672                                          PragmaIntroducerKind Introducer,
   1673                                          Token &Tok) {
   1674   Token Loop = Tok;
   1675   SmallVector<Token, 1> TokenList;
   1676 
   1677   // Lex the optimization option and verify it is an identifier.
   1678   PP.Lex(Tok);
   1679   if (Tok.isNot(tok::identifier)) {
   1680     PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
   1681         << /*MissingOption=*/true << "";
   1682     return;
   1683   }
   1684 
   1685   while (Tok.is(tok::identifier)) {
   1686     Token Option = Tok;
   1687     IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
   1688 
   1689     bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
   1690         .Case("vectorize", true)
   1691         .Case("interleave", true)
   1692         .Case("unroll", true)
   1693         .Case("vectorize_width", true)
   1694         .Case("interleave_count", true)
   1695         .Case("unroll_count", true)
   1696         .Default(false);
   1697     if (!OptionValid) {
   1698       PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
   1699           << /*MissingOption=*/false << OptionInfo;
   1700       return;
   1701     }
   1702 
   1703     // Read '('
   1704     PP.Lex(Tok);
   1705     if (Tok.isNot(tok::l_paren)) {
   1706       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
   1707       return;
   1708     }
   1709 
   1710     // FIXME: All tokens between '(' and ')' should be stored and parsed as a
   1711     // constant expression.
   1712     PP.Lex(Tok);
   1713     if (Tok.is(tok::r_paren)) {
   1714       // Nothing between the parentheses.
   1715       PP.Diag(Tok.getLocation(), diag::err_pragma_loop_missing_argument)
   1716           << OptionInfo;
   1717       return;
   1718     }
   1719     Token Value = Tok;
   1720 
   1721     // Read ')'
   1722     PP.Lex(Tok);
   1723     if (Tok.isNot(tok::r_paren)) {
   1724       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
   1725       return;
   1726     }
   1727 
   1728     // Get next optimization option.
   1729     PP.Lex(Tok);
   1730 
   1731     auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
   1732     Info->Loop = Loop;
   1733     Info->Option = Option;
   1734     Info->Value = Value;
   1735 
   1736     // Generate the vectorization hint token.
   1737     Token LoopHintTok;
   1738     LoopHintTok.startToken();
   1739     LoopHintTok.setKind(tok::annot_pragma_loop_hint);
   1740     LoopHintTok.setLocation(Loop.getLocation());
   1741     LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
   1742     TokenList.push_back(LoopHintTok);
   1743   }
   1744 
   1745   if (Tok.isNot(tok::eod)) {
   1746     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
   1747         << "clang loop";
   1748     return;
   1749   }
   1750 
   1751   Token *TokenArray = new Token[TokenList.size()];
   1752   std::copy(TokenList.begin(), TokenList.end(), TokenArray);
   1753 
   1754   PP.EnterTokenStream(TokenArray, TokenList.size(),
   1755                       /*DisableMacroExpansion=*/false,
   1756                       /*OwnsTokens=*/true);
   1757 }
   1758