clang API Documentation

Pragma.cpp

Go to the documentation of this file.
00001 //===--- Pragma.cpp - Pragma registration and handling --------------------===//
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 PragmaHandler/PragmaTable interfaces and implements
00011 // pragma related methods of the Preprocessor class.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/Lex/Pragma.h"
00016 #include "clang/Lex/HeaderSearch.h"
00017 #include "clang/Lex/LiteralSupport.h"
00018 #include "clang/Lex/Preprocessor.h"
00019 #include "clang/Lex/LexDiagnostic.h"
00020 #include "clang/Basic/FileManager.h"
00021 #include "clang/Basic/SourceManager.h"
00022 #include <algorithm>
00023 using namespace clang;
00024 
00025 // Out-of-line destructor to provide a home for the class.
00026 PragmaHandler::~PragmaHandler() {
00027 }
00028 
00029 //===----------------------------------------------------------------------===//
00030 // PragmaNamespace Implementation.
00031 //===----------------------------------------------------------------------===//
00032 
00033 
00034 PragmaNamespace::~PragmaNamespace() {
00035   for (unsigned i = 0, e = Handlers.size(); i != e; ++i)
00036     delete Handlers[i];
00037 }
00038 
00039 /// FindHandler - Check to see if there is already a handler for the
00040 /// specified name.  If not, return the handler for the null identifier if it
00041 /// exists, otherwise return null.  If IgnoreNull is true (the default) then
00042 /// the null handler isn't returned on failure to match.
00043 PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name,
00044                                             bool IgnoreNull) const {
00045   PragmaHandler *NullHandler = 0;
00046   for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
00047     if (Handlers[i]->getName() == Name)
00048       return Handlers[i];
00049 
00050     if (Handlers[i]->getName() == 0)
00051       NullHandler = Handlers[i];
00052   }
00053   return IgnoreNull ? 0 : NullHandler;
00054 }
00055 
00056 void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
00057   for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
00058     if (Handlers[i] == Handler) {
00059       Handlers[i] = Handlers.back();
00060       Handlers.pop_back();
00061       return;
00062     }
00063   }
00064   assert(0 && "Handler not registered in this namespace");
00065 }
00066 
00067 void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
00068   // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
00069   // expand it, the user can have a STDC #define, that should not affect this.
00070   PP.LexUnexpandedToken(Tok);
00071 
00072   // Get the handler for this token.  If there is no handler, ignore the pragma.
00073   PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false);
00074   if (Handler == 0) {
00075     PP.Diag(Tok, diag::warn_pragma_ignored);
00076     return;
00077   }
00078 
00079   // Otherwise, pass it down.
00080   Handler->HandlePragma(PP, Tok);
00081 }
00082 
00083 //===----------------------------------------------------------------------===//
00084 // Preprocessor Pragma Directive Handling.
00085 //===----------------------------------------------------------------------===//
00086 
00087 /// HandlePragmaDirective - The "#pragma" directive has been parsed.  Lex the
00088 /// rest of the pragma, passing it to the registered pragma handlers.
00089 void Preprocessor::HandlePragmaDirective() {
00090   ++NumPragma;
00091 
00092   // Invoke the first level of pragma handlers which reads the namespace id.
00093   Token Tok;
00094   PragmaHandlers->HandlePragma(*this, Tok);
00095 
00096   // If the pragma handler didn't read the rest of the line, consume it now.
00097   if (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective)
00098     DiscardUntilEndOfDirective();
00099 }
00100 
00101 /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
00102 /// return the first token after the directive.  The _Pragma token has just
00103 /// been read into 'Tok'.
00104 void Preprocessor::Handle_Pragma(Token &Tok) {
00105   // Remember the pragma token location.
00106   SourceLocation PragmaLoc = Tok.getLocation();
00107 
00108   // Read the '('.
00109   Lex(Tok);
00110   if (Tok.isNot(tok::l_paren)) {
00111     Diag(PragmaLoc, diag::err__Pragma_malformed);
00112     return;
00113   }
00114 
00115   // Read the '"..."'.
00116   Lex(Tok);
00117   if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal)) {
00118     Diag(PragmaLoc, diag::err__Pragma_malformed);
00119     return;
00120   }
00121 
00122   // Remember the string.
00123   std::string StrVal = getSpelling(Tok);
00124 
00125   // Read the ')'.
00126   Lex(Tok);
00127   if (Tok.isNot(tok::r_paren)) {
00128     Diag(PragmaLoc, diag::err__Pragma_malformed);
00129     return;
00130   }
00131 
00132   SourceLocation RParenLoc = Tok.getLocation();
00133 
00134   // The _Pragma is lexically sound.  Destringize according to C99 6.10.9.1:
00135   // "The string literal is destringized by deleting the L prefix, if present,
00136   // deleting the leading and trailing double-quotes, replacing each escape
00137   // sequence \" by a double-quote, and replacing each escape sequence \\ by a
00138   // single backslash."
00139   if (StrVal[0] == 'L')  // Remove L prefix.
00140     StrVal.erase(StrVal.begin());
00141   assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
00142          "Invalid string token!");
00143 
00144   // Remove the front quote, replacing it with a space, so that the pragma
00145   // contents appear to have a space before them.
00146   StrVal[0] = ' ';
00147 
00148   // Replace the terminating quote with a \n.
00149   StrVal[StrVal.size()-1] = '\n';
00150 
00151   // Remove escaped quotes and escapes.
00152   for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) {
00153     if (StrVal[i] == '\\' &&
00154         (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
00155       // \\ -> '\' and \" -> '"'.
00156       StrVal.erase(StrVal.begin()+i);
00157       --e;
00158     }
00159   }
00160 
00161   // Plop the string (including the newline and trailing null) into a buffer
00162   // where we can lex it.
00163   Token TmpTok;
00164   TmpTok.startToken();
00165   CreateString(&StrVal[0], StrVal.size(), TmpTok);
00166   SourceLocation TokLoc = TmpTok.getLocation();
00167 
00168   // Make and enter a lexer object so that we lex and expand the tokens just
00169   // like any others.
00170   Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
00171                                         StrVal.size(), *this);
00172 
00173   EnterSourceFileWithLexer(TL, 0);
00174 
00175   // With everything set up, lex this as a #pragma directive.
00176   HandlePragmaDirective();
00177 
00178   // Finally, return whatever came after the pragma directive.
00179   return Lex(Tok);
00180 }
00181 
00182 
00183 
00184 /// HandlePragmaOnce - Handle #pragma once.  OnceTok is the 'once'.
00185 ///
00186 void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
00187   if (isInPrimaryFile()) {
00188     Diag(OnceTok, diag::pp_pragma_once_in_main_file);
00189     return;
00190   }
00191 
00192   // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
00193   // Mark the file as a once-only file now.
00194   HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
00195 }
00196 
00197 void Preprocessor::HandlePragmaMark() {
00198   assert(CurPPLexer && "No current lexer?");
00199   if (CurLexer)
00200     CurLexer->ReadToEndOfLine();
00201   else
00202     CurPTHLexer->DiscardToEndOfLine();
00203 }
00204 
00205 
00206 /// HandlePragmaPoison - Handle #pragma GCC poison.  PoisonTok is the 'poison'.
00207 ///
00208 void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
00209   Token Tok;
00210 
00211   while (1) {
00212     // Read the next token to poison.  While doing this, pretend that we are
00213     // skipping while reading the identifier to poison.
00214     // This avoids errors on code like:
00215     //   #pragma GCC poison X
00216     //   #pragma GCC poison X
00217     if (CurPPLexer) CurPPLexer->LexingRawMode = true;
00218     LexUnexpandedToken(Tok);
00219     if (CurPPLexer) CurPPLexer->LexingRawMode = false;
00220 
00221     // If we reached the end of line, we're done.
00222     if (Tok.is(tok::eom)) return;
00223 
00224     // Can only poison identifiers.
00225     if (Tok.isNot(tok::identifier)) {
00226       Diag(Tok, diag::err_pp_invalid_poison);
00227       return;
00228     }
00229 
00230     // Look up the identifier info for the token.  We disabled identifier lookup
00231     // by saying we're skipping contents, so we need to do this manually.
00232     IdentifierInfo *II = LookUpIdentifierInfo(Tok);
00233 
00234     // Already poisoned.
00235     if (II->isPoisoned()) continue;
00236 
00237     // If this is a macro identifier, emit a warning.
00238     if (II->hasMacroDefinition())
00239       Diag(Tok, diag::pp_poisoning_existing_macro);
00240 
00241     // Finally, poison it!
00242     II->setIsPoisoned();
00243   }
00244 }
00245 
00246 /// HandlePragmaSystemHeader - Implement #pragma GCC system_header.  We know
00247 /// that the whole directive has been parsed.
00248 void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
00249   if (isInPrimaryFile()) {
00250     Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
00251     return;
00252   }
00253 
00254   // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
00255   PreprocessorLexer *TheLexer = getCurrentFileLexer();
00256 
00257   // Mark the file as a system header.
00258   HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
00259 
00260 
00261   PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
00262   unsigned FilenameLen = strlen(PLoc.getFilename());
00263   unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename(),
00264                                                          FilenameLen);
00265 
00266   // Emit a line marker.  This will change any source locations from this point
00267   // forward to realize they are in a system header.
00268   // Create a line note with this information.
00269   SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine(), FilenameID,
00270                         false, false, true, false);
00271 
00272   // Notify the client, if desired, that we are in a new source file.
00273   if (Callbacks)
00274     Callbacks->FileChanged(SysHeaderTok.getLocation(),
00275                            PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
00276 }
00277 
00278 /// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
00279 ///
00280 void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
00281   Token FilenameTok;
00282   CurPPLexer->LexIncludeFilename(FilenameTok);
00283 
00284   // If the token kind is EOM, the error has already been diagnosed.
00285   if (FilenameTok.is(tok::eom))
00286     return;
00287 
00288   // Reserve a buffer to get the spelling.
00289   llvm::SmallString<128> FilenameBuffer;
00290   bool Invalid = false;
00291   llvm::StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
00292   if (Invalid)
00293     return;
00294 
00295   bool isAngled =
00296     GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
00297   // If GetIncludeFilenameSpelling set the start ptr to null, there was an
00298   // error.
00299   if (Filename.empty())
00300     return;
00301 
00302   // Search include directories for this file.
00303   const DirectoryLookup *CurDir;
00304   const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir);
00305   if (File == 0) {
00306     Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
00307     return;
00308   }
00309 
00310   const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
00311 
00312   // If this file is older than the file it depends on, emit a diagnostic.
00313   if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
00314     // Lex tokens at the end of the message and include them in the message.
00315     std::string Message;
00316     Lex(DependencyTok);
00317     while (DependencyTok.isNot(tok::eom)) {
00318       Message += getSpelling(DependencyTok) + " ";
00319       Lex(DependencyTok);
00320     }
00321 
00322     Message.erase(Message.end()-1);
00323     Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
00324   }
00325 }
00326 
00327 /// HandlePragmaComment - Handle the microsoft #pragma comment extension.  The
00328 /// syntax is:
00329 ///   #pragma comment(linker, "foo")
00330 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
00331 /// "foo" is a string, which is fully macro expanded, and permits string
00332 /// concatenation, embedded escape characters etc.  See MSDN for more details.
00333 void Preprocessor::HandlePragmaComment(Token &Tok) {
00334   SourceLocation CommentLoc = Tok.getLocation();
00335   Lex(Tok);
00336   if (Tok.isNot(tok::l_paren)) {
00337     Diag(CommentLoc, diag::err_pragma_comment_malformed);
00338     return;
00339   }
00340 
00341   // Read the identifier.
00342   Lex(Tok);
00343   if (Tok.isNot(tok::identifier)) {
00344     Diag(CommentLoc, diag::err_pragma_comment_malformed);
00345     return;
00346   }
00347 
00348   // Verify that this is one of the 5 whitelisted options.
00349   // FIXME: warn that 'exestr' is deprecated.
00350   const IdentifierInfo *II = Tok.getIdentifierInfo();
00351   if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") &&
00352       !II->isStr("linker") && !II->isStr("user")) {
00353     Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
00354     return;
00355   }
00356 
00357   // Read the optional string if present.
00358   Lex(Tok);
00359   std::string ArgumentString;
00360   if (Tok.is(tok::comma)) {
00361     Lex(Tok); // eat the comma.
00362 
00363     // We need at least one string.
00364     if (Tok.isNot(tok::string_literal)) {
00365       Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
00366       return;
00367     }
00368 
00369     // String concatenation allows multiple strings, which can even come from
00370     // macro expansion.
00371     // "foo " "bar" "Baz"
00372     llvm::SmallVector<Token, 4> StrToks;
00373     while (Tok.is(tok::string_literal)) {
00374       StrToks.push_back(Tok);
00375       Lex(Tok);
00376     }
00377 
00378     // Concatenate and parse the strings.
00379     StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
00380     assert(!Literal.AnyWide && "Didn't allow wide strings in");
00381     if (Literal.hadError)
00382       return;
00383     if (Literal.Pascal) {
00384       Diag(StrToks[0].getLocation(), diag::err_pragma_comment_malformed);
00385       return;
00386     }
00387 
00388     ArgumentString = std::string(Literal.GetString(),
00389                                  Literal.GetString()+Literal.GetStringLength());
00390   }
00391 
00392   // FIXME: If the kind is "compiler" warn if the string is present (it is
00393   // ignored).
00394   // FIXME: 'lib' requires a comment string.
00395   // FIXME: 'linker' requires a comment string, and has a specific list of
00396   // things that are allowable.
00397 
00398   if (Tok.isNot(tok::r_paren)) {
00399     Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
00400     return;
00401   }
00402   Lex(Tok);  // eat the r_paren.
00403 
00404   if (Tok.isNot(tok::eom)) {
00405     Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
00406     return;
00407   }
00408 
00409   // If the pragma is lexically sound, notify any interested PPCallbacks.
00410   if (Callbacks)
00411     Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
00412 }
00413 
00414 
00415 
00416 
00417 /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
00418 /// If 'Namespace' is non-null, then it is a token required to exist on the
00419 /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
00420 void Preprocessor::AddPragmaHandler(const char *Namespace,
00421                                     PragmaHandler *Handler) {
00422   PragmaNamespace *InsertNS = PragmaHandlers;
00423 
00424   // If this is specified to be in a namespace, step down into it.
00425   if (Namespace) {
00426     IdentifierInfo *NSID = getIdentifierInfo(Namespace);
00427 
00428     // If there is already a pragma handler with the name of this namespace,
00429     // we either have an error (directive with the same name as a namespace) or
00430     // we already have the namespace to insert into.
00431     if (PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID)) {
00432       InsertNS = Existing->getIfNamespace();
00433       assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
00434              " handler with the same name!");
00435     } else {
00436       // Otherwise, this namespace doesn't exist yet, create and insert the
00437       // handler for it.
00438       InsertNS = new PragmaNamespace(NSID);
00439       PragmaHandlers->AddPragma(InsertNS);
00440     }
00441   }
00442 
00443   // Check to make sure we don't already have a pragma for this identifier.
00444   assert(!InsertNS->FindHandler(Handler->getName()) &&
00445          "Pragma handler already exists for this identifier!");
00446   InsertNS->AddPragma(Handler);
00447 }
00448 
00449 /// RemovePragmaHandler - Remove the specific pragma handler from the
00450 /// preprocessor. If \arg Namespace is non-null, then it should be the
00451 /// namespace that \arg Handler was added to. It is an error to remove
00452 /// a handler that has not been registered.
00453 void Preprocessor::RemovePragmaHandler(const char *Namespace,
00454                                        PragmaHandler *Handler) {
00455   PragmaNamespace *NS = PragmaHandlers;
00456 
00457   // If this is specified to be in a namespace, step down into it.
00458   if (Namespace) {
00459     IdentifierInfo *NSID = getIdentifierInfo(Namespace);
00460     PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID);
00461     assert(Existing && "Namespace containing handler does not exist!");
00462 
00463     NS = Existing->getIfNamespace();
00464     assert(NS && "Invalid namespace, registered as a regular pragma handler!");
00465   }
00466 
00467   NS->RemovePragmaHandler(Handler);
00468 
00469   // If this is a non-default namespace and it is now empty, remove
00470   // it.
00471   if (NS != PragmaHandlers && NS->IsEmpty())
00472     PragmaHandlers->RemovePragmaHandler(NS);
00473 }
00474 
00475 namespace {
00476 /// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
00477 struct PragmaOnceHandler : public PragmaHandler {
00478   PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {}
00479   virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) {
00480     PP.CheckEndOfDirective("pragma once");
00481     PP.HandlePragmaOnce(OnceTok);
00482   }
00483 };
00484 
00485 /// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the
00486 /// rest of the line is not lexed.
00487 struct PragmaMarkHandler : public PragmaHandler {
00488   PragmaMarkHandler(const IdentifierInfo *MarkID) : PragmaHandler(MarkID) {}
00489   virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) {
00490     PP.HandlePragmaMark();
00491   }
00492 };
00493 
00494 /// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
00495 struct PragmaPoisonHandler : public PragmaHandler {
00496   PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
00497   virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) {
00498     PP.HandlePragmaPoison(PoisonTok);
00499   }
00500 };
00501 
00502 /// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file
00503 /// as a system header, which silences warnings in it.
00504 struct PragmaSystemHeaderHandler : public PragmaHandler {
00505   PragmaSystemHeaderHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
00506   virtual void HandlePragma(Preprocessor &PP, Token &SHToken) {
00507     PP.HandlePragmaSystemHeader(SHToken);
00508     PP.CheckEndOfDirective("pragma");
00509   }
00510 };
00511 struct PragmaDependencyHandler : public PragmaHandler {
00512   PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
00513   virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
00514     PP.HandlePragmaDependency(DepToken);
00515   }
00516 };
00517 
00518 /// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"'
00519 /// Since clang's diagnostic supports extended functionality beyond GCC's
00520 /// the constructor takes a clangMode flag to tell it whether or not to allow
00521 /// clang's extended functionality, or whether to reject it.
00522 struct PragmaDiagnosticHandler : public PragmaHandler {
00523 private:
00524   const bool ClangMode;
00525 public:
00526   PragmaDiagnosticHandler(const IdentifierInfo *ID,
00527                           const bool clangMode) : PragmaHandler(ID),
00528                                                   ClangMode(clangMode) {}
00529   virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) {
00530     Token Tok;
00531     PP.LexUnexpandedToken(Tok);
00532     if (Tok.isNot(tok::identifier)) {
00533       unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid
00534                                  : diag::warn_pragma_diagnostic_gcc_invalid;
00535       PP.Diag(Tok, Diag);
00536       return;
00537     }
00538     IdentifierInfo *II = Tok.getIdentifierInfo();
00539 
00540     diag::Mapping Map;
00541     if (II->isStr("warning"))
00542       Map = diag::MAP_WARNING;
00543     else if (II->isStr("error"))
00544       Map = diag::MAP_ERROR;
00545     else if (II->isStr("ignored"))
00546       Map = diag::MAP_IGNORE;
00547     else if (II->isStr("fatal"))
00548       Map = diag::MAP_FATAL;
00549     else if (ClangMode) {
00550       if (II->isStr("pop")) {
00551         if (!PP.getDiagnostics().popMappings())
00552           PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_cannot_ppp);
00553         return;
00554       }
00555 
00556       if (II->isStr("push")) {
00557         PP.getDiagnostics().pushMappings();
00558         return;
00559       }
00560 
00561       PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_invalid);
00562       return;
00563     } else {
00564       PP.Diag(Tok, diag::warn_pragma_diagnostic_gcc_invalid);
00565       return;
00566     }
00567 
00568     PP.LexUnexpandedToken(Tok);
00569 
00570     // We need at least one string.
00571     if (Tok.isNot(tok::string_literal)) {
00572       PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
00573       return;
00574     }
00575 
00576     // String concatenation allows multiple strings, which can even come from
00577     // macro expansion.
00578     // "foo " "bar" "Baz"
00579     llvm::SmallVector<Token, 4> StrToks;
00580     while (Tok.is(tok::string_literal)) {
00581       StrToks.push_back(Tok);
00582       PP.LexUnexpandedToken(Tok);
00583     }
00584 
00585     if (Tok.isNot(tok::eom)) {
00586       PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
00587       return;
00588     }
00589 
00590     // Concatenate and parse the strings.
00591     StringLiteralParser Literal(&StrToks[0], StrToks.size(), PP);
00592     assert(!Literal.AnyWide && "Didn't allow wide strings in");
00593     if (Literal.hadError)
00594       return;
00595     if (Literal.Pascal) {
00596       unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid
00597                                  : diag::warn_pragma_diagnostic_gcc_invalid;
00598       PP.Diag(Tok, Diag);
00599       return;
00600     }
00601 
00602     std::string WarningName(Literal.GetString(),
00603                             Literal.GetString()+Literal.GetStringLength());
00604 
00605     if (WarningName.size() < 3 || WarningName[0] != '-' ||
00606         WarningName[1] != 'W') {
00607       PP.Diag(StrToks[0].getLocation(),
00608               diag::warn_pragma_diagnostic_invalid_option);
00609       return;
00610     }
00611 
00612     if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.c_str()+2,
00613                                                       Map))
00614       PP.Diag(StrToks[0].getLocation(),
00615               diag::warn_pragma_diagnostic_unknown_warning) << WarningName;
00616   }
00617 };
00618 
00619 /// PragmaCommentHandler - "#pragma comment ...".
00620 struct PragmaCommentHandler : public PragmaHandler {
00621   PragmaCommentHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
00622   virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) {
00623     PP.HandlePragmaComment(CommentTok);
00624   }
00625 };
00626 
00627 // Pragma STDC implementations.
00628 
00629 enum STDCSetting {
00630   STDC_ON, STDC_OFF, STDC_DEFAULT, STDC_INVALID
00631 };
00632 
00633 static STDCSetting LexOnOffSwitch(Preprocessor &PP) {
00634   Token Tok;
00635   PP.LexUnexpandedToken(Tok);
00636 
00637   if (Tok.isNot(tok::identifier)) {
00638     PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
00639     return STDC_INVALID;
00640   }
00641   IdentifierInfo *II = Tok.getIdentifierInfo();
00642   STDCSetting Result;
00643   if (II->isStr("ON"))
00644     Result = STDC_ON;
00645   else if (II->isStr("OFF"))
00646     Result = STDC_OFF;
00647   else if (II->isStr("DEFAULT"))
00648     Result = STDC_DEFAULT;
00649   else {
00650     PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
00651     return STDC_INVALID;
00652   }
00653 
00654   // Verify that this is followed by EOM.
00655   PP.LexUnexpandedToken(Tok);
00656   if (Tok.isNot(tok::eom))
00657     PP.Diag(Tok, diag::ext_stdc_pragma_syntax_eom);
00658   return Result;
00659 }
00660 
00661 /// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...".
00662 struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler {
00663   PragmaSTDC_FP_CONTRACTHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
00664   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
00665     // We just ignore the setting of FP_CONTRACT. Since we don't do contractions
00666     // at all, our default is OFF and setting it to ON is an optimization hint
00667     // we can safely ignore.  When we support -ffma or something, we would need
00668     // to diagnose that we are ignoring FMA.
00669     LexOnOffSwitch(PP);
00670   }
00671 };
00672 
00673 /// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...".
00674 struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
00675   PragmaSTDC_FENV_ACCESSHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
00676   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
00677     if (LexOnOffSwitch(PP) == STDC_ON)
00678       PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
00679   }
00680 };
00681 
00682 /// PragmaSTDC_CX_LIMITED_RANGEHandler - "#pragma STDC CX_LIMITED_RANGE ...".
00683 struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
00684   PragmaSTDC_CX_LIMITED_RANGEHandler(const IdentifierInfo *ID)
00685     : PragmaHandler(ID) {}
00686   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
00687     LexOnOffSwitch(PP);
00688   }
00689 };
00690 
00691 /// PragmaSTDC_UnknownHandler - "#pragma STDC ...".
00692 struct PragmaSTDC_UnknownHandler : public PragmaHandler {
00693   PragmaSTDC_UnknownHandler() : PragmaHandler(0) {}
00694   virtual void HandlePragma(Preprocessor &PP, Token &UnknownTok) {
00695     // C99 6.10.6p2, unknown forms are not allowed.
00696     PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
00697   }
00698 };
00699 
00700 }  // end anonymous namespace
00701 
00702 
00703 /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
00704 /// #pragma GCC poison/system_header/dependency and #pragma once.
00705 void Preprocessor::RegisterBuiltinPragmas() {
00706   AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
00707   AddPragmaHandler(0, new PragmaMarkHandler(getIdentifierInfo("mark")));
00708 
00709   // #pragma GCC ...
00710   AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
00711   AddPragmaHandler("GCC", new PragmaSystemHeaderHandler(
00712                                           getIdentifierInfo("system_header")));
00713   AddPragmaHandler("GCC", new PragmaDependencyHandler(
00714                                           getIdentifierInfo("dependency")));
00715   AddPragmaHandler("GCC", new PragmaDiagnosticHandler(
00716                                               getIdentifierInfo("diagnostic"),
00717                                               false));
00718   // #pragma clang ...
00719   AddPragmaHandler("clang", new PragmaPoisonHandler(
00720                                           getIdentifierInfo("poison")));
00721   AddPragmaHandler("clang", new PragmaSystemHeaderHandler(
00722                                           getIdentifierInfo("system_header")));
00723   AddPragmaHandler("clang", new PragmaDependencyHandler(
00724                                           getIdentifierInfo("dependency")));
00725   AddPragmaHandler("clang", new PragmaDiagnosticHandler(
00726                                           getIdentifierInfo("diagnostic"),
00727                                           true));
00728 
00729   AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler(
00730                                              getIdentifierInfo("FP_CONTRACT")));
00731   AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler(
00732                                              getIdentifierInfo("FENV_ACCESS")));
00733   AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler(
00734                                         getIdentifierInfo("CX_LIMITED_RANGE")));
00735   AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
00736 
00737   // MS extensions.
00738   if (Features.Microsoft)
00739     AddPragmaHandler(0, new PragmaCommentHandler(getIdentifierInfo("comment")));
00740 }