diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 |
commit | 1928da94b55683957759d5c5ff4593a118773394 (patch) | |
tree | 48b44512b5db8ced345df4a1a56b5065cf2a14d9 /lib/Lex | |
parent | 53992adde3eda3ccf9da63bc7e45673f043de18f (diff) | |
download | FreeBSD-src-1928da94b55683957759d5c5ff4593a118773394.zip FreeBSD-src-1928da94b55683957759d5c5ff4593a118773394.tar.gz |
Update clang to r108243.
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/Lexer.cpp | 56 | ||||
-rw-r--r-- | lib/Lex/LiteralSupport.cpp | 17 | ||||
-rw-r--r-- | lib/Lex/Makefile | 8 | ||||
-rw-r--r-- | lib/Lex/PPCaching.cpp | 12 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 209 | ||||
-rw-r--r-- | lib/Lex/Preprocessor.cpp | 10 |
7 files changed, 189 insertions, 125 deletions
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index cd153e1..91b14f6 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -752,19 +752,21 @@ void Lexer::LexStringLiteral(Token &Result, const char *CurPtr, bool Wide) { char C = getAndAdvanceChar(CurPtr, Result); while (C != '"') { - // Skip escaped characters. - if (C == '\\') { - // Skip the escaped character. + // Skip escaped characters. Escaped newlines will already be processed by + // getAndAdvanceChar. + if (C == '\\') C = getAndAdvanceChar(CurPtr, Result); - } else if (C == '\n' || C == '\r' || // Newline. - (C == 0 && CurPtr-1 == BufferEnd)) { // End of file. + + if (C == '\n' || C == '\r' || // Newline. + (C == 0 && CurPtr-1 == BufferEnd)) { // End of file. if (!isLexingRawMode() && !Features.AsmPreprocessor) Diag(BufferPtr, diag::err_unterminated_string); FormTokenWithChars(Result, CurPtr-1, tok::unknown); return; - } else if (C == 0) { - NulCharacter = CurPtr-1; } + + if (C == 0) + NulCharacter = CurPtr-1; C = getAndAdvanceChar(CurPtr, Result); } @@ -818,41 +820,33 @@ void Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) { void Lexer::LexCharConstant(Token &Result, const char *CurPtr) { const char *NulCharacter = 0; // Does this character contain the \0 character? - // Handle the common case of 'x' and '\y' efficiently. char C = getAndAdvanceChar(CurPtr, Result); if (C == '\'') { if (!isLexingRawMode() && !Features.AsmPreprocessor) Diag(BufferPtr, diag::err_empty_character); FormTokenWithChars(Result, CurPtr, tok::unknown); return; - } else if (C == '\\') { - // Skip the escaped character. - // FIXME: UCN's. - C = getAndAdvanceChar(CurPtr, Result); } - if (C && C != '\n' && C != '\r' && CurPtr[0] == '\'') { - ++CurPtr; - } else { - // Fall back on generic code for embedded nulls, newlines, wide chars. - do { - // Skip escaped characters. - if (C == '\\') { - // Skip the escaped character. - C = getAndAdvanceChar(CurPtr, Result); - } else if (C == '\n' || C == '\r' || // Newline. - (C == 0 && CurPtr-1 == BufferEnd)) { // End of file. - if (!isLexingRawMode() && !Features.AsmPreprocessor) - Diag(BufferPtr, diag::err_unterminated_char); - FormTokenWithChars(Result, CurPtr-1, tok::unknown); - return; - } else if (C == 0) { - NulCharacter = CurPtr-1; - } + while (C != '\'') { + // Skip escaped characters. + if (C == '\\') { + // Skip the escaped character. + // FIXME: UCN's C = getAndAdvanceChar(CurPtr, Result); - } while (C != '\''); + } else if (C == '\n' || C == '\r' || // Newline. + (C == 0 && CurPtr-1 == BufferEnd)) { // End of file. + if (!isLexingRawMode() && !Features.AsmPreprocessor) + Diag(BufferPtr, diag::err_unterminated_char); + FormTokenWithChars(Result, CurPtr-1, tok::unknown); + return; + } else if (C == 0) { + NulCharacter = CurPtr-1; + } + C = getAndAdvanceChar(CurPtr, Result); } + // If a nul character existed in the character, warn about it. if (NulCharacter && !isLexingRawMode()) Diag(NulCharacter, diag::null_in_char); diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index b73f236..b8fd3ce 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -169,9 +169,8 @@ static unsigned ProcessCharEscape(const char *&ThisTokBuf, /// we will likely rework our support for UCN's. static void ProcessUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd, char *&ResultBuf, bool &HadError, - SourceLocation Loc, bool IsWide, Preprocessor &PP, - bool Complain) -{ + SourceLocation Loc, Preprocessor &PP, + bool Complain) { // FIXME: Add a warning - UCN's are only valid in C++ & C99. // FIXME: Handle wide strings. @@ -835,11 +834,8 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks, // TODO: Input character set mapping support. // Skip L marker for wide strings. - bool ThisIsWide = false; - if (ThisTokBuf[0] == 'L') { + if (ThisTokBuf[0] == 'L') ++ThisTokBuf; - ThisIsWide = true; - } assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?"); ++ThisTokBuf; @@ -884,14 +880,13 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks, // Is this a Universal Character Name escape? if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') { ProcessUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr, - hadError, StringToks[i].getLocation(), ThisIsWide, PP, - Complain); + hadError, StringToks[i].getLocation(), PP, Complain); continue; } // Otherwise, this is a non-UCN escape character. Process it. unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError, StringToks[i].getLocation(), - ThisIsWide, PP, Complain); + AnyWide, PP, Complain); // Note: our internal rep of wide char tokens is always little-endian. *ResultPtr++ = ResultChar & 0xFF; @@ -905,6 +900,8 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks, if (Pascal) { ResultBuf[0] = ResultPtr-&ResultBuf[0]-1; + if (AnyWide) + ResultBuf[0] /= wchar_tByteWidth; // Verify that pascal strings aren't too large. if (GetStringLength() > 256 && Complain) { diff --git a/lib/Lex/Makefile b/lib/Lex/Makefile index bd3c7a8..938b8d5 100644 --- a/lib/Lex/Makefile +++ b/lib/Lex/Makefile @@ -11,8 +11,8 @@ # ##===----------------------------------------------------------------------===## -LEVEL = ../../../.. -include $(LEVEL)/Makefile.config +CLANG_LEVEL := ../.. +include $(CLANG_LEVEL)/../../Makefile.config LIBRARYNAME := clangLex BUILD_ARCHIVE = 1 @@ -21,7 +21,5 @@ ifeq ($(ARCH),PowerPC) CXX.Flags += -maltivec endif -CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include - -include $(LEVEL)/Makefile.common +include $(CLANG_LEVEL)/Makefile diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp index 6aeb6fa..3310659 100644 --- a/lib/Lex/PPCaching.cpp +++ b/lib/Lex/PPCaching.cpp @@ -45,6 +45,9 @@ void Preprocessor::Backtrack() { } void Preprocessor::CachingLex(Token &Result) { + if (!InCachingLexMode()) + return; + if (CachedLexPos < CachedTokens.size()) { Result = CachedTokens[CachedLexPos++]; return; @@ -60,13 +63,10 @@ void Preprocessor::CachingLex(Token &Result) { return; } - // We should cache the lexed token. - + // Cache the lexed token. EnterCachingLexMode(); - if (Result.isNot(tok::eof)) { - CachedTokens.push_back(Result); - ++CachedLexPos; - } + CachedTokens.push_back(Result); + ++CachedLexPos; } void Preprocessor::EnterCachingLexMode() { diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 71bb4fc..ebf606e 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -17,6 +17,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Lex/LexDiagnostic.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/raw_ostream.h" @@ -510,6 +511,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { //.Case("cxx_nullptr", false) //.Case("cxx_rvalue_references", false) //.Case("cxx_variadic_templates", false) + .Case("tls", PP.getTargetInfo().isTLSSupported()) .Default(false); } diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 92332a0..7bf4094 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -27,41 +27,47 @@ PragmaHandler::~PragmaHandler() { } //===----------------------------------------------------------------------===// +// EmptyPragmaHandler Implementation. +//===----------------------------------------------------------------------===// + +EmptyPragmaHandler::EmptyPragmaHandler() {} + +void EmptyPragmaHandler::HandlePragma(Preprocessor &PP, Token &FirstToken) {} + +//===----------------------------------------------------------------------===// // PragmaNamespace Implementation. //===----------------------------------------------------------------------===// PragmaNamespace::~PragmaNamespace() { - for (unsigned i = 0, e = Handlers.size(); i != e; ++i) - delete Handlers[i]; + for (llvm::StringMap<PragmaHandler*>::iterator + I = Handlers.begin(), E = Handlers.end(); I != E; ++I) + delete I->second; } /// FindHandler - Check to see if there is already a handler for the /// specified name. If not, return the handler for the null identifier if it /// exists, otherwise return null. If IgnoreNull is true (the default) then /// the null handler isn't returned on failure to match. -PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name, +PragmaHandler *PragmaNamespace::FindHandler(llvm::StringRef Name, bool IgnoreNull) const { - PragmaHandler *NullHandler = 0; - for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { - if (Handlers[i]->getName() == Name) - return Handlers[i]; + if (PragmaHandler *Handler = Handlers.lookup(Name)) + return Handler; + return IgnoreNull ? 0 : Handlers.lookup(llvm::StringRef()); +} - if (Handlers[i]->getName() == 0) - NullHandler = Handlers[i]; - } - return IgnoreNull ? 0 : NullHandler; +void PragmaNamespace::AddPragma(PragmaHandler *Handler) { + assert(!Handlers.lookup(Handler->getName()) && + "A handler with this name is already registered in this namespace"); + llvm::StringMapEntry<PragmaHandler *> &Entry = + Handlers.GetOrCreateValue(Handler->getName()); + Entry.setValue(Handler); } void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) { - for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { - if (Handlers[i] == Handler) { - Handlers[i] = Handlers.back(); - Handlers.pop_back(); - return; - } - } - assert(0 && "Handler not registered in this namespace"); + assert(Handlers.lookup(Handler->getName()) && + "Handler not registered in this namespace"); + Handlers.erase(Handler->getName()); } void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) { @@ -70,7 +76,10 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) { PP.LexUnexpandedToken(Tok); // Get the handler for this token. If there is no handler, ignore the pragma. - PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false); + PragmaHandler *Handler + = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName() + : llvm::StringRef(), + /*IgnoreNull=*/false); if (Handler == 0) { PP.Diag(Tok, diag::warn_pragma_ignored); return; @@ -411,31 +420,90 @@ void Preprocessor::HandlePragmaComment(Token &Tok) { Callbacks->PragmaComment(CommentLoc, II, ArgumentString); } +/// HandlePragmaMessage - Handle the microsoft #pragma message extension. The +/// syntax is: +/// #pragma message(messagestring) +/// messagestring is a string, which is fully macro expanded, and permits string +/// concatenation, embedded escape characters etc. See MSDN for more details. +void Preprocessor::HandlePragmaMessage(Token &Tok) { + SourceLocation MessageLoc = Tok.getLocation(); + Lex(Tok); + if (Tok.isNot(tok::l_paren)) { + Diag(MessageLoc, diag::err_pragma_message_malformed); + return; + } + + // Read the string. + Lex(Tok); + + + // We need at least one string. + if (Tok.isNot(tok::string_literal)) { + Diag(Tok.getLocation(), diag::err_pragma_message_malformed); + return; + } + + // String concatenation allows multiple strings, which can even come from + // macro expansion. + // "foo " "bar" "Baz" + llvm::SmallVector<Token, 4> StrToks; + while (Tok.is(tok::string_literal)) { + StrToks.push_back(Tok); + Lex(Tok); + } + + // Concatenate and parse the strings. + StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this); + assert(!Literal.AnyWide && "Didn't allow wide strings in"); + if (Literal.hadError) + return; + if (Literal.Pascal) { + Diag(StrToks[0].getLocation(), diag::err_pragma_message_malformed); + return; + } + + llvm::StringRef MessageString(Literal.GetString(), Literal.GetStringLength()); + + if (Tok.isNot(tok::r_paren)) { + Diag(Tok.getLocation(), diag::err_pragma_message_malformed); + return; + } + Lex(Tok); // eat the r_paren. + + if (Tok.isNot(tok::eom)) { + Diag(Tok.getLocation(), diag::err_pragma_message_malformed); + return; + } + + // Output the message. + Diag(MessageLoc, diag::warn_pragma_message) << MessageString; + // If the pragma is lexically sound, notify any interested PPCallbacks. + if (Callbacks) + Callbacks->PragmaMessage(MessageLoc, MessageString); +} /// AddPragmaHandler - Add the specified pragma handler to the preprocessor. /// If 'Namespace' is non-null, then it is a token required to exist on the /// pragma line before the pragma string starts, e.g. "STDC" or "GCC". -void Preprocessor::AddPragmaHandler(const char *Namespace, +void Preprocessor::AddPragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler) { PragmaNamespace *InsertNS = PragmaHandlers; // If this is specified to be in a namespace, step down into it. - if (Namespace) { - IdentifierInfo *NSID = getIdentifierInfo(Namespace); - + if (!Namespace.empty()) { // If there is already a pragma handler with the name of this namespace, // we either have an error (directive with the same name as a namespace) or // we already have the namespace to insert into. - if (PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID)) { + if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) { InsertNS = Existing->getIfNamespace(); assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma" " handler with the same name!"); } else { // Otherwise, this namespace doesn't exist yet, create and insert the // handler for it. - InsertNS = new PragmaNamespace(NSID); + InsertNS = new PragmaNamespace(Namespace); PragmaHandlers->AddPragma(InsertNS); } } @@ -450,14 +518,13 @@ void Preprocessor::AddPragmaHandler(const char *Namespace, /// preprocessor. If \arg Namespace is non-null, then it should be the /// namespace that \arg Handler was added to. It is an error to remove /// a handler that has not been registered. -void Preprocessor::RemovePragmaHandler(const char *Namespace, +void Preprocessor::RemovePragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler) { PragmaNamespace *NS = PragmaHandlers; // If this is specified to be in a namespace, step down into it. - if (Namespace) { - IdentifierInfo *NSID = getIdentifierInfo(Namespace); - PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID); + if (!Namespace.empty()) { + PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace); assert(Existing && "Namespace containing handler does not exist!"); NS = Existing->getIfNamespace(); @@ -475,7 +542,7 @@ void Preprocessor::RemovePragmaHandler(const char *Namespace, namespace { /// PragmaOnceHandler - "#pragma once" marks the file as atomically included. struct PragmaOnceHandler : public PragmaHandler { - PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {} + PragmaOnceHandler() : PragmaHandler("once") {} virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) { PP.CheckEndOfDirective("pragma once"); PP.HandlePragmaOnce(OnceTok); @@ -485,7 +552,7 @@ struct PragmaOnceHandler : public PragmaHandler { /// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the /// rest of the line is not lexed. struct PragmaMarkHandler : public PragmaHandler { - PragmaMarkHandler(const IdentifierInfo *MarkID) : PragmaHandler(MarkID) {} + PragmaMarkHandler() : PragmaHandler("mark") {} virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) { PP.HandlePragmaMark(); } @@ -493,7 +560,7 @@ struct PragmaMarkHandler : public PragmaHandler { /// PragmaPoisonHandler - "#pragma poison x" marks x as not usable. struct PragmaPoisonHandler : public PragmaHandler { - PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} + PragmaPoisonHandler() : PragmaHandler("poison") {} virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) { PP.HandlePragmaPoison(PoisonTok); } @@ -502,14 +569,14 @@ struct PragmaPoisonHandler : public PragmaHandler { /// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file /// as a system header, which silences warnings in it. struct PragmaSystemHeaderHandler : public PragmaHandler { - PragmaSystemHeaderHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} + PragmaSystemHeaderHandler() : PragmaHandler("system_header") {} virtual void HandlePragma(Preprocessor &PP, Token &SHToken) { PP.HandlePragmaSystemHeader(SHToken); PP.CheckEndOfDirective("pragma"); } }; struct PragmaDependencyHandler : public PragmaHandler { - PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} + PragmaDependencyHandler() : PragmaHandler("dependency") {} virtual void HandlePragma(Preprocessor &PP, Token &DepToken) { PP.HandlePragmaDependency(DepToken); } @@ -523,9 +590,9 @@ struct PragmaDiagnosticHandler : public PragmaHandler { private: const bool ClangMode; public: - PragmaDiagnosticHandler(const IdentifierInfo *ID, - const bool clangMode) : PragmaHandler(ID), - ClangMode(clangMode) {} + explicit PragmaDiagnosticHandler(const bool clangMode) + : PragmaHandler("diagnostic"), ClangMode(clangMode) {} + virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) { Token Tok; PP.LexUnexpandedToken(Tok); @@ -618,12 +685,20 @@ public: /// PragmaCommentHandler - "#pragma comment ...". struct PragmaCommentHandler : public PragmaHandler { - PragmaCommentHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} + PragmaCommentHandler() : PragmaHandler("comment") {} virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) { PP.HandlePragmaComment(CommentTok); } }; +/// PragmaMessageHandler - "#pragma message("...")". +struct PragmaMessageHandler : public PragmaHandler { + PragmaMessageHandler() : PragmaHandler("message") {} + virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) { + PP.HandlePragmaMessage(CommentTok); + } +}; + // Pragma STDC implementations. enum STDCSetting { @@ -660,7 +735,7 @@ static STDCSetting LexOnOffSwitch(Preprocessor &PP) { /// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...". struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler { - PragmaSTDC_FP_CONTRACTHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} + PragmaSTDC_FP_CONTRACTHandler() : PragmaHandler("FP_CONTRACT") {} virtual void HandlePragma(Preprocessor &PP, Token &Tok) { // We just ignore the setting of FP_CONTRACT. Since we don't do contractions // at all, our default is OFF and setting it to ON is an optimization hint @@ -672,7 +747,7 @@ struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler { /// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...". struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { - PragmaSTDC_FENV_ACCESSHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {} + PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {} virtual void HandlePragma(Preprocessor &PP, Token &Tok) { if (LexOnOffSwitch(PP) == STDC_ON) PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); @@ -681,8 +756,8 @@ struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { /// PragmaSTDC_CX_LIMITED_RANGEHandler - "#pragma STDC CX_LIMITED_RANGE ...". struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { - PragmaSTDC_CX_LIMITED_RANGEHandler(const IdentifierInfo *ID) - : PragmaHandler(ID) {} + PragmaSTDC_CX_LIMITED_RANGEHandler() + : PragmaHandler("CX_LIMITED_RANGE") {} virtual void HandlePragma(Preprocessor &PP, Token &Tok) { LexOnOffSwitch(PP); } @@ -690,7 +765,7 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { /// PragmaSTDC_UnknownHandler - "#pragma STDC ...". struct PragmaSTDC_UnknownHandler : public PragmaHandler { - PragmaSTDC_UnknownHandler() : PragmaHandler(0) {} + PragmaSTDC_UnknownHandler() {} virtual void HandlePragma(Preprocessor &PP, Token &UnknownTok) { // C99 6.10.6p2, unknown forms are not allowed. PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored); @@ -703,38 +778,28 @@ struct PragmaSTDC_UnknownHandler : public PragmaHandler { /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas: /// #pragma GCC poison/system_header/dependency and #pragma once. void Preprocessor::RegisterBuiltinPragmas() { - AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once"))); - AddPragmaHandler(0, new PragmaMarkHandler(getIdentifierInfo("mark"))); + AddPragmaHandler(new PragmaOnceHandler()); + AddPragmaHandler(new PragmaMarkHandler()); // #pragma GCC ... - AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison"))); - AddPragmaHandler("GCC", new PragmaSystemHeaderHandler( - getIdentifierInfo("system_header"))); - AddPragmaHandler("GCC", new PragmaDependencyHandler( - getIdentifierInfo("dependency"))); - AddPragmaHandler("GCC", new PragmaDiagnosticHandler( - getIdentifierInfo("diagnostic"), - false)); + AddPragmaHandler("GCC", new PragmaPoisonHandler()); + AddPragmaHandler("GCC", new PragmaSystemHeaderHandler()); + AddPragmaHandler("GCC", new PragmaDependencyHandler()); + AddPragmaHandler("GCC", new PragmaDiagnosticHandler(false)); // #pragma clang ... - AddPragmaHandler("clang", new PragmaPoisonHandler( - getIdentifierInfo("poison"))); - AddPragmaHandler("clang", new PragmaSystemHeaderHandler( - getIdentifierInfo("system_header"))); - AddPragmaHandler("clang", new PragmaDependencyHandler( - getIdentifierInfo("dependency"))); - AddPragmaHandler("clang", new PragmaDiagnosticHandler( - getIdentifierInfo("diagnostic"), - true)); - - AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler( - getIdentifierInfo("FP_CONTRACT"))); - AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler( - getIdentifierInfo("FENV_ACCESS"))); - AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler( - getIdentifierInfo("CX_LIMITED_RANGE"))); + AddPragmaHandler("clang", new PragmaPoisonHandler()); + AddPragmaHandler("clang", new PragmaSystemHeaderHandler()); + AddPragmaHandler("clang", new PragmaDependencyHandler()); + AddPragmaHandler("clang", new PragmaDiagnosticHandler(true)); + + AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler()); + AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler()); + AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler()); AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler()); // MS extensions. - if (Features.Microsoft) - AddPragmaHandler(0, new PragmaCommentHandler(getIdentifierInfo("comment"))); + if (Features.Microsoft) { + AddPragmaHandler(new PragmaCommentHandler()); + AddPragmaHandler(new PragmaMessageHandler()); + } } diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index ce6d9ab..51f7293 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -87,7 +87,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned(); // Initialize the pragma handlers. - PragmaHandlers = new PragmaNamespace(0); + PragmaHandlers = new PragmaNamespace(llvm::StringRef()); RegisterBuiltinPragmas(); // Initialize builtin macros like __LINE__ and friends. @@ -113,6 +113,14 @@ Preprocessor::~Preprocessor() { I->second->Destroy(BP); I->first->setHasMacroDefinition(false); } + for (std::vector<MacroInfo*>::iterator I = MICache.begin(), + E = MICache.end(); I != E; ++I) { + // We don't need to free the MacroInfo objects directly. These + // will be released when the BumpPtrAllocator 'BP' object gets + // destroyed. We still need to run the dtor, however, to free + // memory alocated by MacroInfo. + (*I)->Destroy(BP); + } // Free any cached macro expanders. for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i) |