summaryrefslogtreecommitdiffstats
path: root/lib/Lex
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-07-13 17:21:42 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-07-13 17:21:42 +0000
commit1928da94b55683957759d5c5ff4593a118773394 (patch)
tree48b44512b5db8ced345df4a1a56b5065cf2a14d9 /lib/Lex
parent53992adde3eda3ccf9da63bc7e45673f043de18f (diff)
downloadFreeBSD-src-1928da94b55683957759d5c5ff4593a118773394.zip
FreeBSD-src-1928da94b55683957759d5c5ff4593a118773394.tar.gz
Update clang to r108243.
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/Lexer.cpp56
-rw-r--r--lib/Lex/LiteralSupport.cpp17
-rw-r--r--lib/Lex/Makefile8
-rw-r--r--lib/Lex/PPCaching.cpp12
-rw-r--r--lib/Lex/PPMacroExpansion.cpp2
-rw-r--r--lib/Lex/Pragma.cpp209
-rw-r--r--lib/Lex/Preprocessor.cpp10
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)
OpenPOWER on IntegriCloud