clang API Documentation

ParsePragma.cpp
Go to the documentation of this file.
00001 //===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the language specific #pragma handlers.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "RAIIObjectsForParser.h"
00015 #include "clang/AST/ASTContext.h"
00016 #include "clang/Basic/TargetInfo.h"
00017 #include "clang/Lex/Preprocessor.h"
00018 #include "clang/Parse/ParseDiagnostic.h"
00019 #include "clang/Parse/Parser.h"
00020 #include "clang/Sema/LoopHint.h"
00021 #include "clang/Sema/Scope.h"
00022 #include "llvm/ADT/StringSwitch.h"
00023 using namespace clang;
00024 
00025 namespace {
00026 
00027 struct PragmaAlignHandler : public PragmaHandler {
00028   explicit PragmaAlignHandler() : PragmaHandler("align") {}
00029   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00030                     Token &FirstToken) override;
00031 };
00032 
00033 struct PragmaGCCVisibilityHandler : public PragmaHandler {
00034   explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
00035   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00036                     Token &FirstToken) override;
00037 };
00038 
00039 struct PragmaOptionsHandler : public PragmaHandler {
00040   explicit PragmaOptionsHandler() : PragmaHandler("options") {}
00041   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00042                     Token &FirstToken) override;
00043 };
00044 
00045 struct PragmaPackHandler : public PragmaHandler {
00046   explicit PragmaPackHandler() : PragmaHandler("pack") {}
00047   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00048                     Token &FirstToken) override;
00049 };
00050 
00051 struct PragmaMSStructHandler : public PragmaHandler {
00052   explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
00053   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00054                     Token &FirstToken) override;
00055 };
00056 
00057 struct PragmaUnusedHandler : public PragmaHandler {
00058   PragmaUnusedHandler() : PragmaHandler("unused") {}
00059   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00060                     Token &FirstToken) override;
00061 };
00062 
00063 struct PragmaWeakHandler : public PragmaHandler {
00064   explicit PragmaWeakHandler() : PragmaHandler("weak") {}
00065   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00066                     Token &FirstToken) override;
00067 };
00068 
00069 struct PragmaRedefineExtnameHandler : public PragmaHandler {
00070   explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
00071   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00072                     Token &FirstToken) override;
00073 };
00074 
00075 struct PragmaOpenCLExtensionHandler : public PragmaHandler {
00076   PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
00077   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00078                     Token &FirstToken) override;
00079 };
00080 
00081 
00082 struct PragmaFPContractHandler : public PragmaHandler {
00083   PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
00084   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00085                     Token &FirstToken) override;
00086 };
00087 
00088 struct PragmaNoOpenMPHandler : public PragmaHandler {
00089   PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
00090   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00091                     Token &FirstToken) override;
00092 };
00093 
00094 struct PragmaOpenMPHandler : public PragmaHandler {
00095   PragmaOpenMPHandler() : PragmaHandler("omp") { }
00096   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00097                     Token &FirstToken) override;
00098 };
00099 
00100 /// PragmaCommentHandler - "\#pragma comment ...".
00101 struct PragmaCommentHandler : public PragmaHandler {
00102   PragmaCommentHandler(Sema &Actions)
00103     : PragmaHandler("comment"), Actions(Actions) {}
00104   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00105                     Token &FirstToken) override;
00106 private:
00107   Sema &Actions;
00108 };
00109 
00110 struct PragmaDetectMismatchHandler : public PragmaHandler {
00111   PragmaDetectMismatchHandler(Sema &Actions)
00112     : PragmaHandler("detect_mismatch"), Actions(Actions) {}
00113   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00114                     Token &FirstToken) override;
00115 private:
00116   Sema &Actions;
00117 };
00118 
00119 struct PragmaMSPointersToMembers : public PragmaHandler {
00120   explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
00121   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00122                     Token &FirstToken) override;
00123 };
00124 
00125 struct PragmaMSVtorDisp : public PragmaHandler {
00126   explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
00127   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00128                     Token &FirstToken) override;
00129 };
00130 
00131 struct PragmaMSPragma : public PragmaHandler {
00132   explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
00133   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00134                     Token &FirstToken) override;
00135 };
00136 
00137 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
00138 struct PragmaOptimizeHandler : public PragmaHandler {
00139   PragmaOptimizeHandler(Sema &S)
00140     : PragmaHandler("optimize"), Actions(S) {}
00141   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00142                     Token &FirstToken) override;
00143 private:
00144   Sema &Actions;
00145 };
00146 
00147 struct PragmaLoopHintHandler : public PragmaHandler {
00148   PragmaLoopHintHandler() : PragmaHandler("loop") {}
00149   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00150                     Token &FirstToken) override;
00151 };
00152 
00153 struct PragmaUnrollHintHandler : public PragmaHandler {
00154   PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
00155   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
00156                     Token &FirstToken) override;
00157 };
00158 
00159 }  // end namespace
00160 
00161 void Parser::initializePragmaHandlers() {
00162   AlignHandler.reset(new PragmaAlignHandler());
00163   PP.AddPragmaHandler(AlignHandler.get());
00164 
00165   GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
00166   PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
00167 
00168   OptionsHandler.reset(new PragmaOptionsHandler());
00169   PP.AddPragmaHandler(OptionsHandler.get());
00170 
00171   PackHandler.reset(new PragmaPackHandler());
00172   PP.AddPragmaHandler(PackHandler.get());
00173 
00174   MSStructHandler.reset(new PragmaMSStructHandler());
00175   PP.AddPragmaHandler(MSStructHandler.get());
00176 
00177   UnusedHandler.reset(new PragmaUnusedHandler());
00178   PP.AddPragmaHandler(UnusedHandler.get());
00179 
00180   WeakHandler.reset(new PragmaWeakHandler());
00181   PP.AddPragmaHandler(WeakHandler.get());
00182 
00183   RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
00184   PP.AddPragmaHandler(RedefineExtnameHandler.get());
00185 
00186   FPContractHandler.reset(new PragmaFPContractHandler());
00187   PP.AddPragmaHandler("STDC", FPContractHandler.get());
00188 
00189   if (getLangOpts().OpenCL) {
00190     OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
00191     PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
00192 
00193     PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
00194   }
00195   if (getLangOpts().OpenMP)
00196     OpenMPHandler.reset(new PragmaOpenMPHandler());
00197   else
00198     OpenMPHandler.reset(new PragmaNoOpenMPHandler());
00199   PP.AddPragmaHandler(OpenMPHandler.get());
00200 
00201   if (getLangOpts().MicrosoftExt) {
00202     MSCommentHandler.reset(new PragmaCommentHandler(Actions));
00203     PP.AddPragmaHandler(MSCommentHandler.get());
00204     MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
00205     PP.AddPragmaHandler(MSDetectMismatchHandler.get());
00206     MSPointersToMembers.reset(new PragmaMSPointersToMembers());
00207     PP.AddPragmaHandler(MSPointersToMembers.get());
00208     MSVtorDisp.reset(new PragmaMSVtorDisp());
00209     PP.AddPragmaHandler(MSVtorDisp.get());
00210     MSInitSeg.reset(new PragmaMSPragma("init_seg"));
00211     PP.AddPragmaHandler(MSInitSeg.get());
00212     MSDataSeg.reset(new PragmaMSPragma("data_seg"));
00213     PP.AddPragmaHandler(MSDataSeg.get());
00214     MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
00215     PP.AddPragmaHandler(MSBSSSeg.get());
00216     MSConstSeg.reset(new PragmaMSPragma("const_seg"));
00217     PP.AddPragmaHandler(MSConstSeg.get());
00218     MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
00219     PP.AddPragmaHandler(MSCodeSeg.get());
00220     MSSection.reset(new PragmaMSPragma("section"));
00221     PP.AddPragmaHandler(MSSection.get());
00222   }
00223 
00224   OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
00225   PP.AddPragmaHandler("clang", OptimizeHandler.get());
00226 
00227   LoopHintHandler.reset(new PragmaLoopHintHandler());
00228   PP.AddPragmaHandler("clang", LoopHintHandler.get());
00229 
00230   UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
00231   PP.AddPragmaHandler(UnrollHintHandler.get());
00232 
00233   NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
00234   PP.AddPragmaHandler(NoUnrollHintHandler.get());
00235 }
00236 
00237 void Parser::resetPragmaHandlers() {
00238   // Remove the pragma handlers we installed.
00239   PP.RemovePragmaHandler(AlignHandler.get());
00240   AlignHandler.reset();
00241   PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
00242   GCCVisibilityHandler.reset();
00243   PP.RemovePragmaHandler(OptionsHandler.get());
00244   OptionsHandler.reset();
00245   PP.RemovePragmaHandler(PackHandler.get());
00246   PackHandler.reset();
00247   PP.RemovePragmaHandler(MSStructHandler.get());
00248   MSStructHandler.reset();
00249   PP.RemovePragmaHandler(UnusedHandler.get());
00250   UnusedHandler.reset();
00251   PP.RemovePragmaHandler(WeakHandler.get());
00252   WeakHandler.reset();
00253   PP.RemovePragmaHandler(RedefineExtnameHandler.get());
00254   RedefineExtnameHandler.reset();
00255 
00256   if (getLangOpts().OpenCL) {
00257     PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
00258     OpenCLExtensionHandler.reset();
00259     PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
00260   }
00261   PP.RemovePragmaHandler(OpenMPHandler.get());
00262   OpenMPHandler.reset();
00263 
00264   if (getLangOpts().MicrosoftExt) {
00265     PP.RemovePragmaHandler(MSCommentHandler.get());
00266     MSCommentHandler.reset();
00267     PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
00268     MSDetectMismatchHandler.reset();
00269     PP.RemovePragmaHandler(MSPointersToMembers.get());
00270     MSPointersToMembers.reset();
00271     PP.RemovePragmaHandler(MSVtorDisp.get());
00272     MSVtorDisp.reset();
00273     PP.RemovePragmaHandler(MSInitSeg.get());
00274     MSInitSeg.reset();
00275     PP.RemovePragmaHandler(MSDataSeg.get());
00276     MSDataSeg.reset();
00277     PP.RemovePragmaHandler(MSBSSSeg.get());
00278     MSBSSSeg.reset();
00279     PP.RemovePragmaHandler(MSConstSeg.get());
00280     MSConstSeg.reset();
00281     PP.RemovePragmaHandler(MSCodeSeg.get());
00282     MSCodeSeg.reset();
00283     PP.RemovePragmaHandler(MSSection.get());
00284     MSSection.reset();
00285   }
00286 
00287   PP.RemovePragmaHandler("STDC", FPContractHandler.get());
00288   FPContractHandler.reset();
00289 
00290   PP.RemovePragmaHandler("clang", OptimizeHandler.get());
00291   OptimizeHandler.reset();
00292 
00293   PP.RemovePragmaHandler("clang", LoopHintHandler.get());
00294   LoopHintHandler.reset();
00295 
00296   PP.RemovePragmaHandler(UnrollHintHandler.get());
00297   UnrollHintHandler.reset();
00298 
00299   PP.RemovePragmaHandler(NoUnrollHintHandler.get());
00300   NoUnrollHintHandler.reset();
00301 }
00302 
00303 /// \brief Handle the annotation token produced for #pragma unused(...)
00304 ///
00305 /// Each annot_pragma_unused is followed by the argument token so e.g.
00306 /// "#pragma unused(x,y)" becomes:
00307 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
00308 void Parser::HandlePragmaUnused() {
00309   assert(Tok.is(tok::annot_pragma_unused));
00310   SourceLocation UnusedLoc = ConsumeToken();
00311   Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
00312   ConsumeToken(); // The argument token.
00313 }
00314 
00315 void Parser::HandlePragmaVisibility() {
00316   assert(Tok.is(tok::annot_pragma_vis));
00317   const IdentifierInfo *VisType =
00318     static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
00319   SourceLocation VisLoc = ConsumeToken();
00320   Actions.ActOnPragmaVisibility(VisType, VisLoc);
00321 }
00322 
00323 struct PragmaPackInfo {
00324   Sema::PragmaPackKind Kind;
00325   IdentifierInfo *Name;
00326   Token Alignment;
00327   SourceLocation LParenLoc;
00328   SourceLocation RParenLoc;
00329 };
00330 
00331 void Parser::HandlePragmaPack() {
00332   assert(Tok.is(tok::annot_pragma_pack));
00333   PragmaPackInfo *Info =
00334     static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
00335   SourceLocation PragmaLoc = ConsumeToken();
00336   ExprResult Alignment;
00337   if (Info->Alignment.is(tok::numeric_constant)) {
00338     Alignment = Actions.ActOnNumericConstant(Info->Alignment);
00339     if (Alignment.isInvalid())
00340       return;
00341   }
00342   Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
00343                           Info->LParenLoc, Info->RParenLoc);
00344 }
00345 
00346 void Parser::HandlePragmaMSStruct() {
00347   assert(Tok.is(tok::annot_pragma_msstruct));
00348   Sema::PragmaMSStructKind Kind =
00349     static_cast<Sema::PragmaMSStructKind>(
00350     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
00351   Actions.ActOnPragmaMSStruct(Kind);
00352   ConsumeToken(); // The annotation token.
00353 }
00354 
00355 void Parser::HandlePragmaAlign() {
00356   assert(Tok.is(tok::annot_pragma_align));
00357   Sema::PragmaOptionsAlignKind Kind =
00358     static_cast<Sema::PragmaOptionsAlignKind>(
00359     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
00360   SourceLocation PragmaLoc = ConsumeToken();
00361   Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
00362 }
00363 
00364 void Parser::HandlePragmaWeak() {
00365   assert(Tok.is(tok::annot_pragma_weak));
00366   SourceLocation PragmaLoc = ConsumeToken();
00367   Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
00368                             Tok.getLocation());
00369   ConsumeToken(); // The weak name.
00370 }
00371 
00372 void Parser::HandlePragmaWeakAlias() {
00373   assert(Tok.is(tok::annot_pragma_weakalias));
00374   SourceLocation PragmaLoc = ConsumeToken();
00375   IdentifierInfo *WeakName = Tok.getIdentifierInfo();
00376   SourceLocation WeakNameLoc = Tok.getLocation();
00377   ConsumeToken();
00378   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
00379   SourceLocation AliasNameLoc = Tok.getLocation();
00380   ConsumeToken();
00381   Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
00382                                WeakNameLoc, AliasNameLoc);
00383 
00384 }
00385 
00386 void Parser::HandlePragmaRedefineExtname() {
00387   assert(Tok.is(tok::annot_pragma_redefine_extname));
00388   SourceLocation RedefLoc = ConsumeToken();
00389   IdentifierInfo *RedefName = Tok.getIdentifierInfo();
00390   SourceLocation RedefNameLoc = Tok.getLocation();
00391   ConsumeToken();
00392   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
00393   SourceLocation AliasNameLoc = Tok.getLocation();
00394   ConsumeToken();
00395   Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
00396                                      RedefNameLoc, AliasNameLoc);
00397 }
00398 
00399 void Parser::HandlePragmaFPContract() {
00400   assert(Tok.is(tok::annot_pragma_fp_contract));
00401   tok::OnOffSwitch OOS =
00402     static_cast<tok::OnOffSwitch>(
00403     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
00404   Actions.ActOnPragmaFPContract(OOS);
00405   ConsumeToken(); // The annotation token.
00406 }
00407 
00408 StmtResult Parser::HandlePragmaCaptured()
00409 {
00410   assert(Tok.is(tok::annot_pragma_captured));
00411   ConsumeToken();
00412 
00413   if (Tok.isNot(tok::l_brace)) {
00414     PP.Diag(Tok, diag::err_expected) << tok::l_brace;
00415     return StmtError();
00416   }
00417 
00418   SourceLocation Loc = Tok.getLocation();
00419 
00420   ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
00421   Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
00422                                    /*NumParams=*/1);
00423 
00424   StmtResult R = ParseCompoundStatement();
00425   CapturedRegionScope.Exit();
00426 
00427   if (R.isInvalid()) {
00428     Actions.ActOnCapturedRegionError();
00429     return StmtError();
00430   }
00431 
00432   return Actions.ActOnCapturedRegionEnd(R.get());
00433 }
00434 
00435 namespace {
00436   typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
00437 }
00438 
00439 void Parser::HandlePragmaOpenCLExtension() {
00440   assert(Tok.is(tok::annot_pragma_opencl_extension));
00441   OpenCLExtData data =
00442       OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
00443   unsigned state = data.getInt();
00444   IdentifierInfo *ename = data.getPointer();
00445   SourceLocation NameLoc = Tok.getLocation();
00446   ConsumeToken(); // The annotation token.
00447 
00448   OpenCLOptions &f = Actions.getOpenCLOptions();
00449   // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
00450   // overriding all previously issued extension directives, but only if the
00451   // behavior is set to disable."
00452   if (state == 0 && ename->isStr("all")) {
00453 #define OPENCLEXT(nm)   f.nm = 0;
00454 #include "clang/Basic/OpenCLExtensions.def"
00455   }
00456 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
00457 #include "clang/Basic/OpenCLExtensions.def"
00458   else {
00459     PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
00460     return;
00461   }
00462 }
00463 
00464 void Parser::HandlePragmaMSPointersToMembers() {
00465   assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
00466   LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
00467       static_cast<LangOptions::PragmaMSPointersToMembersKind>(
00468           reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
00469   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
00470   Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
00471 }
00472 
00473 void Parser::HandlePragmaMSVtorDisp() {
00474   assert(Tok.is(tok::annot_pragma_ms_vtordisp));
00475   uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
00476   Sema::PragmaVtorDispKind Kind =
00477       static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
00478   MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
00479   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
00480   Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
00481 }
00482 
00483 void Parser::HandlePragmaMSPragma() {
00484   assert(Tok.is(tok::annot_pragma_ms_pragma));
00485   // Grab the tokens out of the annotation and enter them into the stream.
00486   auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
00487   PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
00488   SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
00489   assert(Tok.isAnyIdentifier());
00490   StringRef PragmaName = Tok.getIdentifierInfo()->getName();
00491   PP.Lex(Tok); // pragma kind
00492 
00493   // Figure out which #pragma we're dealing with.  The switch has no default
00494   // because lex shouldn't emit the annotation token for unrecognized pragmas.
00495   typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
00496   PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
00497     .Case("data_seg", &Parser::HandlePragmaMSSegment)
00498     .Case("bss_seg", &Parser::HandlePragmaMSSegment)
00499     .Case("const_seg", &Parser::HandlePragmaMSSegment)
00500     .Case("code_seg", &Parser::HandlePragmaMSSegment)
00501     .Case("section", &Parser::HandlePragmaMSSection)
00502     .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
00503 
00504   if (!(this->*Handler)(PragmaName, PragmaLocation)) {
00505     // Pragma handling failed, and has been diagnosed.  Slurp up the tokens
00506     // until eof (really end of line) to prevent follow-on errors.
00507     while (Tok.isNot(tok::eof))
00508       PP.Lex(Tok);
00509     PP.Lex(Tok);
00510   }
00511 }
00512 
00513 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
00514                                    SourceLocation PragmaLocation) {
00515   if (Tok.isNot(tok::l_paren)) {
00516     PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
00517     return false;
00518   }
00519   PP.Lex(Tok); // (
00520   // Parsing code for pragma section
00521   if (Tok.isNot(tok::string_literal)) {
00522     PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
00523         << PragmaName;
00524     return false;
00525   }
00526   ExprResult StringResult = ParseStringLiteralExpression();
00527   if (StringResult.isInvalid())
00528     return false; // Already diagnosed.
00529   StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
00530   if (SegmentName->getCharByteWidth() != 1) {
00531     PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
00532         << PragmaName;
00533     return false;
00534   }
00535   int SectionFlags = ASTContext::PSF_Read;
00536   bool SectionFlagsAreDefault = true;
00537   while (Tok.is(tok::comma)) {
00538     PP.Lex(Tok); // ,
00539     // Ignore "long" and "short".
00540     // They are undocumented, but widely used, section attributes which appear
00541     // to do nothing.
00542     if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
00543       PP.Lex(Tok); // long/short
00544       continue;
00545     }
00546 
00547     if (!Tok.isAnyIdentifier()) {
00548       PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
00549           << PragmaName;
00550       return false;
00551     }
00552     ASTContext::PragmaSectionFlag Flag =
00553       llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
00554       Tok.getIdentifierInfo()->getName())
00555       .Case("read", ASTContext::PSF_Read)
00556       .Case("write", ASTContext::PSF_Write)
00557       .Case("execute", ASTContext::PSF_Execute)
00558       .Case("shared", ASTContext::PSF_Invalid)
00559       .Case("nopage", ASTContext::PSF_Invalid)
00560       .Case("nocache", ASTContext::PSF_Invalid)
00561       .Case("discard", ASTContext::PSF_Invalid)
00562       .Case("remove", ASTContext::PSF_Invalid)
00563       .Default(ASTContext::PSF_None);
00564     if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
00565       PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
00566                                   ? diag::warn_pragma_invalid_specific_action
00567                                   : diag::warn_pragma_unsupported_action)
00568           << PragmaName << Tok.getIdentifierInfo()->getName();
00569       return false;
00570     }
00571     SectionFlags |= Flag;
00572     SectionFlagsAreDefault = false;
00573     PP.Lex(Tok); // Identifier
00574   }
00575   // If no section attributes are specified, the section will be marked as
00576   // read/write.
00577   if (SectionFlagsAreDefault)
00578     SectionFlags |= ASTContext::PSF_Write;
00579   if (Tok.isNot(tok::r_paren)) {
00580     PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
00581     return false;
00582   }
00583   PP.Lex(Tok); // )
00584   if (Tok.isNot(tok::eof)) {
00585     PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
00586         << PragmaName;
00587     return false;
00588   }
00589   PP.Lex(Tok); // eof
00590   Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
00591   return true;
00592 }
00593 
00594 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
00595                                    SourceLocation PragmaLocation) {
00596   if (Tok.isNot(tok::l_paren)) {
00597     PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
00598     return false;
00599   }
00600   PP.Lex(Tok); // (
00601   Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
00602   StringRef SlotLabel;
00603   if (Tok.isAnyIdentifier()) {
00604     StringRef PushPop = Tok.getIdentifierInfo()->getName();
00605     if (PushPop == "push")
00606       Action = Sema::PSK_Push;
00607     else if (PushPop == "pop")
00608       Action = Sema::PSK_Pop;
00609     else {
00610       PP.Diag(PragmaLocation,
00611               diag::warn_pragma_expected_section_push_pop_or_name)
00612           << PragmaName;
00613       return false;
00614     }
00615     if (Action != Sema::PSK_Reset) {
00616       PP.Lex(Tok); // push | pop
00617       if (Tok.is(tok::comma)) {
00618         PP.Lex(Tok); // ,
00619         // If we've got a comma, we either need a label or a string.
00620         if (Tok.isAnyIdentifier()) {
00621           SlotLabel = Tok.getIdentifierInfo()->getName();
00622           PP.Lex(Tok); // identifier
00623           if (Tok.is(tok::comma))
00624             PP.Lex(Tok);
00625           else if (Tok.isNot(tok::r_paren)) {
00626             PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
00627                 << PragmaName;
00628             return false;
00629           }
00630         }
00631       } else if (Tok.isNot(tok::r_paren)) {
00632         PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
00633         return false;
00634       }
00635     }
00636   }
00637   // Grab the string literal for our section name.
00638   StringLiteral *SegmentName = nullptr;
00639   if (Tok.isNot(tok::r_paren)) {
00640     if (Tok.isNot(tok::string_literal)) {
00641       unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
00642           diag::warn_pragma_expected_section_name :
00643           diag::warn_pragma_expected_section_label_or_name :
00644           diag::warn_pragma_expected_section_push_pop_or_name;
00645       PP.Diag(PragmaLocation, DiagID) << PragmaName;
00646       return false;
00647     }
00648     ExprResult StringResult = ParseStringLiteralExpression();
00649     if (StringResult.isInvalid())
00650       return false; // Already diagnosed.
00651     SegmentName = cast<StringLiteral>(StringResult.get());
00652     if (SegmentName->getCharByteWidth() != 1) {
00653       PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
00654           << PragmaName;
00655       return false;
00656     }
00657     // Setting section "" has no effect
00658     if (SegmentName->getLength())
00659       Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
00660   }
00661   if (Tok.isNot(tok::r_paren)) {
00662     PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
00663     return false;
00664   }
00665   PP.Lex(Tok); // )
00666   if (Tok.isNot(tok::eof)) {
00667     PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
00668         << PragmaName;
00669     return false;
00670   }
00671   PP.Lex(Tok); // eof
00672   Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
00673                            SegmentName, PragmaName);
00674   return true;
00675 }
00676 
00677 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
00678 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
00679                                    SourceLocation PragmaLocation) {
00680   if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
00681     PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
00682     return false;
00683   }
00684 
00685   if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
00686                        PragmaName))
00687     return false;
00688 
00689   // Parse either the known section names or the string section name.
00690   StringLiteral *SegmentName = nullptr;
00691   if (Tok.isAnyIdentifier()) {
00692     auto *II = Tok.getIdentifierInfo();
00693     StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
00694                             .Case("compiler", "\".CRT$XCC\"")
00695                             .Case("lib", "\".CRT$XCL\"")
00696                             .Case("user", "\".CRT$XCU\"")
00697                             .Default("");
00698 
00699     if (!Section.empty()) {
00700       // Pretend the user wrote the appropriate string literal here.
00701       Token Toks[1];
00702       Toks[0].startToken();
00703       Toks[0].setKind(tok::string_literal);
00704       Toks[0].setLocation(Tok.getLocation());
00705       Toks[0].setLiteralData(Section.data());
00706       Toks[0].setLength(Section.size());
00707       SegmentName =
00708           cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
00709       PP.Lex(Tok);
00710     }
00711   } else if (Tok.is(tok::string_literal)) {
00712     ExprResult StringResult = ParseStringLiteralExpression();
00713     if (StringResult.isInvalid())
00714       return false;
00715     SegmentName = cast<StringLiteral>(StringResult.get());
00716     if (SegmentName->getCharByteWidth() != 1) {
00717       PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
00718           << PragmaName;
00719       return false;
00720     }
00721     // FIXME: Add support for the '[, func-name]' part of the pragma.
00722   }
00723 
00724   if (!SegmentName) {
00725     PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
00726     return false;
00727   }
00728 
00729   if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
00730                        PragmaName) ||
00731       ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
00732                        PragmaName))
00733     return false;
00734 
00735   Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
00736   return true;
00737 }
00738 
00739 struct PragmaLoopHintInfo {
00740   Token PragmaName;
00741   Token Option;
00742   Token *Toks;
00743   size_t TokSize;
00744   PragmaLoopHintInfo() : Toks(nullptr), TokSize(0) {}
00745 };
00746 
00747 static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
00748   std::string PragmaString;
00749   if (PragmaName.getIdentifierInfo()->getName() == "loop") {
00750     PragmaString = "clang loop ";
00751     PragmaString += Option.getIdentifierInfo()->getName();
00752   } else {
00753     assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
00754            "Unexpected pragma name");
00755     PragmaString = "unroll";
00756   }
00757   return PragmaString;
00758 }
00759 
00760 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
00761   assert(Tok.is(tok::annot_pragma_loop_hint));
00762   PragmaLoopHintInfo *Info =
00763       static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
00764 
00765   IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
00766   Hint.PragmaNameLoc = IdentifierLoc::create(
00767       Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
00768 
00769   // It is possible that the loop hint has no option identifier, such as
00770   // #pragma unroll(4).
00771   IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
00772                                    ? Info->Option.getIdentifierInfo()
00773                                    : nullptr;
00774   Hint.OptionLoc = IdentifierLoc::create(
00775       Actions.Context, Info->Option.getLocation(), OptionInfo);
00776 
00777   Token *Toks = Info->Toks;
00778   size_t TokSize = Info->TokSize;
00779 
00780   // Return a valid hint if pragma unroll or nounroll were specified
00781   // without an argument.
00782   bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
00783   bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
00784   if (TokSize == 0 && (PragmaUnroll || PragmaNoUnroll)) {
00785     ConsumeToken(); // The annotation token.
00786     Hint.Range = Info->PragmaName.getLocation();
00787     return true;
00788   }
00789 
00790   // The constant expression is always followed by an eof token, which increases
00791   // the TokSize by 1.
00792   assert(TokSize > 0 &&
00793          "PragmaLoopHintInfo::Toks must contain at least one token.");
00794 
00795   // If no option is specified the argument is assumed to be a constant expr.
00796   bool StateOption = false;
00797   if (OptionInfo) { // Pragma unroll does not specify an option.
00798     StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
00799                       .Case("vectorize", true)
00800                       .Case("interleave", true)
00801                       .Case("unroll", true)
00802                       .Default(false);
00803   }
00804 
00805   // Verify loop hint has an argument.
00806   if (Toks[0].is(tok::eof)) {
00807     ConsumeToken(); // The annotation token.
00808     Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
00809         << /*StateArgument=*/StateOption << /*FullKeyword=*/PragmaUnroll;
00810     return false;
00811   }
00812 
00813   // Validate the argument.
00814   if (StateOption) {
00815     ConsumeToken(); // The annotation token.
00816     bool OptionUnroll = OptionInfo->isStr("unroll");
00817     SourceLocation StateLoc = Toks[0].getLocation();
00818     IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
00819     if (!StateInfo || ((OptionUnroll ? !StateInfo->isStr("full")
00820                                      : !StateInfo->isStr("enable")) &&
00821                        !StateInfo->isStr("disable"))) {
00822       Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
00823           << /*FullKeyword=*/OptionUnroll;
00824       return false;
00825     }
00826     if (TokSize > 2)
00827       Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
00828           << PragmaLoopHintString(Info->PragmaName, Info->Option);
00829     Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
00830   } else {
00831     // Enter constant expression including eof terminator into token stream.
00832     PP.EnterTokenStream(Toks, TokSize, /*DisableMacroExpansion=*/false,
00833                         /*OwnsTokens=*/false);
00834     ConsumeToken(); // The annotation token.
00835 
00836     ExprResult R = ParseConstantExpression();
00837 
00838     // Tokens following an error in an ill-formed constant expression will
00839     // remain in the token stream and must be removed.
00840     if (Tok.isNot(tok::eof)) {
00841       Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
00842           << PragmaLoopHintString(Info->PragmaName, Info->Option);
00843       while (Tok.isNot(tok::eof))
00844         ConsumeAnyToken();
00845     }
00846 
00847     ConsumeToken(); // Consume the constant expression eof terminator.
00848 
00849     if (R.isInvalid() ||
00850         Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
00851       return false;
00852 
00853     // Argument is a constant expression with an integer type.
00854     Hint.ValueExpr = R.get();
00855   }
00856 
00857   Hint.Range = SourceRange(Info->PragmaName.getLocation(),
00858                            Info->Toks[TokSize - 1].getLocation());
00859   return true;
00860 }
00861 
00862 // #pragma GCC visibility comes in two variants:
00863 //   'push' '(' [visibility] ')'
00864 //   'pop'
00865 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, 
00866                                               PragmaIntroducerKind Introducer,
00867                                               Token &VisTok) {
00868   SourceLocation VisLoc = VisTok.getLocation();
00869 
00870   Token Tok;
00871   PP.LexUnexpandedToken(Tok);
00872 
00873   const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
00874 
00875   const IdentifierInfo *VisType;
00876   if (PushPop && PushPop->isStr("pop")) {
00877     VisType = nullptr;
00878   } else if (PushPop && PushPop->isStr("push")) {
00879     PP.LexUnexpandedToken(Tok);
00880     if (Tok.isNot(tok::l_paren)) {
00881       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
00882         << "visibility";
00883       return;
00884     }
00885     PP.LexUnexpandedToken(Tok);
00886     VisType = Tok.getIdentifierInfo();
00887     if (!VisType) {
00888       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
00889         << "visibility";
00890       return;
00891     }
00892     PP.LexUnexpandedToken(Tok);
00893     if (Tok.isNot(tok::r_paren)) {
00894       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
00895         << "visibility";
00896       return;
00897     }
00898   } else {
00899     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
00900       << "visibility";
00901     return;
00902   }
00903   PP.LexUnexpandedToken(Tok);
00904   if (Tok.isNot(tok::eod)) {
00905     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
00906       << "visibility";
00907     return;
00908   }
00909 
00910   Token *Toks = new Token[1];
00911   Toks[0].startToken();
00912   Toks[0].setKind(tok::annot_pragma_vis);
00913   Toks[0].setLocation(VisLoc);
00914   Toks[0].setAnnotationValue(
00915                           const_cast<void*>(static_cast<const void*>(VisType)));
00916   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
00917                       /*OwnsTokens=*/true);
00918 }
00919 
00920 // #pragma pack(...) comes in the following delicious flavors:
00921 //   pack '(' [integer] ')'
00922 //   pack '(' 'show' ')'
00923 //   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
00924 void PragmaPackHandler::HandlePragma(Preprocessor &PP, 
00925                                      PragmaIntroducerKind Introducer,
00926                                      Token &PackTok) {
00927   SourceLocation PackLoc = PackTok.getLocation();
00928 
00929   Token Tok;
00930   PP.Lex(Tok);
00931   if (Tok.isNot(tok::l_paren)) {
00932     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
00933     return;
00934   }
00935 
00936   Sema::PragmaPackKind Kind = Sema::PPK_Default;
00937   IdentifierInfo *Name = nullptr;
00938   Token Alignment;
00939   Alignment.startToken();
00940   SourceLocation LParenLoc = Tok.getLocation();
00941   PP.Lex(Tok);
00942   if (Tok.is(tok::numeric_constant)) {
00943     Alignment = Tok;
00944 
00945     PP.Lex(Tok);
00946 
00947     // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
00948     // the push/pop stack.
00949     // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
00950     if (PP.getLangOpts().ApplePragmaPack)
00951       Kind = Sema::PPK_Push;
00952   } else if (Tok.is(tok::identifier)) {
00953     const IdentifierInfo *II = Tok.getIdentifierInfo();
00954     if (II->isStr("show")) {
00955       Kind = Sema::PPK_Show;
00956       PP.Lex(Tok);
00957     } else {
00958       if (II->isStr("push")) {
00959         Kind = Sema::PPK_Push;
00960       } else if (II->isStr("pop")) {
00961         Kind = Sema::PPK_Pop;
00962       } else {
00963         PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
00964         return;
00965       }
00966       PP.Lex(Tok);
00967 
00968       if (Tok.is(tok::comma)) {
00969         PP.Lex(Tok);
00970 
00971         if (Tok.is(tok::numeric_constant)) {
00972           Alignment = Tok;
00973 
00974           PP.Lex(Tok);
00975         } else if (Tok.is(tok::identifier)) {
00976           Name = Tok.getIdentifierInfo();
00977           PP.Lex(Tok);
00978 
00979           if (Tok.is(tok::comma)) {
00980             PP.Lex(Tok);
00981 
00982             if (Tok.isNot(tok::numeric_constant)) {
00983               PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
00984               return;
00985             }
00986 
00987             Alignment = Tok;
00988 
00989             PP.Lex(Tok);
00990           }
00991         } else {
00992           PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
00993           return;
00994         }
00995       }
00996     }
00997   } else if (PP.getLangOpts().ApplePragmaPack) {
00998     // In MSVC/gcc, #pragma pack() resets the alignment without affecting
00999     // the push/pop stack.
01000     // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
01001     Kind = Sema::PPK_Pop;
01002   }
01003 
01004   if (Tok.isNot(tok::r_paren)) {
01005     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
01006     return;
01007   }
01008 
01009   SourceLocation RParenLoc = Tok.getLocation();
01010   PP.Lex(Tok);
01011   if (Tok.isNot(tok::eod)) {
01012     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
01013     return;
01014   }
01015 
01016   PragmaPackInfo *Info = 
01017     (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
01018       sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
01019   new (Info) PragmaPackInfo();
01020   Info->Kind = Kind;
01021   Info->Name = Name;
01022   Info->Alignment = Alignment;
01023   Info->LParenLoc = LParenLoc;
01024   Info->RParenLoc = RParenLoc;
01025 
01026   Token *Toks = 
01027     (Token*) PP.getPreprocessorAllocator().Allocate(
01028       sizeof(Token) * 1, llvm::alignOf<Token>());
01029   new (Toks) Token();
01030   Toks[0].startToken();
01031   Toks[0].setKind(tok::annot_pragma_pack);
01032   Toks[0].setLocation(PackLoc);
01033   Toks[0].setAnnotationValue(static_cast<void*>(Info));
01034   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
01035                       /*OwnsTokens=*/false);
01036 }
01037 
01038 // #pragma ms_struct on
01039 // #pragma ms_struct off
01040 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, 
01041                                          PragmaIntroducerKind Introducer,
01042                                          Token &MSStructTok) {
01043   Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
01044   
01045   Token Tok;
01046   PP.Lex(Tok);
01047   if (Tok.isNot(tok::identifier)) {
01048     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
01049     return;
01050   }
01051   const IdentifierInfo *II = Tok.getIdentifierInfo();
01052   if (II->isStr("on")) {
01053     Kind = Sema::PMSST_ON;
01054     PP.Lex(Tok);
01055   }
01056   else if (II->isStr("off") || II->isStr("reset"))
01057     PP.Lex(Tok);
01058   else {
01059     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
01060     return;
01061   }
01062   
01063   if (Tok.isNot(tok::eod)) {
01064     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
01065       << "ms_struct";
01066     return;
01067   }
01068 
01069   Token *Toks =
01070     (Token*) PP.getPreprocessorAllocator().Allocate(
01071       sizeof(Token) * 1, llvm::alignOf<Token>());
01072   new (Toks) Token();
01073   Toks[0].startToken();
01074   Toks[0].setKind(tok::annot_pragma_msstruct);
01075   Toks[0].setLocation(MSStructTok.getLocation());
01076   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
01077                              static_cast<uintptr_t>(Kind)));
01078   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
01079                       /*OwnsTokens=*/false);
01080 }
01081 
01082 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
01083 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
01084 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
01085                              bool IsOptions) {
01086   Token Tok;
01087 
01088   if (IsOptions) {
01089     PP.Lex(Tok);
01090     if (Tok.isNot(tok::identifier) ||
01091         !Tok.getIdentifierInfo()->isStr("align")) {
01092       PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
01093       return;
01094     }
01095   }
01096 
01097   PP.Lex(Tok);
01098   if (Tok.isNot(tok::equal)) {
01099     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
01100       << IsOptions;
01101     return;
01102   }
01103 
01104   PP.Lex(Tok);
01105   if (Tok.isNot(tok::identifier)) {
01106     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
01107       << (IsOptions ? "options" : "align");
01108     return;
01109   }
01110 
01111   Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
01112   const IdentifierInfo *II = Tok.getIdentifierInfo();
01113   if (II->isStr("native"))
01114     Kind = Sema::POAK_Native;
01115   else if (II->isStr("natural"))
01116     Kind = Sema::POAK_Natural;
01117   else if (II->isStr("packed"))
01118     Kind = Sema::POAK_Packed;
01119   else if (II->isStr("power"))
01120     Kind = Sema::POAK_Power;
01121   else if (II->isStr("mac68k"))
01122     Kind = Sema::POAK_Mac68k;
01123   else if (II->isStr("reset"))
01124     Kind = Sema::POAK_Reset;
01125   else {
01126     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
01127       << IsOptions;
01128     return;
01129   }
01130 
01131   PP.Lex(Tok);
01132   if (Tok.isNot(tok::eod)) {
01133     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
01134       << (IsOptions ? "options" : "align");
01135     return;
01136   }
01137 
01138   Token *Toks =
01139     (Token*) PP.getPreprocessorAllocator().Allocate(
01140       sizeof(Token) * 1, llvm::alignOf<Token>());
01141   new (Toks) Token();
01142   Toks[0].startToken();
01143   Toks[0].setKind(tok::annot_pragma_align);
01144   Toks[0].setLocation(FirstTok.getLocation());
01145   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
01146                              static_cast<uintptr_t>(Kind)));
01147   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
01148                       /*OwnsTokens=*/false);
01149 }
01150 
01151 void PragmaAlignHandler::HandlePragma(Preprocessor &PP, 
01152                                       PragmaIntroducerKind Introducer,
01153                                       Token &AlignTok) {
01154   ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
01155 }
01156 
01157 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, 
01158                                         PragmaIntroducerKind Introducer,
01159                                         Token &OptionsTok) {
01160   ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
01161 }
01162 
01163 // #pragma unused(identifier)
01164 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, 
01165                                        PragmaIntroducerKind Introducer,
01166                                        Token &UnusedTok) {
01167   // FIXME: Should we be expanding macros here? My guess is no.
01168   SourceLocation UnusedLoc = UnusedTok.getLocation();
01169 
01170   // Lex the left '('.
01171   Token Tok;
01172   PP.Lex(Tok);
01173   if (Tok.isNot(tok::l_paren)) {
01174     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
01175     return;
01176   }
01177 
01178   // Lex the declaration reference(s).
01179   SmallVector<Token, 5> Identifiers;
01180   SourceLocation RParenLoc;
01181   bool LexID = true;
01182 
01183   while (true) {
01184     PP.Lex(Tok);
01185 
01186     if (LexID) {
01187       if (Tok.is(tok::identifier)) {
01188         Identifiers.push_back(Tok);
01189         LexID = false;
01190         continue;
01191       }
01192 
01193       // Illegal token!
01194       PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
01195       return;
01196     }
01197 
01198     // We are execting a ')' or a ','.
01199     if (Tok.is(tok::comma)) {
01200       LexID = true;
01201       continue;
01202     }
01203 
01204     if (Tok.is(tok::r_paren)) {
01205       RParenLoc = Tok.getLocation();
01206       break;
01207     }
01208 
01209     // Illegal token!
01210     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
01211     return;
01212   }
01213 
01214   PP.Lex(Tok);
01215   if (Tok.isNot(tok::eod)) {
01216     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
01217         "unused";
01218     return;
01219   }
01220 
01221   // Verify that we have a location for the right parenthesis.
01222   assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
01223   assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
01224 
01225   // For each identifier token, insert into the token stream a
01226   // annot_pragma_unused token followed by the identifier token.
01227   // This allows us to cache a "#pragma unused" that occurs inside an inline
01228   // C++ member function.
01229 
01230   Token *Toks = 
01231     (Token*) PP.getPreprocessorAllocator().Allocate(
01232       sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
01233   for (unsigned i=0; i != Identifiers.size(); i++) {
01234     Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
01235     pragmaUnusedTok.startToken();
01236     pragmaUnusedTok.setKind(tok::annot_pragma_unused);
01237     pragmaUnusedTok.setLocation(UnusedLoc);
01238     idTok = Identifiers[i];
01239   }
01240   PP.EnterTokenStream(Toks, 2*Identifiers.size(),
01241                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
01242 }
01243 
01244 // #pragma weak identifier
01245 // #pragma weak identifier '=' identifier
01246 void PragmaWeakHandler::HandlePragma(Preprocessor &PP, 
01247                                      PragmaIntroducerKind Introducer,
01248                                      Token &WeakTok) {
01249   SourceLocation WeakLoc = WeakTok.getLocation();
01250 
01251   Token Tok;
01252   PP.Lex(Tok);
01253   if (Tok.isNot(tok::identifier)) {
01254     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
01255     return;
01256   }
01257 
01258   Token WeakName = Tok;
01259   bool HasAlias = false;
01260   Token AliasName;
01261 
01262   PP.Lex(Tok);
01263   if (Tok.is(tok::equal)) {
01264     HasAlias = true;
01265     PP.Lex(Tok);
01266     if (Tok.isNot(tok::identifier)) {
01267       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
01268           << "weak";
01269       return;
01270     }
01271     AliasName = Tok;
01272     PP.Lex(Tok);
01273   }
01274 
01275   if (Tok.isNot(tok::eod)) {
01276     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
01277     return;
01278   }
01279 
01280   if (HasAlias) {
01281     Token *Toks = 
01282       (Token*) PP.getPreprocessorAllocator().Allocate(
01283         sizeof(Token) * 3, llvm::alignOf<Token>());
01284     Token &pragmaUnusedTok = Toks[0];
01285     pragmaUnusedTok.startToken();
01286     pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
01287     pragmaUnusedTok.setLocation(WeakLoc);
01288     Toks[1] = WeakName;
01289     Toks[2] = AliasName;
01290     PP.EnterTokenStream(Toks, 3,
01291                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
01292   } else {
01293     Token *Toks = 
01294       (Token*) PP.getPreprocessorAllocator().Allocate(
01295         sizeof(Token) * 2, llvm::alignOf<Token>());
01296     Token &pragmaUnusedTok = Toks[0];
01297     pragmaUnusedTok.startToken();
01298     pragmaUnusedTok.setKind(tok::annot_pragma_weak);
01299     pragmaUnusedTok.setLocation(WeakLoc);
01300     Toks[1] = WeakName;
01301     PP.EnterTokenStream(Toks, 2,
01302                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
01303   }
01304 }
01305 
01306 // #pragma redefine_extname identifier identifier
01307 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, 
01308                                                PragmaIntroducerKind Introducer,
01309                                                 Token &RedefToken) {
01310   SourceLocation RedefLoc = RedefToken.getLocation();
01311 
01312   Token Tok;
01313   PP.Lex(Tok);
01314   if (Tok.isNot(tok::identifier)) {
01315     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
01316       "redefine_extname";
01317     return;
01318   }
01319 
01320   Token RedefName = Tok;
01321   PP.Lex(Tok);
01322 
01323   if (Tok.isNot(tok::identifier)) {
01324     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
01325         << "redefine_extname";
01326     return;
01327   }
01328 
01329   Token AliasName = Tok;
01330   PP.Lex(Tok);
01331 
01332   if (Tok.isNot(tok::eod)) {
01333     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
01334       "redefine_extname";
01335     return;
01336   }
01337 
01338   Token *Toks = 
01339     (Token*) PP.getPreprocessorAllocator().Allocate(
01340       sizeof(Token) * 3, llvm::alignOf<Token>());
01341   Token &pragmaRedefTok = Toks[0];
01342   pragmaRedefTok.startToken();
01343   pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
01344   pragmaRedefTok.setLocation(RedefLoc);
01345   Toks[1] = RedefName;
01346   Toks[2] = AliasName;
01347   PP.EnterTokenStream(Toks, 3,
01348                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
01349 }
01350 
01351 
01352 void
01353 PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 
01354                                       PragmaIntroducerKind Introducer,
01355                                       Token &Tok) {
01356   tok::OnOffSwitch OOS;
01357   if (PP.LexOnOffSwitch(OOS))
01358     return;
01359 
01360   Token *Toks =
01361     (Token*) PP.getPreprocessorAllocator().Allocate(
01362       sizeof(Token) * 1, llvm::alignOf<Token>());
01363   new (Toks) Token();
01364   Toks[0].startToken();
01365   Toks[0].setKind(tok::annot_pragma_fp_contract);
01366   Toks[0].setLocation(Tok.getLocation());
01367   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
01368                              static_cast<uintptr_t>(OOS)));
01369   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
01370                       /*OwnsTokens=*/false);
01371 }
01372 
01373 void 
01374 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, 
01375                                            PragmaIntroducerKind Introducer,
01376                                            Token &Tok) {
01377   PP.LexUnexpandedToken(Tok);
01378   if (Tok.isNot(tok::identifier)) {
01379     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
01380       "OPENCL";
01381     return;
01382   }
01383   IdentifierInfo *ename = Tok.getIdentifierInfo();
01384   SourceLocation NameLoc = Tok.getLocation();
01385 
01386   PP.Lex(Tok);
01387   if (Tok.isNot(tok::colon)) {
01388     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
01389     return;
01390   }
01391 
01392   PP.Lex(Tok);
01393   if (Tok.isNot(tok::identifier)) {
01394     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
01395     return;
01396   }
01397   IdentifierInfo *op = Tok.getIdentifierInfo();
01398 
01399   unsigned state;
01400   if (op->isStr("enable")) {
01401     state = 1;
01402   } else if (op->isStr("disable")) {
01403     state = 0;
01404   } else {
01405     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
01406     return;
01407   }
01408   SourceLocation StateLoc = Tok.getLocation();
01409 
01410   PP.Lex(Tok);
01411   if (Tok.isNot(tok::eod)) {
01412     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
01413       "OPENCL EXTENSION";
01414     return;
01415   }
01416 
01417   OpenCLExtData data(ename, state);
01418   Token *Toks =
01419     (Token*) PP.getPreprocessorAllocator().Allocate(
01420       sizeof(Token) * 1, llvm::alignOf<Token>());
01421   new (Toks) Token();
01422   Toks[0].startToken();
01423   Toks[0].setKind(tok::annot_pragma_opencl_extension);
01424   Toks[0].setLocation(NameLoc);
01425   Toks[0].setAnnotationValue(data.getOpaqueValue());
01426   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
01427                       /*OwnsTokens=*/false);
01428 
01429   if (PP.getPPCallbacks())
01430     PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, 
01431                                                StateLoc, state);
01432 }
01433 
01434 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
01435 ///
01436 void
01437 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
01438                                     PragmaIntroducerKind Introducer,
01439                                     Token &FirstTok) {
01440   if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
01441                                      FirstTok.getLocation())) {
01442     PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
01443     PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
01444                                     diag::Severity::Ignored, SourceLocation());
01445   }
01446   PP.DiscardUntilEndOfDirective();
01447 }
01448 
01449 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
01450 ///
01451 void
01452 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
01453                                   PragmaIntroducerKind Introducer,
01454                                   Token &FirstTok) {
01455   SmallVector<Token, 16> Pragma;
01456   Token Tok;
01457   Tok.startToken();
01458   Tok.setKind(tok::annot_pragma_openmp);
01459   Tok.setLocation(FirstTok.getLocation());
01460 
01461   while (Tok.isNot(tok::eod)) {
01462     Pragma.push_back(Tok);
01463     PP.Lex(Tok);
01464   }
01465   SourceLocation EodLoc = Tok.getLocation();
01466   Tok.startToken();
01467   Tok.setKind(tok::annot_pragma_openmp_end);
01468   Tok.setLocation(EodLoc);
01469   Pragma.push_back(Tok);
01470 
01471   Token *Toks = new Token[Pragma.size()];
01472   std::copy(Pragma.begin(), Pragma.end(), Toks);
01473   PP.EnterTokenStream(Toks, Pragma.size(),
01474                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
01475 }
01476 
01477 /// \brief Handle '#pragma pointers_to_members'
01478 // The grammar for this pragma is as follows:
01479 //
01480 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
01481 //
01482 // #pragma pointers_to_members '(' 'best_case' ')'
01483 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
01484 // #pragma pointers_to_members '(' inheritance-model ')'
01485 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
01486                                              PragmaIntroducerKind Introducer,
01487                                              Token &Tok) {
01488   SourceLocation PointersToMembersLoc = Tok.getLocation();
01489   PP.Lex(Tok);
01490   if (Tok.isNot(tok::l_paren)) {
01491     PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
01492       << "pointers_to_members";
01493     return;
01494   }
01495   PP.Lex(Tok);
01496   const IdentifierInfo *Arg = Tok.getIdentifierInfo();
01497   if (!Arg) {
01498     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
01499       << "pointers_to_members";
01500     return;
01501   }
01502   PP.Lex(Tok);
01503 
01504   LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
01505   if (Arg->isStr("best_case")) {
01506     RepresentationMethod = LangOptions::PPTMK_BestCase;
01507   } else {
01508     if (Arg->isStr("full_generality")) {
01509       if (Tok.is(tok::comma)) {
01510         PP.Lex(Tok);
01511 
01512         Arg = Tok.getIdentifierInfo();
01513         if (!Arg) {
01514           PP.Diag(Tok.getLocation(),
01515                   diag::err_pragma_pointers_to_members_unknown_kind)
01516               << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
01517           return;
01518         }
01519         PP.Lex(Tok);
01520       } else if (Tok.is(tok::r_paren)) {
01521         // #pragma pointers_to_members(full_generality) implicitly specifies
01522         // virtual_inheritance.
01523         Arg = nullptr;
01524         RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
01525       } else {
01526         PP.Diag(Tok.getLocation(), diag::err_expected_punc)
01527             << "full_generality";
01528         return;
01529       }
01530     }
01531 
01532     if (Arg) {
01533       if (Arg->isStr("single_inheritance")) {
01534         RepresentationMethod =
01535             LangOptions::PPTMK_FullGeneralitySingleInheritance;
01536       } else if (Arg->isStr("multiple_inheritance")) {
01537         RepresentationMethod =
01538             LangOptions::PPTMK_FullGeneralityMultipleInheritance;
01539       } else if (Arg->isStr("virtual_inheritance")) {
01540         RepresentationMethod =
01541             LangOptions::PPTMK_FullGeneralityVirtualInheritance;
01542       } else {
01543         PP.Diag(Tok.getLocation(),
01544                 diag::err_pragma_pointers_to_members_unknown_kind)
01545             << Arg << /*HasPointerDeclaration*/ 1;
01546         return;
01547       }
01548     }
01549   }
01550 
01551   if (Tok.isNot(tok::r_paren)) {
01552     PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
01553         << (Arg ? Arg->getName() : "full_generality");
01554     return;
01555   }
01556 
01557   PP.Lex(Tok);
01558   if (Tok.isNot(tok::eod)) {
01559     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
01560       << "pointers_to_members";
01561     return;
01562   }
01563 
01564   Token AnnotTok;
01565   AnnotTok.startToken();
01566   AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
01567   AnnotTok.setLocation(PointersToMembersLoc);
01568   AnnotTok.setAnnotationValue(
01569       reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
01570   PP.EnterToken(AnnotTok);
01571 }
01572 
01573 /// \brief Handle '#pragma vtordisp'
01574 // The grammar for this pragma is as follows:
01575 //
01576 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
01577 //
01578 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
01579 // #pragma vtordisp '(' 'pop' ')'
01580 // #pragma vtordisp '(' ')'
01581 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
01582                                     PragmaIntroducerKind Introducer,
01583                                     Token &Tok) {
01584   SourceLocation VtorDispLoc = Tok.getLocation();
01585   PP.Lex(Tok);
01586   if (Tok.isNot(tok::l_paren)) {
01587     PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
01588     return;
01589   }
01590   PP.Lex(Tok);
01591 
01592   Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
01593   const IdentifierInfo *II = Tok.getIdentifierInfo();
01594   if (II) {
01595     if (II->isStr("push")) {
01596       // #pragma vtordisp(push, mode)
01597       PP.Lex(Tok);
01598       if (Tok.isNot(tok::comma)) {
01599         PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
01600         return;
01601       }
01602       PP.Lex(Tok);
01603       Kind = Sema::PVDK_Push;
01604       // not push, could be on/off
01605     } else if (II->isStr("pop")) {
01606       // #pragma vtordisp(pop)
01607       PP.Lex(Tok);
01608       Kind = Sema::PVDK_Pop;
01609     }
01610     // not push or pop, could be on/off
01611   } else {
01612     if (Tok.is(tok::r_paren)) {
01613       // #pragma vtordisp()
01614       Kind = Sema::PVDK_Reset;
01615     }
01616   }
01617 
01618 
01619   uint64_t Value = 0;
01620   if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
01621     const IdentifierInfo *II = Tok.getIdentifierInfo();
01622     if (II && II->isStr("off")) {
01623       PP.Lex(Tok);
01624       Value = 0;
01625     } else if (II && II->isStr("on")) {
01626       PP.Lex(Tok);
01627       Value = 1;
01628     } else if (Tok.is(tok::numeric_constant) &&
01629                PP.parseSimpleIntegerLiteral(Tok, Value)) {
01630       if (Value > 2) {
01631         PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
01632             << 0 << 2 << "vtordisp";
01633         return;
01634       }
01635     } else {
01636       PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
01637           << "vtordisp";
01638       return;
01639     }
01640   }
01641 
01642   // Finish the pragma: ')' $
01643   if (Tok.isNot(tok::r_paren)) {
01644     PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
01645     return;
01646   }
01647   PP.Lex(Tok);
01648   if (Tok.isNot(tok::eod)) {
01649     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
01650         << "vtordisp";
01651     return;
01652   }
01653 
01654   // Enter the annotation.
01655   Token AnnotTok;
01656   AnnotTok.startToken();
01657   AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
01658   AnnotTok.setLocation(VtorDispLoc);
01659   AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
01660       static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
01661   PP.EnterToken(AnnotTok);
01662 }
01663 
01664 /// \brief Handle all MS pragmas.  Simply forwards the tokens after inserting
01665 /// an annotation token.
01666 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
01667                                   PragmaIntroducerKind Introducer,
01668                                   Token &Tok) {
01669   Token EoF, AnnotTok;
01670   EoF.startToken();
01671   EoF.setKind(tok::eof);
01672   AnnotTok.startToken();
01673   AnnotTok.setKind(tok::annot_pragma_ms_pragma);
01674   AnnotTok.setLocation(Tok.getLocation());
01675   SmallVector<Token, 8> TokenVector;
01676   // Suck up all of the tokens before the eod.
01677   for (; Tok.isNot(tok::eod); PP.Lex(Tok))
01678     TokenVector.push_back(Tok);
01679   // Add a sentinal EoF token to the end of the list.
01680   TokenVector.push_back(EoF);
01681   // We must allocate this array with new because EnterTokenStream is going to
01682   // delete it later.
01683   Token *TokenArray = new Token[TokenVector.size()];
01684   std::copy(TokenVector.begin(), TokenVector.end(), TokenArray);
01685   auto Value = new (PP.getPreprocessorAllocator())
01686       std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
01687   AnnotTok.setAnnotationValue(Value);
01688   PP.EnterToken(AnnotTok);
01689 }
01690 
01691 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
01692 ///
01693 /// The syntax is:
01694 /// \code
01695 ///   #pragma detect_mismatch("name", "value")
01696 /// \endcode
01697 /// Where 'name' and 'value' are quoted strings.  The values are embedded in
01698 /// the object file and passed along to the linker.  If the linker detects a
01699 /// mismatch in the object file's values for the given name, a LNK2038 error
01700 /// is emitted.  See MSDN for more details.
01701 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
01702                                                PragmaIntroducerKind Introducer,
01703                                                Token &Tok) {
01704   SourceLocation CommentLoc = Tok.getLocation();
01705   PP.Lex(Tok);
01706   if (Tok.isNot(tok::l_paren)) {
01707     PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
01708     return;
01709   }
01710 
01711   // Read the name to embed, which must be a string literal.
01712   std::string NameString;
01713   if (!PP.LexStringLiteral(Tok, NameString,
01714                            "pragma detect_mismatch",
01715                            /*MacroExpansion=*/true))
01716     return;
01717 
01718   // Read the comma followed by a second string literal.
01719   std::string ValueString;
01720   if (Tok.isNot(tok::comma)) {
01721     PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
01722     return;
01723   }
01724 
01725   if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
01726                            /*MacroExpansion=*/true))
01727     return;
01728 
01729   if (Tok.isNot(tok::r_paren)) {
01730     PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
01731     return;
01732   }
01733   PP.Lex(Tok);  // Eat the r_paren.
01734 
01735   if (Tok.isNot(tok::eod)) {
01736     PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
01737     return;
01738   }
01739 
01740   // If the pragma is lexically sound, notify any interested PPCallbacks.
01741   if (PP.getPPCallbacks())
01742     PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString,
01743                                               ValueString);
01744 
01745   Actions.ActOnPragmaDetectMismatch(NameString, ValueString);
01746 }
01747 
01748 /// \brief Handle the microsoft \#pragma comment extension.
01749 ///
01750 /// The syntax is:
01751 /// \code
01752 ///   #pragma comment(linker, "foo")
01753 /// \endcode
01754 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
01755 /// "foo" is a string, which is fully macro expanded, and permits string
01756 /// concatenation, embedded escape characters etc.  See MSDN for more details.
01757 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
01758                                         PragmaIntroducerKind Introducer,
01759                                         Token &Tok) {
01760   SourceLocation CommentLoc = Tok.getLocation();
01761   PP.Lex(Tok);
01762   if (Tok.isNot(tok::l_paren)) {
01763     PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
01764     return;
01765   }
01766 
01767   // Read the identifier.
01768   PP.Lex(Tok);
01769   if (Tok.isNot(tok::identifier)) {
01770     PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
01771     return;
01772   }
01773 
01774   // Verify that this is one of the 5 whitelisted options.
01775   IdentifierInfo *II = Tok.getIdentifierInfo();
01776   Sema::PragmaMSCommentKind Kind =
01777     llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())
01778     .Case("linker",   Sema::PCK_Linker)
01779     .Case("lib",      Sema::PCK_Lib)
01780     .Case("compiler", Sema::PCK_Compiler)
01781     .Case("exestr",   Sema::PCK_ExeStr)
01782     .Case("user",     Sema::PCK_User)
01783     .Default(Sema::PCK_Unknown);
01784   if (Kind == Sema::PCK_Unknown) {
01785     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
01786     return;
01787   }
01788 
01789   // Read the optional string if present.
01790   PP.Lex(Tok);
01791   std::string ArgumentString;
01792   if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
01793                                                  "pragma comment",
01794                                                  /*MacroExpansion=*/true))
01795     return;
01796 
01797   // FIXME: warn that 'exestr' is deprecated.
01798   // FIXME: If the kind is "compiler" warn if the string is present (it is
01799   // ignored).
01800   // The MSDN docs say that "lib" and "linker" require a string and have a short
01801   // whitelist of linker options they support, but in practice MSVC doesn't
01802   // issue a diagnostic.  Therefore neither does clang.
01803 
01804   if (Tok.isNot(tok::r_paren)) {
01805     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
01806     return;
01807   }
01808   PP.Lex(Tok);  // eat the r_paren.
01809 
01810   if (Tok.isNot(tok::eod)) {
01811     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
01812     return;
01813   }
01814 
01815   // If the pragma is lexically sound, notify any interested PPCallbacks.
01816   if (PP.getPPCallbacks())
01817     PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
01818 
01819   Actions.ActOnPragmaMSComment(Kind, ArgumentString);
01820 }
01821 
01822 // #pragma clang optimize off
01823 // #pragma clang optimize on
01824 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP, 
01825                                         PragmaIntroducerKind Introducer,
01826                                         Token &FirstToken) {
01827   Token Tok;
01828   PP.Lex(Tok);
01829   if (Tok.is(tok::eod)) {
01830     PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
01831         << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
01832     return;
01833   }
01834   if (Tok.isNot(tok::identifier)) {
01835     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
01836       << PP.getSpelling(Tok);
01837     return;
01838   }
01839   const IdentifierInfo *II = Tok.getIdentifierInfo();
01840   // The only accepted values are 'on' or 'off'.
01841   bool IsOn = false;
01842   if (II->isStr("on")) {
01843     IsOn = true;
01844   } else if (!II->isStr("off")) {
01845     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
01846       << PP.getSpelling(Tok);
01847     return;
01848   }
01849   PP.Lex(Tok);
01850   
01851   if (Tok.isNot(tok::eod)) {
01852     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
01853       << PP.getSpelling(Tok);
01854     return;
01855   }
01856 
01857   Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
01858 }
01859 
01860 /// \brief Parses loop or unroll pragma hint value and fills in Info.
01861 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
01862                                Token Option, bool ValueInParens,
01863                                PragmaLoopHintInfo &Info) {
01864   SmallVector<Token, 1> ValueList;
01865   int OpenParens = ValueInParens ? 1 : 0;
01866   // Read constant expression.
01867   while (Tok.isNot(tok::eod)) {
01868     if (Tok.is(tok::l_paren))
01869       OpenParens++;
01870     else if (Tok.is(tok::r_paren)) {
01871       OpenParens--;
01872       if (OpenParens == 0 && ValueInParens)
01873         break;
01874     }
01875 
01876     ValueList.push_back(Tok);
01877     PP.Lex(Tok);
01878   }
01879 
01880   if (ValueInParens) {
01881     // Read ')'
01882     if (Tok.isNot(tok::r_paren)) {
01883       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
01884       return true;
01885     }
01886     PP.Lex(Tok);
01887   }
01888 
01889   Token EOFTok;
01890   EOFTok.startToken();
01891   EOFTok.setKind(tok::eof);
01892   EOFTok.setLocation(Tok.getLocation());
01893   ValueList.push_back(EOFTok); // Terminates expression for parsing.
01894 
01895   Token *TokenArray = (Token *)PP.getPreprocessorAllocator().Allocate(
01896       ValueList.size() * sizeof(Token), llvm::alignOf<Token>());
01897   std::copy(ValueList.begin(), ValueList.end(), TokenArray);
01898   Info.Toks = TokenArray;
01899   Info.TokSize = ValueList.size();
01900 
01901   Info.PragmaName = PragmaName;
01902   Info.Option = Option;
01903   return false;
01904 }
01905 
01906 /// \brief Handle the \#pragma clang loop directive.
01907 ///  #pragma clang 'loop' loop-hints
01908 ///
01909 ///  loop-hints:
01910 ///    loop-hint loop-hints[opt]
01911 ///
01912 ///  loop-hint:
01913 ///    'vectorize' '(' loop-hint-keyword ')'
01914 ///    'interleave' '(' loop-hint-keyword ')'
01915 ///    'unroll' '(' unroll-hint-keyword ')'
01916 ///    'vectorize_width' '(' loop-hint-value ')'
01917 ///    'interleave_count' '(' loop-hint-value ')'
01918 ///    'unroll_count' '(' loop-hint-value ')'
01919 ///
01920 ///  loop-hint-keyword:
01921 ///    'enable'
01922 ///    'disable'
01923 ///
01924 ///  unroll-hint-keyword:
01925 ///    'full'
01926 ///    'disable'
01927 ///
01928 ///  loop-hint-value:
01929 ///    constant-expression
01930 ///
01931 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
01932 /// try vectorizing the instructions of the loop it precedes. Specifying
01933 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
01934 /// interleaving multiple iterations of the loop it precedes. The width of the
01935 /// vector instructions is specified by vectorize_width() and the number of
01936 /// interleaved loop iterations is specified by interleave_count(). Specifying a
01937 /// value of 1 effectively disables vectorization/interleaving, even if it is
01938 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
01939 /// only works on inner loops.
01940 ///
01941 /// The unroll and unroll_count directives control the concatenation
01942 /// unroller. Specifying unroll(full) instructs llvm to try to
01943 /// unroll the loop completely, and unroll(disable) disables unrolling
01944 /// for the loop. Specifying unroll_count(_value_) instructs llvm to
01945 /// try to unroll the loop the number of times indicated by the value.
01946 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
01947                                          PragmaIntroducerKind Introducer,
01948                                          Token &Tok) {
01949   // Incoming token is "loop" from "#pragma clang loop".
01950   Token PragmaName = Tok;
01951   SmallVector<Token, 1> TokenList;
01952 
01953   // Lex the optimization option and verify it is an identifier.
01954   PP.Lex(Tok);
01955   if (Tok.isNot(tok::identifier)) {
01956     PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
01957         << /*MissingOption=*/true << "";
01958     return;
01959   }
01960 
01961   while (Tok.is(tok::identifier)) {
01962     Token Option = Tok;
01963     IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
01964 
01965     bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
01966                            .Case("vectorize", true)
01967                            .Case("interleave", true)
01968                            .Case("unroll", true)
01969                            .Case("vectorize_width", true)
01970                            .Case("interleave_count", true)
01971                            .Case("unroll_count", true)
01972                            .Default(false);
01973     if (!OptionValid) {
01974       PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
01975           << /*MissingOption=*/false << OptionInfo;
01976       return;
01977     }
01978     PP.Lex(Tok);
01979 
01980     // Read '('
01981     if (Tok.isNot(tok::l_paren)) {
01982       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
01983       return;
01984     }
01985     PP.Lex(Tok);
01986 
01987     auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
01988     if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
01989                            *Info))
01990       return;
01991 
01992     // Generate the loop hint token.
01993     Token LoopHintTok;
01994     LoopHintTok.startToken();
01995     LoopHintTok.setKind(tok::annot_pragma_loop_hint);
01996     LoopHintTok.setLocation(PragmaName.getLocation());
01997     LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
01998     TokenList.push_back(LoopHintTok);
01999   }
02000 
02001   if (Tok.isNot(tok::eod)) {
02002     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
02003         << "clang loop";
02004     return;
02005   }
02006 
02007   Token *TokenArray = new Token[TokenList.size()];
02008   std::copy(TokenList.begin(), TokenList.end(), TokenArray);
02009 
02010   PP.EnterTokenStream(TokenArray, TokenList.size(),
02011                       /*DisableMacroExpansion=*/false,
02012                       /*OwnsTokens=*/true);
02013 }
02014 
02015 /// \brief Handle the loop unroll optimization pragmas.
02016 ///  #pragma unroll
02017 ///  #pragma unroll unroll-hint-value
02018 ///  #pragma unroll '(' unroll-hint-value ')'
02019 ///  #pragma nounroll
02020 ///
02021 ///  unroll-hint-value:
02022 ///    constant-expression
02023 ///
02024 /// Loop unrolling hints can be specified with '#pragma unroll' or
02025 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
02026 /// contained in parentheses. With no argument the directive instructs llvm to
02027 /// try to unroll the loop completely. A positive integer argument can be
02028 /// specified to indicate the number of times the loop should be unrolled.  To
02029 /// maximize compatibility with other compilers the unroll count argument can be
02030 /// specified with or without parentheses.  Specifying, '#pragma nounroll'
02031 /// disables unrolling of the loop.
02032 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
02033                                            PragmaIntroducerKind Introducer,
02034                                            Token &Tok) {
02035   // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
02036   // "#pragma nounroll".
02037   Token PragmaName = Tok;
02038   PP.Lex(Tok);
02039   auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
02040   if (Tok.is(tok::eod)) {
02041     // nounroll or unroll pragma without an argument.
02042     Info->PragmaName = PragmaName;
02043     Info->Option.startToken();
02044   } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
02045     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
02046         << "nounroll";
02047     return;
02048   } else {
02049     // Unroll pragma with an argument: "#pragma unroll N" or
02050     // "#pragma unroll(N)".
02051     // Read '(' if it exists.
02052     bool ValueInParens = Tok.is(tok::l_paren);
02053     if (ValueInParens)
02054       PP.Lex(Tok);
02055 
02056     Token Option;
02057     Option.startToken();
02058     if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
02059       return;
02060 
02061     // In CUDA, the argument to '#pragma unroll' should not be contained in
02062     // parentheses.
02063     if (PP.getLangOpts().CUDA && ValueInParens)
02064       PP.Diag(Info->Toks[0].getLocation(),
02065               diag::warn_pragma_unroll_cuda_value_in_parens);
02066 
02067     if (Tok.isNot(tok::eod)) {
02068       PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
02069           << "unroll";
02070       return;
02071     }
02072   }
02073 
02074   // Generate the hint token.
02075   Token *TokenArray = new Token[1];
02076   TokenArray[0].startToken();
02077   TokenArray[0].setKind(tok::annot_pragma_loop_hint);
02078   TokenArray[0].setLocation(PragmaName.getLocation());
02079   TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
02080   PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false,
02081                       /*OwnsTokens=*/true);
02082 }