aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
commit56d91b49b13fe55c918afbda19f6165b5fbff87a (patch)
tree9abb1a658a297776086f4e0dfa6ca533de02104e /lib/Lex
parent41e20f564abdb05101d6b2b29c59459a966c22cc (diff)
downloadsrc-56d91b49b13fe55c918afbda19f6165b5fbff87a.tar.gz
src-56d91b49b13fe55c918afbda19f6165b5fbff87a.zip
Vendor import of clang trunk r161861:vendor/clang/clang-trunk-r161861
Notes
Notes: svn path=/vendor/clang/dist/; revision=239313 svn path=/vendor/clang/clang-trunk-r161861/; revision=239314; tag=vendor/clang/clang-trunk-r161861
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/CMakeLists.txt12
-rw-r--r--lib/Lex/HeaderSearch.cpp42
-rw-r--r--lib/Lex/Lexer.cpp91
-rw-r--r--lib/Lex/LiteralSupport.cpp154
-rw-r--r--lib/Lex/PPDirectives.cpp183
-rw-r--r--lib/Lex/PPLexerChange.cpp2
-rw-r--r--lib/Lex/PPMacroExpansion.cpp46
-rw-r--r--lib/Lex/Pragma.cpp78
-rw-r--r--lib/Lex/PreprocessingRecord.cpp4
-rw-r--r--lib/Lex/Preprocessor.cpp127
-rw-r--r--lib/Lex/PreprocessorLexer.cpp2
-rw-r--r--lib/Lex/TokenConcatenation.cpp1
-rw-r--r--lib/Lex/TokenLexer.cpp12
13 files changed, 470 insertions, 284 deletions
diff --git a/lib/Lex/CMakeLists.txt b/lib/Lex/CMakeLists.txt
index 0a2ffdbf232d..241abbc4bc68 100644
--- a/lib/Lex/CMakeLists.txt
+++ b/lib/Lex/CMakeLists.txt
@@ -2,8 +2,6 @@
set(LLVM_LINK_COMPONENTS support)
-set(LLVM_USED_LIBS clangBasic)
-
add_clang_library(clangLex
HeaderMap.cpp
HeaderSearch.cpp
@@ -28,4 +26,12 @@ add_clang_library(clangLex
TokenLexer.cpp
)
-add_dependencies(clangLex ClangDiagnosticLex ClangAttrSpellings)
+add_dependencies(clangLex
+ ClangAttrSpellings
+ ClangDiagnosticCommon
+ ClangDiagnosticLex
+ )
+
+target_link_libraries(clangLex
+ clangBasic
+ )
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index d688e23fa405..bb3a67378ad5 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -84,7 +84,7 @@ void HeaderSearch::PrintStats() {
}
/// CreateHeaderMap - This method returns a HeaderMap for the specified
-/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
+/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
// We expect the number of headermaps to be small, and almost always empty.
// If it ever grows, use of a linear search should be re-evaluated.
@@ -390,10 +390,10 @@ void HeaderSearch::setTarget(const TargetInfo &Target) {
//===----------------------------------------------------------------------===//
-/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+/// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
/// return null on failure. isAngled indicates whether the file reference is
-/// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if
-/// non-null, indicates where the #including file is, in case a relative search
+/// for system \#include's or not (i.e. using <> instead of ""). CurFileEnt, if
+/// non-null, indicates where the \#including file is, in case a relative search
/// is needed.
const FileEntry *HeaderSearch::LookupFile(
StringRef Filename,
@@ -442,11 +442,19 @@ const FileEntry *HeaderSearch::LookupFile(
// Leave CurDir unset.
// This file is a system header or C++ unfriendly if the old file is.
//
- // Note that the temporary 'DirInfo' is required here, as either call to
- // getFileInfo could resize the vector and we don't want to rely on order
- // of evaluation.
- unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
- getFileInfo(FE).DirInfo = DirInfo;
+ // Note that we only use one of FromHFI/ToHFI at once, due to potential
+ // reallocation of the underlying vector potentially making the first
+ // reference binding dangling.
+ HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt);
+ unsigned DirInfo = FromHFI.DirInfo;
+ bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
+ StringRef Framework = FromHFI.Framework;
+
+ HeaderFileInfo &ToHFI = getFileInfo(FE);
+ ToHFI.DirInfo = DirInfo;
+ ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
+ ToHFI.Framework = Framework;
+
if (SearchPath != NULL) {
StringRef SearchPathRef(CurFileEnt->getDir()->getName());
SearchPath->clear();
@@ -510,6 +518,16 @@ const FileEntry *HeaderSearch::LookupFile(
if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
HFI.DirInfo = SrcMgr::C_System;
+ // If the filename matches a known system header prefix, override
+ // whether the file is a system header.
+ for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
+ if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
+ HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
+ : SrcMgr::C_User;
+ break;
+ }
+ }
+
// If this file is found in a header map and uses the framework style of
// includes, then this header is part of a framework we're building.
if (CurDir->isIndexHeaderMap()) {
@@ -556,7 +574,7 @@ const FileEntry *HeaderSearch::LookupFile(
}
/// LookupSubframeworkHeader - Look up a subframework for the specified
-/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
+/// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
/// is a subframework within Carbon.framework. If so, return the FileEntry
/// for the designated file, otherwise return null.
@@ -739,9 +757,6 @@ void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) {
FileInfo[UID] = HFI;
}
-/// ShouldEnterIncludeFile - Mark the specified file as a target of of a
-/// #include, #include_next, or #import directive. Return false if #including
-/// the file will have no effect or true if we should include it.
bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
++NumIncluded; // Count # of attempted #includes.
@@ -1032,4 +1047,3 @@ void HeaderSearch::collectAllModules(llvm::SmallVectorImpl<Module *> &Modules) {
Modules.push_back(M->getValue());
}
}
-
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 535a852429b5..5212dd86e7a1 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -127,7 +127,7 @@ Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *InputFile, Preprocessor &PP)
}
/// Lexer constructor - Create a new raw lexer object. This object is only
-/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
+/// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
const char *BufStart, const char *BufPtr, const char *BufEnd)
@@ -140,7 +140,7 @@ Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
}
/// Lexer constructor - Create a new raw lexer object. This object is only
-/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
+/// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *FromFile,
const SourceManager &SM, const LangOptions &langOpts)
@@ -544,7 +544,6 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer,
if (InPreprocessorDirective) {
// If we've hit the end of the file, we're done.
if (TheTok.getKind() == tok::eof) {
- InPreprocessorDirective = false;
break;
}
@@ -820,10 +819,6 @@ static CharSourceRange makeRangeFromFileLocs(CharSourceRange Range,
return CharSourceRange::getCharRange(Begin, End);
}
-/// \brief Accepts a range and returns a character range with file locations.
-///
-/// Returns a null range if a part of the range resides inside a macro
-/// expansion or the range does not reside on the same FileID.
CharSourceRange Lexer::makeFileCharRange(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts) {
@@ -1091,20 +1086,21 @@ static inline bool isIdentifierBody(unsigned char c) {
}
/// isHorizontalWhitespace - Return true if this character is horizontal
-/// whitespace: ' ', '\t', '\f', '\v'. Note that this returns false for '\0'.
+/// whitespace: ' ', '\\t', '\\f', '\\v'. Note that this returns false for
+/// '\\0'.
static inline bool isHorizontalWhitespace(unsigned char c) {
return (CharInfo[c] & CHAR_HORZ_WS) ? true : false;
}
/// isVerticalWhitespace - Return true if this character is vertical
-/// whitespace: '\n', '\r'. Note that this returns false for '\0'.
+/// whitespace: '\\n', '\\r'. Note that this returns false for '\\0'.
static inline bool isVerticalWhitespace(unsigned char c) {
return (CharInfo[c] & CHAR_VERT_WS) ? true : false;
}
/// isWhitespace - Return true if this character is horizontal or vertical
-/// whitespace: ' ', '\t', '\f', '\v', '\n', '\r'. Note that this returns false
-/// for '\0'.
+/// whitespace: ' ', '\\t', '\\f', '\\v', '\\n', '\\r'. Note that this returns
+/// false for '\\0'.
static inline bool isWhitespace(unsigned char c) {
return (CharInfo[c] & (CHAR_HORZ_WS|CHAR_VERT_WS)) ? true : false;
}
@@ -1124,6 +1120,11 @@ static inline bool isRawStringDelimBody(unsigned char c) {
true : false;
}
+// Allow external clients to make use of CharInfo.
+bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) {
+ return isIdentifierBody(c) || (c == '$' && LangOpts.DollarIdents);
+}
+
//===----------------------------------------------------------------------===//
// Diagnostics forwarding code.
@@ -1564,8 +1565,20 @@ void Lexer::LexNumericConstant(Token &Result, const char *CurPtr) {
}
// If we have a hex FP constant, continue.
- if ((C == '-' || C == '+') && (PrevCh == 'P' || PrevCh == 'p'))
- return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
+ if ((C == '-' || C == '+') && (PrevCh == 'P' || PrevCh == 'p')) {
+ // Outside C99, we accept hexadecimal floating point numbers as a
+ // not-quite-conforming extension. Only do so if this looks like it's
+ // actually meant to be a hexfloat, and not if it has a ud-suffix.
+ bool IsHexFloat = true;
+ if (!LangOpts.C99) {
+ if (!isHexaLiteral(BufferPtr, LangOpts))
+ IsHexFloat = false;
+ else if (std::find(BufferPtr, CurPtr, '_') != CurPtr)
+ IsHexFloat = false;
+ }
+ if (IsHexFloat)
+ return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
+ }
// Update the location of token as well as BufferPtr.
const char *TokStart = BufferPtr;
@@ -1635,7 +1648,7 @@ void Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
- Diag(BufferPtr, diag::warn_unterminated_string);
+ Diag(BufferPtr, diag::ext_unterminated_string);
FormTokenWithChars(Result, CurPtr-1, tok::unknown);
return;
}
@@ -1755,7 +1768,7 @@ void Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
// Skip escaped characters.
if (C == '\\') {
// Skip the escaped character.
- C = getAndAdvanceChar(CurPtr, Result);
+ getAndAdvanceChar(CurPtr, Result);
} else if (C == '\n' || C == '\r' || // Newline.
(C == 0 && (CurPtr-1 == BufferEnd || // End of file.
isCodeCompletionPoint(CurPtr-1)))) {
@@ -1793,7 +1806,7 @@ void Lexer::LexCharConstant(Token &Result, const char *CurPtr,
char C = getAndAdvanceChar(CurPtr, Result);
if (C == '\'') {
if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
- Diag(BufferPtr, diag::err_empty_character);
+ Diag(BufferPtr, diag::ext_empty_character);
FormTokenWithChars(Result, CurPtr, tok::unknown);
return;
}
@@ -1803,11 +1816,11 @@ void Lexer::LexCharConstant(Token &Result, const char *CurPtr,
if (C == '\\') {
// Skip the escaped character.
// FIXME: UCN's
- C = getAndAdvanceChar(CurPtr, Result);
+ getAndAdvanceChar(CurPtr, Result);
} else if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
- Diag(BufferPtr, diag::warn_unterminated_char);
+ Diag(BufferPtr, diag::ext_unterminated_char);
FormTokenWithChars(Result, CurPtr-1, tok::unknown);
return;
} else if (C == 0) {
@@ -1924,8 +1937,6 @@ bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
CurPtr = EscapePtr-2;
else
break; // This is a newline, we're done.
-
- C = *CurPtr;
}
// Otherwise, this is a hard case. Fall back on getAndAdvanceChar to
@@ -2022,7 +2033,7 @@ bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) {
// directly.
FormTokenWithChars(Result, CurPtr, tok::comment);
- if (!ParsingPreprocessorDirective)
+ if (!ParsingPreprocessorDirective || LexingRawMode)
return true;
// If this BCPL-style comment is in a macro definition, transmogrify it into
@@ -2043,8 +2054,8 @@ bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) {
}
/// isBlockCommentEndOfEscapedNewLine - Return true if the specified newline
-/// character (either \n or \r) is part of an escaped newline sequence. Issue a
-/// diagnostic if so. We know that the newline is inside of a block comment.
+/// character (either \\n or \\r) is part of an escaped newline sequence. Issue
+/// a diagnostic if so. We know that the newline is inside of a block comment.
static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr,
Lexer *L) {
assert(CurPtr[0] == '\n' || CurPtr[0] == '\r');
@@ -2110,12 +2121,12 @@ static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr,
#undef bool
#endif
-/// SkipBlockComment - We have just read the /* characters from input. Read
-/// until we find the */ characters that terminate the comment. Note that we
-/// don't bother decoding trigraphs or escaped newlines in block comments,
-/// because they cannot cause the comment to end. The only thing that can
-/// happen is the comment could end with an escaped newline between the */ end
-/// of comment.
+/// We have just read from input the / and * characters that started a comment.
+/// Read until we find the * and / characters that terminate the comment.
+/// Note that we don't bother decoding trigraphs or escaped newlines in block
+/// comments, because they cannot cause the comment to end. The only thing
+/// that can happen is the comment could end with an escaped newline between
+/// the terminating * and /.
///
/// If we're in KeepCommentMode or any CommentHandler has inserted
/// some tokens, this will store the first token and return true.
@@ -2286,10 +2297,9 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
/// uninterpreted string. This switches the lexer out of directive mode.
-std::string Lexer::ReadToEndOfLine() {
+void Lexer::ReadToEndOfLine(SmallVectorImpl<char> *Result) {
assert(ParsingPreprocessorDirective && ParsingFilename == false &&
"Must be in a preprocessing directive!");
- std::string Result;
Token Tmp;
// CurPtr - Cache BufferPtr in an automatic variable.
@@ -2298,7 +2308,8 @@ std::string Lexer::ReadToEndOfLine() {
char Char = getAndAdvanceChar(CurPtr, Tmp);
switch (Char) {
default:
- Result += Char;
+ if (Result)
+ Result->push_back(Char);
break;
case 0: // Null.
// Found end of file?
@@ -2306,11 +2317,12 @@ std::string Lexer::ReadToEndOfLine() {
if (isCodeCompletionPoint(CurPtr-1)) {
PP->CodeCompleteNaturalLanguage();
cutOffLexing();
- return Result;
+ return;
}
// Nope, normal character, continue.
- Result += Char;
+ if (Result)
+ Result->push_back(Char);
break;
}
// FALL THROUGH.
@@ -2329,8 +2341,8 @@ std::string Lexer::ReadToEndOfLine() {
}
assert(Tmp.is(tok::eod) && "Unexpected token!");
- // Finally, we're done, return the string we found.
- return Result;
+ // Finally, we're done;
+ return;
}
}
}
@@ -2383,7 +2395,7 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
BufferPtr = CurPtr;
// Finally, let the preprocessor handle this.
- return PP->HandleEndOfFile(Result);
+ return PP->HandleEndOfFile(Result, isPragmaLexer());
}
/// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from
@@ -2418,7 +2430,7 @@ unsigned Lexer::isNextPPTokenLParen() {
return Tok.is(tok::l_paren);
}
-/// FindConflictEnd - Find the end of a version control conflict marker.
+/// \brief Find the end of a version control conflict marker.
static const char *FindConflictEnd(const char *CurPtr, const char *BufferEnd,
ConflictMarkerKind CMK) {
const char *Terminator = CMK == CMK_Perforce ? "<<<<\n" : ">>>>>>>";
@@ -2625,7 +2637,8 @@ LexNextToken:
ParsingPreprocessorDirective = false;
// Restore comment saving mode, in case it was disabled for directive.
- SetCommentRetentionState(PP->getCommentRetentionState());
+ if (PP)
+ SetCommentRetentionState(PP->getCommentRetentionState());
// Since we consumed a newline, we are back at the start of a line.
IsAtStartOfLine = true;
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index c1d228b87989..9e3c7786a732 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -250,6 +250,39 @@ static bool ProcessUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
return true;
}
+/// MeasureUCNEscape - Determine the number of bytes within the resulting string
+/// which this UCN will occupy.
+static int MeasureUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
+ const char *ThisTokEnd, unsigned CharByteWidth,
+ const LangOptions &Features, bool &HadError) {
+ // UTF-32: 4 bytes per escape.
+ if (CharByteWidth == 4)
+ return 4;
+
+ uint32_t UcnVal = 0;
+ unsigned short UcnLen = 0;
+ FullSourceLoc Loc;
+
+ if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal,
+ UcnLen, Loc, 0, Features, true)) {
+ HadError = true;
+ return 0;
+ }
+
+ // UTF-16: 2 bytes for BMP, 4 bytes otherwise.
+ if (CharByteWidth == 2)
+ return UcnVal <= 0xFFFF ? 2 : 4;
+
+ // UTF-8.
+ if (UcnVal < 0x80)
+ return 1;
+ if (UcnVal < 0x800)
+ return 2;
+ if (UcnVal < 0x10000)
+ return 3;
+ return 4;
+}
+
/// EncodeUCNEscape - Read the Universal Character Name, check constraints and
/// convert the UTF32 to UTF8 or UTF16. This is a subroutine of
/// StringLiteralParser. When we decide to implement UCN's for identifiers,
@@ -265,7 +298,7 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
unsigned short UcnLen = 0;
if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal, UcnLen,
Loc, Diags, Features, true)) {
- HadError = 1;
+ HadError = true;
return;
}
@@ -289,7 +322,7 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
// using reinterpret_cast.
UTF16 *ResultPtr = reinterpret_cast<UTF16*>(ResultBuf);
- if (UcnVal < (UTF32)0xFFFF) {
+ if (UcnVal <= (UTF32)0xFFFF) {
*ResultPtr = UcnVal;
ResultBuf += 2;
return;
@@ -756,6 +789,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) {
}
+/// \verbatim
/// user-defined-character-literal: [C++11 lex.ext]
/// character-literal ud-suffix
/// ud-suffix:
@@ -791,6 +825,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) {
/// \U hex-quad hex-quad
/// hex-quad:
/// hex-digit hex-digit hex-digit hex-digit
+/// \endverbatim
///
CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
SourceLocation Loc, Preprocessor &PP,
@@ -971,7 +1006,7 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
Value = (signed char)Value;
}
-
+/// \verbatim
/// string-literal: [C++0x lex.string]
/// encoding-prefix " [s-char-sequence] "
/// encoding-prefix R raw-string
@@ -1023,6 +1058,7 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
/// \U hex-quad hex-quad
/// hex-quad:
/// hex-digit hex-digit hex-digit hex-digit
+/// \endverbatim
///
StringLiteralParser::
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
@@ -1037,10 +1073,8 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
// The literal token may have come from an invalid source location (e.g. due
// to a PCH error), in which case the token length will be 0.
- if (NumStringToks == 0 || StringToks[0].getLength() < 2) {
- hadError = true;
- return;
- }
+ if (NumStringToks == 0 || StringToks[0].getLength() < 2)
+ return DiagnoseLexingError(SourceLocation());
// Scan all of the string portions, remember the max individual token length,
// computing a bound on the concatenated string length, and see whether any
@@ -1057,10 +1091,8 @@ void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
// Implement Translation Phase #6: concatenation of string literals
/// (C99 5.1.1.2p1). The common case is only one string fragment.
for (unsigned i = 1; i != NumStringToks; ++i) {
- if (StringToks[i].getLength() < 2) {
- hadError = true;
- return;
- }
+ if (StringToks[i].getLength() < 2)
+ return DiagnoseLexingError(StringToks[i].getLocation());
// The string could be shorter than this if it needs cleaning, but this is a
// reasonable bound, which is all we need.
@@ -1123,10 +1155,8 @@ void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
unsigned ThisTokLen =
Lexer::getSpelling(StringToks[i], ThisTokBuf, SM, Features,
&StringInvalid);
- if (StringInvalid) {
- hadError = true;
- continue;
- }
+ if (StringInvalid)
+ return DiagnoseLexingError(StringToks[i].getLocation());
const char *ThisTokBegin = ThisTokBuf;
const char *ThisTokEnd = ThisTokBuf+ThisTokLen;
@@ -1192,7 +1222,11 @@ void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
if (DiagnoseBadString(StringToks[i]))
hadError = true;
} else {
- assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
+ if (ThisTokBuf[0] != '"') {
+ // The file may have come from PCH and then changed after loading the
+ // PCH; Fail gracefully.
+ return DiagnoseLexingError(StringToks[i].getLocation());
+ }
++ThisTokBuf; // skip "
// Check if this is a pascal string
@@ -1296,45 +1330,10 @@ void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
}
}
-
/// copyStringFragment - This function copies from Start to End into ResultPtr.
/// Performs widening for multi-byte characters.
bool StringLiteralParser::CopyStringFragment(StringRef Fragment) {
- assert(CharByteWidth==1 || CharByteWidth==2 || CharByteWidth==4);
- ConversionResult result = conversionOK;
- // Copy the character span over.
- if (CharByteWidth == 1) {
- if (!isLegalUTF8String(reinterpret_cast<const UTF8*>(Fragment.begin()),
- reinterpret_cast<const UTF8*>(Fragment.end())))
- result = sourceIllegal;
- memcpy(ResultPtr, Fragment.data(), Fragment.size());
- ResultPtr += Fragment.size();
- } else if (CharByteWidth == 2) {
- UTF8 const *sourceStart = (UTF8 const *)Fragment.data();
- // FIXME: Make the type of the result buffer correct instead of
- // using reinterpret_cast.
- UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
- ConversionFlags flags = strictConversion;
- result = ConvertUTF8toUTF16(
- &sourceStart,sourceStart + Fragment.size(),
- &targetStart,targetStart + 2*Fragment.size(),flags);
- if (result==conversionOK)
- ResultPtr = reinterpret_cast<char*>(targetStart);
- } else if (CharByteWidth == 4) {
- UTF8 const *sourceStart = (UTF8 const *)Fragment.data();
- // FIXME: Make the type of the result buffer correct instead of
- // using reinterpret_cast.
- UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
- ConversionFlags flags = strictConversion;
- result = ConvertUTF8toUTF32(
- &sourceStart,sourceStart + Fragment.size(),
- &targetStart,targetStart + 4*Fragment.size(),flags);
- if (result==conversionOK)
- ResultPtr = reinterpret_cast<char*>(targetStart);
- }
- assert((result != targetExhausted)
- && "ConvertUTF8toUTFXX exhausted target buffer");
- return result != conversionOK;
+ return !ConvertUTF8toWide(CharByteWidth, Fragment, ResultPtr);
}
bool StringLiteralParser::DiagnoseBadString(const Token &Tok) {
@@ -1349,6 +1348,12 @@ bool StringLiteralParser::DiagnoseBadString(const Token &Tok) {
return !NoErrorOnBadEncoding;
}
+void StringLiteralParser::DiagnoseLexingError(SourceLocation Loc) {
+ hadError = true;
+ if (Diags)
+ Diags->Report(Loc, diag::err_lexing_string);
+}
+
/// getOffsetOfStringByte - This function returns the offset of the
/// specified byte of the string data represented by Token. This handles
/// advancing over escape sequences in the string.
@@ -1365,14 +1370,31 @@ unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
if (StringInvalid)
return 0;
+ const char *SpellingStart = SpellingPtr;
+ const char *SpellingEnd = SpellingPtr+TokLen;
+
+ // Handle UTF-8 strings just like narrow strings.
+ if (SpellingPtr[0] == 'u' && SpellingPtr[1] == '8')
+ SpellingPtr += 2;
+
assert(SpellingPtr[0] != 'L' && SpellingPtr[0] != 'u' &&
SpellingPtr[0] != 'U' && "Doesn't handle wide or utf strings yet");
+ // For raw string literals, this is easy.
+ if (SpellingPtr[0] == 'R') {
+ assert(SpellingPtr[1] == '"' && "Should be a raw string literal!");
+ // Skip 'R"'.
+ SpellingPtr += 2;
+ while (*SpellingPtr != '(') {
+ ++SpellingPtr;
+ assert(SpellingPtr < SpellingEnd && "Missing ( for raw string literal");
+ }
+ // Skip '('.
+ ++SpellingPtr;
+ return SpellingPtr - SpellingStart + ByteNo;
+ }
- const char *SpellingStart = SpellingPtr;
- const char *SpellingEnd = SpellingPtr+TokLen;
-
- // Skip over the leading quote.
+ // Skip over the leading quote
assert(SpellingPtr[0] == '"' && "Should be a string literal!");
++SpellingPtr;
@@ -1389,11 +1411,23 @@ unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
// Otherwise, this is an escape character. Advance over it.
bool HadError = false;
- ProcessCharEscape(SpellingPtr, SpellingEnd, HadError,
- FullSourceLoc(Tok.getLocation(), SM),
- CharByteWidth*8, Diags);
+ if (SpellingPtr[1] == 'u' || SpellingPtr[1] == 'U') {
+ const char *EscapePtr = SpellingPtr;
+ unsigned Len = MeasureUCNEscape(SpellingStart, SpellingPtr, SpellingEnd,
+ 1, Features, HadError);
+ if (Len > ByteNo) {
+ // ByteNo is somewhere within the escape sequence.
+ SpellingPtr = EscapePtr;
+ break;
+ }
+ ByteNo -= Len;
+ } else {
+ ProcessCharEscape(SpellingPtr, SpellingEnd, HadError,
+ FullSourceLoc(Tok.getLocation(), SM),
+ CharByteWidth*8, Diags);
+ --ByteNo;
+ }
assert(!HadError && "This method isn't valid on erroneous strings");
- --ByteNo;
}
return SpellingPtr-SpellingStart;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 625a204af995..74b9cbc881ac 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file implements # directive processing for the Preprocessor.
-//
+///
+/// \file
+/// \brief Implements # directive processing for the Preprocessor.
+///
//===----------------------------------------------------------------------===//
#include "clang/Lex/Preprocessor.h"
@@ -61,8 +62,8 @@ MacroInfo *Preprocessor::CloneMacroInfo(const MacroInfo &MacroToClone) {
return MI;
}
-/// ReleaseMacroInfo - Release the specified MacroInfo. This memory will
-/// be reused for allocating new MacroInfo objects.
+/// \brief Release the specified MacroInfo to be reused for allocating
+/// new MacroInfo objects.
void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) {
MacroInfoChain *MIChain = (MacroInfoChain*) MI;
if (MacroInfoChain *Prev = MIChain->Prev) {
@@ -82,8 +83,8 @@ void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) {
MI->Destroy();
}
-/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
-/// current line until the tok::eod token is found.
+/// \brief Read and discard all tokens remaining on the current line until
+/// the tok::eod token is found.
void Preprocessor::DiscardUntilEndOfDirective() {
Token Tmp;
do {
@@ -92,11 +93,13 @@ void Preprocessor::DiscardUntilEndOfDirective() {
} while (Tmp.isNot(tok::eod));
}
-/// ReadMacroName - Lex and validate a macro name, which occurs after a
-/// #define or #undef. This sets the token kind to eod and discards the rest
-/// of the macro line if the macro name is invalid. isDefineUndef is 1 if
-/// this is due to a a #define, 2 if #undef directive, 0 if it is something
-/// else (e.g. #ifdef).
+/// \brief Lex and validate a macro name, which occurs after a
+/// \#define or \#undef.
+///
+/// This sets the token kind to eod and discards the rest
+/// of the macro line if the macro name is invalid. \p isDefineUndef is 1 if
+/// this is due to a a \#define, 2 if \#undef directive, 0 if it is something
+/// else (e.g. \#ifdef).
void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) {
// Read the token, don't allow macro expansion on it.
LexUnexpandedToken(MacroNameTok);
@@ -157,8 +160,9 @@ void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) {
return DiscardUntilEndOfDirective();
}
-/// CheckEndOfDirective - Ensure that the next token is a tok::eod token. If
-/// not, emit a diagnostic and consume up until the eod. If EnableMacros is
+/// \brief Ensure that the next token is a tok::eod token.
+///
+/// If not, emit a diagnostic and consume up until the eod. If EnableMacros is
/// true, then we consider macros that expand to zero tokens as being ok.
void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
Token Tmp;
@@ -191,14 +195,14 @@ void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
-/// SkipExcludedConditionalBlock - We just read a #if or related directive and
-/// decided that the subsequent tokens are in the #if'd out portion of the
-/// file. Lex the rest of the file, until we see an #endif. If
+/// SkipExcludedConditionalBlock - We just read a \#if or related directive and
+/// decided that the subsequent tokens are in the \#if'd out portion of the
+/// file. Lex the rest of the file, until we see an \#endif. If
/// FoundNonSkipPortion is true, then we have already emitted code for part of
-/// this #if directive, so #else/#elif blocks should never be entered. If ElseOk
-/// is true, then #else directives are ok, if not, then we have already seen one
-/// so a #else directive is a duplicate. When this returns, the caller can lex
-/// the first valid token.
+/// this \#if directive, so \#else/\#elif blocks should never be entered.
+/// If ElseOk is true, then \#else directives are ok, if not, then we have
+/// already seen one so a \#else directive is a duplicate. When this returns,
+/// the caller can lex the first valid token.
void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
bool FoundNonSkipPortion,
bool FoundElse,
@@ -317,7 +321,6 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
} else if (Directive[0] == 'e') {
StringRef Sub = Directive.substr(1);
if (Sub == "ndif") { // "endif"
- CheckEndOfDirective("endif");
PPConditionalInfo CondInfo;
CondInfo.WasSkipping = true; // Silence bogus warning.
bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
@@ -326,9 +329,16 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
// If we popped the outermost skipping block, we're done skipping!
if (!CondInfo.WasSkipping) {
+ // Restore the value of LexingRawMode so that trailing comments
+ // are handled correctly, if we've reached the outermost block.
+ CurPPLexer->LexingRawMode = false;
+ CheckEndOfDirective("endif");
+ CurPPLexer->LexingRawMode = true;
if (Callbacks)
Callbacks->Endif(Tok.getLocation(), CondInfo.IfLoc);
break;
+ } else {
+ DiscardUntilEndOfDirective();
}
} else if (Sub == "lse") { // "else".
// #else directive in a skipping conditional. If not in some other
@@ -346,7 +356,11 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
// entered, enter the #else block now.
if (!CondInfo.WasSkipping && !CondInfo.FoundNonSkip) {
CondInfo.FoundNonSkip = true;
+ // Restore the value of LexingRawMode so that trailing comments
+ // are handled correctly.
+ CurPPLexer->LexingRawMode = false;
CheckEndOfDirective("else");
+ CurPPLexer->LexingRawMode = true;
if (Callbacks)
Callbacks->Else(Tok.getLocation(), CondInfo.IfLoc);
break;
@@ -484,9 +498,6 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() {
}
}
-/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
-/// return null on failure. isAngled indicates whether the file reference is
-/// for system #include's or not (i.e. using <> instead of "").
const FileEntry *Preprocessor::LookupFile(
StringRef Filename,
bool isAngled,
@@ -553,6 +564,21 @@ const FileEntry *Preprocessor::LookupFile(
// Preprocessor Directive Handling.
//===----------------------------------------------------------------------===//
+class Preprocessor::ResetMacroExpansionHelper {
+public:
+ ResetMacroExpansionHelper(Preprocessor *pp)
+ : PP(pp), save(pp->DisableMacroExpansion) {
+ if (pp->MacroExpansionInDirectivesOverride)
+ pp->DisableMacroExpansion = false;
+ }
+ ~ResetMacroExpansionHelper() {
+ PP->DisableMacroExpansion = save;
+ }
+private:
+ Preprocessor *PP;
+ bool save;
+};
+
/// HandleDirective - This callback is invoked when the lexer sees a # token
/// at the start of a line. This consumes the directive, modifies the
/// lexer/preprocessor state, and advances the lexer(s) so that the next token
@@ -604,6 +630,10 @@ void Preprocessor::HandleDirective(Token &Result) {
Diag(Result, diag::ext_embedded_directive);
}
+ // Temporarily enable macro expansion if set so
+ // and reset to previous state when returning from this function.
+ ResetMacroExpansionHelper helper(this);
+
TryAgain:
switch (Result.getKind()) {
case tok::eod:
@@ -774,23 +804,19 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
Val = NextVal;
}
- // Reject 0, this is needed both by #line numbers and flags.
- if (Val == 0) {
- PP.Diag(DigitTok, DiagID);
- PP.DiscardUntilEndOfDirective();
- return true;
- }
-
- if (DigitTokBegin[0] == '0')
+ if (DigitTokBegin[0] == '0' && Val)
PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal);
return false;
}
-/// HandleLineDirective - Handle #line directive: C99 6.10.4. The two
-/// acceptable forms are:
+/// \brief Handle a \#line directive: C99 6.10.4.
+///
+/// The two acceptable forms are:
+/// \verbatim
/// # line digit-sequence
/// # line digit-sequence "s-char-sequence"
+/// \endverbatim
void Preprocessor::HandleLineDirective(Token &Tok) {
// Read the line # and string argument. Per C99 6.10.4p5, these tokens are
// expanded.
@@ -801,6 +827,9 @@ void Preprocessor::HandleLineDirective(Token &Tok) {
unsigned LineNo;
if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*this))
return;
+
+ if (LineNo == 0)
+ Diag(DigitTok, diag::ext_pp_line_zero);
// Enforce C99 6.10.4p3: "The digit sequence shall not specify ... a
// number greater than 2147483647". C90 requires that the line # be <= 32767.
@@ -1018,15 +1047,13 @@ void Preprocessor::HandleUserDiagnosticDirective(Token &Tok,
// tokens. For example, this is allowed: "#warning ` 'foo". GCC does
// collapse multiple consequtive white space between tokens, but this isn't
// specified by the standard.
- std::string Message = CurLexer->ReadToEndOfLine();
+ SmallString<128> Message;
+ CurLexer->ReadToEndOfLine(&Message);
// Find the first non-whitespace character, so that we can make the
// diagnostic more succinct.
- StringRef Msg(Message);
- size_t i = Msg.find_first_not_of(' ');
- if (i < Msg.size())
- Msg = Msg.substr(i);
-
+ StringRef Msg = Message.str().ltrim(" ");
+
if (isWarning)
Diag(Tok, diag::pp_hash_warning) << Msg;
else
@@ -1135,7 +1162,7 @@ void Preprocessor::HandleMacroPrivateDirective(Token &Tok) {
//===----------------------------------------------------------------------===//
/// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
-/// checked and spelled filename, e.g. as an operand of #include. This returns
+/// checked and spelled filename, e.g. as an operand of \#include. This returns
/// true if the input filename was in <>'s or false if it were in ""'s. The
/// caller is expected to provide a buffer that is large enough to hold the
/// spelling of the filename, but is also expected to handle the case when
@@ -1179,11 +1206,14 @@ bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
return isAngled;
}
-/// ConcatenateIncludeName - Handle cases where the #include name is expanded
-/// from a macro as multiple tokens, which need to be glued together. This
-/// occurs for code like:
-/// #define FOO <a/b.h>
-/// #include FOO
+/// \brief Handle cases where the \#include name is expanded from a macro
+/// as multiple tokens, which need to be glued together.
+///
+/// This occurs for code like:
+/// \code
+/// \#define FOO <a/b.h>
+/// \#include FOO
+/// \endcode
/// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
///
/// This code concatenates and consumes tokens up to the '>' token. It returns
@@ -1238,10 +1268,10 @@ bool Preprocessor::ConcatenateIncludeName(
return true;
}
-/// HandleIncludeDirective - The "#include" tokens have just been read, read the
-/// file to be included from the lexer, then include it! This is a common
-/// routine with functionality shared between #include, #include_next and
-/// #import. LookupFrom is set when this is a #include_next directive, it
+/// HandleIncludeDirective - The "\#include" tokens have just been read, read
+/// the file to be included from the lexer, then include it! This is a common
+/// routine with functionality shared between \#include, \#include_next and
+/// \#import. LookupFrom is set when this is a \#include_next directive, it
/// specifies the file to start searching from.
void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
Token &IncludeTok,
@@ -1360,9 +1390,28 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
}
if (File == 0) {
- if (!SuppressIncludeNotFoundError)
- Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
- return;
+ if (!SuppressIncludeNotFoundError) {
+ // If the file could not be located and it was included via angle
+ // brackets, we can attempt a lookup as though it were a quoted path to
+ // provide the user with a possible fixit.
+ if (isAngled) {
+ File = LookupFile(Filename, false, LookupFrom, CurDir,
+ Callbacks ? &SearchPath : 0,
+ Callbacks ? &RelativePath : 0,
+ getLangOpts().Modules ? &SuggestedModule : 0);
+ if (File) {
+ SourceRange Range(FilenameTok.getLocation(), CharEnd);
+ Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
+ Filename <<
+ FixItHint::CreateReplacement(Range, "\"" + Filename.str() + "\"");
+ }
+ }
+ // If the file is still not found, just go with the vanilla diagnostic
+ if (!File)
+ Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
+ }
+ if (!File)
+ return;
}
// If we are supposed to import a module rather than including the header,
@@ -1465,7 +1514,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
EnterSourceFile(FID, CurDir, FilenameTok.getLocation());
}
-/// HandleIncludeNextDirective - Implements #include_next.
+/// HandleIncludeNextDirective - Implements \#include_next.
///
void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,
Token &IncludeNextTok) {
@@ -1488,7 +1537,7 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,
return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup);
}
-/// HandleMicrosoftImportDirective - Implements #import for Microsoft Mode
+/// HandleMicrosoftImportDirective - Implements \#import for Microsoft Mode
void Preprocessor::HandleMicrosoftImportDirective(Token &Tok) {
// The Microsoft #import directive takes a type library and generates header
// files from it, and includes those. This is beyond the scope of what clang
@@ -1502,7 +1551,7 @@ void Preprocessor::HandleMicrosoftImportDirective(Token &Tok) {
DiscardUntilEndOfDirective();
}
-/// HandleImportDirective - Implements #import.
+/// HandleImportDirective - Implements \#import.
///
void Preprocessor::HandleImportDirective(SourceLocation HashLoc,
Token &ImportTok) {
@@ -1634,7 +1683,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
}
}
-/// HandleDefineDirective - Implements #define. This consumes the entire macro
+/// HandleDefineDirective - Implements \#define. This consumes the entire macro
/// line then lets the caller lex the next real token.
void Preprocessor::HandleDefineDirective(Token &DefineTok) {
++NumDefined;
@@ -1841,7 +1890,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
Callbacks->MacroDefined(MacroNameTok, MI);
}
-/// HandleUndefDirective - Implements #undef.
+/// HandleUndefDirective - Implements \#undef.
///
void Preprocessor::HandleUndefDirective(Token &UndefTok) {
++NumUndefined;
@@ -1882,10 +1931,10 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) {
// Preprocessor Conditional Directive Handling.
//===----------------------------------------------------------------------===//
-/// HandleIfdefDirective - Implements the #ifdef/#ifndef directive. isIfndef is
-/// true when this is a #ifndef directive. ReadAnyTokensBeforeDirective is true
-/// if any tokens have been returned or pp-directives activated before this
-/// #ifndef has been lexed.
+/// HandleIfdefDirective - Implements the \#ifdef/\#ifndef directive. isIfndef
+/// is true when this is a \#ifndef directive. ReadAnyTokensBeforeDirective is
+/// true if any tokens have been returned or pp-directives activated before this
+/// \#ifndef has been lexed.
///
void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
bool ReadAnyTokensBeforeDirective) {
@@ -1947,7 +1996,7 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
}
}
-/// HandleIfDirective - Implements the #if directive.
+/// HandleIfDirective - Implements the \#if directive.
///
void Preprocessor::HandleIfDirective(Token &IfToken,
bool ReadAnyTokensBeforeDirective) {
@@ -1984,7 +2033,7 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
}
}
-/// HandleEndifDirective - Implements the #endif directive.
+/// HandleEndifDirective - Implements the \#endif directive.
///
void Preprocessor::HandleEndifDirective(Token &EndifToken) {
++NumEndif;
@@ -2010,7 +2059,7 @@ void Preprocessor::HandleEndifDirective(Token &EndifToken) {
Callbacks->Endif(EndifToken.getLocation(), CondInfo.IfLoc);
}
-/// HandleElseDirective - Implements the #else directive.
+/// HandleElseDirective - Implements the \#else directive.
///
void Preprocessor::HandleElseDirective(Token &Result) {
++NumElse;
@@ -2039,7 +2088,7 @@ void Preprocessor::HandleElseDirective(Token &Result) {
/*FoundElse*/true, Result.getLocation());
}
-/// HandleElifDirective - Implements the #elif directive.
+/// HandleElifDirective - Implements the \#elif directive.
///
void Preprocessor::HandleElifDirective(Token &ElifToken) {
++NumElse;
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index b6689df18684..e824320cf732 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -31,7 +31,7 @@ PPCallbacks::~PPCallbacks() {}
//===----------------------------------------------------------------------===//
/// isInPrimaryFile - Return true if we're in the top-level file, not in a
-/// #include. This looks through macro expansions and active _Pragma lexers.
+/// \#include. This looks through macro expansions and active _Pragma lexers.
bool Preprocessor::isInPrimaryFile() const {
if (IsFileLexer())
return IncludeMacroStack.empty();
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index fe7058570efa..ebdb6446d167 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -215,7 +215,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// If this is a function-like macro, read the arguments.
if (MI->isFunctionLike()) {
- // C99 6.10.3p10: If the preprocessing token immediately after the the macro
+ // C99 6.10.3p10: If the preprocessing token immediately after the macro
// name isn't a '(', this macro should not be expanded.
if (!isNextPPTokenLParen())
return true;
@@ -242,9 +242,27 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// Remember where the token is expanded.
SourceLocation ExpandLoc = Identifier.getLocation();
-
- if (Callbacks) Callbacks->MacroExpands(Identifier, MI,
- SourceRange(ExpandLoc, ExpansionEnd));
+ SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
+
+ if (Callbacks) {
+ if (InMacroArgs) {
+ // We can have macro expansion inside a conditional directive while
+ // reading the function macro arguments. To ensure, in that case, that
+ // MacroExpands callbacks still happen in source order, queue this
+ // callback to have it happen after the function macro callback.
+ DelayedMacroExpandsCallbacks.push_back(
+ MacroExpandsInfo(Identifier, MI, ExpansionRange));
+ } else {
+ Callbacks->MacroExpands(Identifier, MI, ExpansionRange);
+ if (!DelayedMacroExpandsCallbacks.empty()) {
+ for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
+ MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
+ Callbacks->MacroExpands(Info.Tok, Info.MI, Info.Range);
+ }
+ DelayedMacroExpandsCallbacks.clear();
+ }
+ }
+ }
// If we started lexing a macro, enter the macro expansion body.
@@ -469,10 +487,12 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
} else if (MI->isVariadic() &&
(NumActuals+1 == MinArgsExpected || // A(x, ...) -> A(X)
(NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A()
- // Varargs where the named vararg parameter is missing: ok as extension.
- // #define A(x, ...)
- // A("blah")
+ // Varargs where the named vararg parameter is missing: OK as extension.
+ // #define A(x, ...)
+ // A("blah")
Diag(Tok, diag::ext_missing_varargs_arg);
+ Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+ << MacroName.getIdentifierInfo();
// Remember this occurred, allowing us to elide the comma when used for
// cases like:
@@ -599,6 +619,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("address_sanitizer", LangOpts.AddressSanitizer)
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_availability", true)
+ .Case("attribute_availability_with_message", true)
.Case("attribute_cf_returns_not_retained", true)
.Case("attribute_cf_returns_retained", true)
.Case("attribute_deprecated_with_message", true)
@@ -612,6 +633,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("attribute_objc_method_family", true)
.Case("attribute_overloadable", true)
.Case("attribute_unavailable_with_message", true)
+ .Case("attribute_unused_on_fields", true)
.Case("blocks", LangOpts.Blocks)
.Case("cxx_exceptions", LangOpts.Exceptions)
.Case("cxx_rtti", LangOpts.RTTI)
@@ -625,15 +647,16 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("objc_fixed_enum", LangOpts.ObjC2)
.Case("objc_instancetype", LangOpts.ObjC2)
.Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
- .Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI)
- .Case("objc_weak_class", LangOpts.ObjCNonFragileABI)
+ .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
+ .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
.Case("ownership_holds", true)
.Case("ownership_returns", true)
.Case("ownership_takes", true)
.Case("objc_bool", true)
- .Case("objc_subscripting", LangOpts.ObjCNonFragileABI)
+ .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
.Case("objc_array_literals", LangOpts.ObjC2)
.Case("objc_dictionary_literals", LangOpts.ObjC2)
+ .Case("objc_boxed_expressions", LangOpts.ObjC2)
.Case("arc_cf_code_audited", true)
// C11 features
.Case("c_alignas", LangOpts.C11)
@@ -772,6 +795,7 @@ static bool HasAttribute(const IdentifierInfo *II) {
if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4)
Name = Name.substr(2, Name.size() - 4);
+ // FIXME: Do we need to handle namespaces here?
return llvm::StringSwitch<bool>(Name)
#include "clang/Lex/AttrSpellings.inc"
.Default(false);
@@ -1030,7 +1054,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
if (Tok.is(tok::l_paren)) {
// Read the identifier
Lex(Tok);
- if (Tok.is(tok::identifier)) {
+ if (Tok.is(tok::identifier) || Tok.is(tok::kw_const)) {
FeatureII = Tok.getIdentifierInfo();
// Read the ')'.
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index e2a192b01f28..c9cc4adf4019 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -100,9 +100,12 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP,
// Preprocessor Pragma Directive Handling.
//===----------------------------------------------------------------------===//
-/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the
+/// HandlePragmaDirective - The "\#pragma" directive has been parsed. Lex the
/// rest of the pragma, passing it to the registered pragma handlers.
void Preprocessor::HandlePragmaDirective(unsigned Introducer) {
+ if (!PragmasEnabled)
+ return;
+
++NumPragma;
// Invoke the first level of pragma handlers which reads the namespace id.
@@ -314,7 +317,7 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
return Lex(Tok);
}
-/// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
+/// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'.
///
void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
if (isInPrimaryFile()) {
@@ -336,7 +339,7 @@ void Preprocessor::HandlePragmaMark() {
}
-/// HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
+/// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'.
///
void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
Token Tok;
@@ -378,7 +381,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
}
}
-/// HandlePragmaSystemHeader - Implement #pragma GCC system_header. We know
+/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header. We know
/// that the whole directive has been parsed.
void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
if (isInPrimaryFile()) {
@@ -411,7 +414,7 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
false, false, true, false);
}
-/// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
+/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
///
void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
Token FilenameTok;
@@ -464,9 +467,12 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
}
}
-/// HandlePragmaComment - Handle the microsoft #pragma comment extension. The
-/// syntax is:
-/// #pragma comment(linker, "foo")
+/// \brief Handle the microsoft \#pragma comment extension.
+///
+/// The syntax is:
+/// \code
+/// \#pragma comment(linker, "foo")
+/// \endcode
/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
/// "foo" is a string, which is fully macro expanded, and permits string
/// concatenation, embedded escape characters etc. See MSDN for more details.
@@ -552,11 +558,15 @@ void Preprocessor::HandlePragmaComment(Token &Tok) {
Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
}
-/// HandlePragmaMessage - Handle the microsoft and gcc #pragma message
+/// HandlePragmaMessage - Handle the microsoft and gcc \#pragma message
/// extension. The syntax is:
-/// #pragma message(string)
+/// \code
+/// \#pragma message(string)
+/// \endcode
/// OR, in GCC mode:
-/// #pragma message string
+/// \code
+/// \#pragma message string
+/// \endcode
/// string 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) {
@@ -679,9 +689,12 @@ IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
return LookUpIdentifierInfo(MacroTok);
}
-/// HandlePragmaPushMacro - Handle #pragma push_macro.
+/// \brief Handle \#pragma push_macro.
+///
/// The syntax is:
-/// #pragma push_macro("macro")
+/// \code
+/// \#pragma push_macro("macro")
+/// \endcode
void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
// Parse the pragma directive and get the macro IdentifierInfo*.
IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
@@ -703,9 +716,12 @@ void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
PragmaPushMacroInfo[IdentInfo].push_back(MacroCopyToPush);
}
-/// HandlePragmaPopMacro - Handle #pragma pop_macro.
+/// \brief Handle \#pragma pop_macro.
+///
/// The syntax is:
+/// \code
/// #pragma pop_macro("macro")
+/// \endcode
void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
SourceLocation MessageLoc = PopMacroTok.getLocation();
@@ -931,7 +947,7 @@ bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
}
namespace {
-/// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
+/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
struct PragmaOnceHandler : public PragmaHandler {
PragmaOnceHandler() : PragmaHandler("once") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -941,7 +957,7 @@ struct PragmaOnceHandler : public PragmaHandler {
}
};
-/// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the
+/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
/// rest of the line is not lexed.
struct PragmaMarkHandler : public PragmaHandler {
PragmaMarkHandler() : PragmaHandler("mark") {}
@@ -951,7 +967,7 @@ struct PragmaMarkHandler : public PragmaHandler {
}
};
-/// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
+/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
struct PragmaPoisonHandler : public PragmaHandler {
PragmaPoisonHandler() : PragmaHandler("poison") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -960,7 +976,7 @@ struct PragmaPoisonHandler : public PragmaHandler {
}
};
-/// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file
+/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
/// as a system header, which silences warnings in it.
struct PragmaSystemHeaderHandler : public PragmaHandler {
PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
@@ -994,6 +1010,10 @@ struct PragmaDebugHandler : public PragmaHandler {
llvm_unreachable("This is an assertion!");
} else if (II->isStr("crash")) {
*(volatile int*) 0x11 = 0;
+ } else if (II->isStr("parser_crash")) {
+ Token Crasher;
+ Crasher.setKind(tok::annot_pragma_parser_crash);
+ PP.EnterToken(Crasher);
} else if (II->isStr("llvm_fatal_error")) {
llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
} else if (II->isStr("llvm_unreachable")) {
@@ -1023,7 +1043,7 @@ struct PragmaDebugHandler : public PragmaHandler {
};
-/// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"'
+/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
struct PragmaDiagnosticHandler : public PragmaHandler {
private:
const char *Namespace;
@@ -1117,7 +1137,7 @@ public:
}
};
-/// PragmaCommentHandler - "#pragma comment ...".
+/// PragmaCommentHandler - "\#pragma comment ...".
struct PragmaCommentHandler : public PragmaHandler {
PragmaCommentHandler() : PragmaHandler("comment") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -1126,7 +1146,7 @@ struct PragmaCommentHandler : public PragmaHandler {
}
};
-/// PragmaIncludeAliasHandler - "#pragma include_alias("...")".
+/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
struct PragmaIncludeAliasHandler : public PragmaHandler {
PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -1135,7 +1155,7 @@ struct PragmaIncludeAliasHandler : public PragmaHandler {
}
};
-/// PragmaMessageHandler - "#pragma message("...")".
+/// PragmaMessageHandler - "\#pragma message("...")".
struct PragmaMessageHandler : public PragmaHandler {
PragmaMessageHandler() : PragmaHandler("message") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -1144,7 +1164,7 @@ struct PragmaMessageHandler : public PragmaHandler {
}
};
-/// PragmaPushMacroHandler - "#pragma push_macro" saves the value of the
+/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
/// macro on the top of the stack.
struct PragmaPushMacroHandler : public PragmaHandler {
PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
@@ -1155,7 +1175,7 @@ struct PragmaPushMacroHandler : public PragmaHandler {
};
-/// PragmaPopMacroHandler - "#pragma pop_macro" sets the value of the
+/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
/// macro to the value on the top of the stack.
struct PragmaPopMacroHandler : public PragmaHandler {
PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
@@ -1167,7 +1187,7 @@ struct PragmaPopMacroHandler : public PragmaHandler {
// Pragma STDC implementations.
-/// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...".
+/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -1180,7 +1200,7 @@ struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
}
};
-/// PragmaSTDC_CX_LIMITED_RANGEHandler - "#pragma STDC CX_LIMITED_RANGE ...".
+/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
PragmaSTDC_CX_LIMITED_RANGEHandler()
: PragmaHandler("CX_LIMITED_RANGE") {}
@@ -1191,7 +1211,7 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
}
};
-/// PragmaSTDC_UnknownHandler - "#pragma STDC ...".
+/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
struct PragmaSTDC_UnknownHandler : public PragmaHandler {
PragmaSTDC_UnknownHandler() {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -1202,7 +1222,7 @@ struct PragmaSTDC_UnknownHandler : public PragmaHandler {
};
/// PragmaARCCFCodeAuditedHandler -
-/// #pragma clang arc_cf_code_audited begin/end
+/// \#pragma clang arc_cf_code_audited begin/end
struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -1259,7 +1279,7 @@ struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
-/// #pragma GCC poison/system_header/dependency and #pragma once.
+/// \#pragma GCC poison/system_header/dependency and \#pragma once.
void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler(new PragmaOnceHandler());
AddPragmaHandler(new PragmaMarkHandler());
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index 89d19fd52adc..dfdeba3f9cd9 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -48,7 +48,7 @@ PreprocessingRecord::PreprocessingRecord(SourceManager &SM,
}
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
-/// that source range \arg R encompasses.
+/// that source range \p Range encompasses.
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
if (Range.isInvalid())
@@ -89,7 +89,7 @@ static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
///
/// Can be used to avoid implicit deserializations of preallocated
/// preprocessed entities if we only care about entities of a specific file
-/// and not from files #included in the range given at
+/// and not from files \#included in the range given at
/// \see getPreprocessedEntitiesInRange.
bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
if (FID.isInvalid())
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 06e5685a8b67..614530cf387f 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -66,54 +66,6 @@ Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
Record(0), MIChainHead(0), MICache(0)
{
OwnsHeaderSearch = OwnsHeaders;
-
- if (!DelayInitialization) {
- assert(Target && "Must provide target information for PP initialization");
- Initialize(*Target);
- }
-}
-
-Preprocessor::~Preprocessor() {
- assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
-
- while (!IncludeMacroStack.empty()) {
- delete IncludeMacroStack.back().TheLexer;
- delete IncludeMacroStack.back().TheTokenLexer;
- IncludeMacroStack.pop_back();
- }
-
- // Free any macro definitions.
- for (MacroInfoChain *I = MIChainHead ; I ; I = I->Next)
- I->MI.Destroy();
-
- // Free any cached macro expanders.
- for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
- delete TokenLexerCache[i];
-
- // Free any cached MacroArgs.
- for (MacroArgs *ArgList = MacroArgCache; ArgList; )
- ArgList = ArgList->deallocate();
-
- // Release pragma information.
- delete PragmaHandlers;
-
- // Delete the scratch buffer info.
- delete ScratchBuf;
-
- // Delete the header search info, if we own it.
- if (OwnsHeaderSearch)
- delete &HeaderInfo;
-
- delete Callbacks;
-}
-
-void Preprocessor::Initialize(const TargetInfo &Target) {
- assert((!this->Target || this->Target == &Target) &&
- "Invalid override of target information");
- this->Target = &Target;
-
- // Initialize information about built-ins.
- BuiltinInfo.InitializeTarget(Target);
ScratchBuf = new ScratchBuffer(SourceMgr);
CounterValue = 0; // __COUNTER__ starts at 0.
@@ -134,10 +86,12 @@ void Preprocessor::Initialize(const TargetInfo &Target) {
// Macro expansion is enabled.
DisableMacroExpansion = false;
+ MacroExpansionInDirectivesOverride = false;
InMacroArgs = false;
InMacroArgPreExpansion = false;
NumCachedTokenLexers = 0;
-
+ PragmasEnabled = true;
+
CachedLexPos = 0;
// We haven't read anything from the external source.
@@ -170,7 +124,54 @@ void Preprocessor::Initialize(const TargetInfo &Target) {
Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0;
Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0;
}
+
+ if (!DelayInitialization) {
+ assert(Target && "Must provide target information for PP initialization");
+ Initialize(*Target);
+ }
+}
+
+Preprocessor::~Preprocessor() {
+ assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
+
+ while (!IncludeMacroStack.empty()) {
+ delete IncludeMacroStack.back().TheLexer;
+ delete IncludeMacroStack.back().TheTokenLexer;
+ IncludeMacroStack.pop_back();
+ }
+
+ // Free any macro definitions.
+ for (MacroInfoChain *I = MIChainHead ; I ; I = I->Next)
+ I->MI.Destroy();
+
+ // Free any cached macro expanders.
+ for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
+ delete TokenLexerCache[i];
+
+ // Free any cached MacroArgs.
+ for (MacroArgs *ArgList = MacroArgCache; ArgList; )
+ ArgList = ArgList->deallocate();
+
+ // Release pragma information.
+ delete PragmaHandlers;
+
+ // Delete the scratch buffer info.
+ delete ScratchBuf;
+
+ // Delete the header search info, if we own it.
+ if (OwnsHeaderSearch)
+ delete &HeaderInfo;
+
+ delete Callbacks;
+}
+
+void Preprocessor::Initialize(const TargetInfo &Target) {
+ assert((!this->Target || this->Target == &Target) &&
+ "Invalid override of target information");
+ this->Target = &Target;
+ // Initialize information about built-ins.
+ BuiltinInfo.InitializeTarget(Target);
HeaderInfo.setTarget(Target);
}
@@ -236,6 +237,20 @@ void Preprocessor::PrintStats() {
llvm::errs() << (NumFastTokenPaste+NumTokenPaste)
<< " token paste (##) operations performed, "
<< NumFastTokenPaste << " on the fast path.\n";
+
+ llvm::errs() << "\nPreprocessor Memory: " << getTotalMemory() << "B total";
+
+ llvm::errs() << "\n BumpPtr: " << BP.getTotalMemory();
+ llvm::errs() << "\n Macro Expanded Tokens: "
+ << llvm::capacity_in_bytes(MacroExpandedTokens);
+ llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity();
+ llvm::errs() << "\n Macros: " << llvm::capacity_in_bytes(Macros);
+ llvm::errs() << "\n #pragma push_macro Info: "
+ << llvm::capacity_in_bytes(PragmaPushMacroInfo);
+ llvm::errs() << "\n Poison Reasons: "
+ << llvm::capacity_in_bytes(PoisonReasons);
+ llvm::errs() << "\n Comment Handlers: "
+ << llvm::capacity_in_bytes(CommentHandlers) << "\n";
}
Preprocessor::macro_iterator
@@ -514,9 +529,19 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
// If the information about this identifier is out of date, update it from
// the external source.
+ // We have to treat __VA_ARGS__ in a special way, since it gets
+ // serialized with isPoisoned = true, but our preprocessor may have
+ // unpoisoned it if we're defining a C99 macro.
if (II.isOutOfDate()) {
+ bool CurrentIsPoisoned = false;
+ if (&II == Ident__VA_ARGS__)
+ CurrentIsPoisoned = Ident__VA_ARGS__->isPoisoned();
+
ExternalSource->updateOutOfDateIdentifier(II);
Identifier.setKind(II.getTokenID());
+
+ if (&II == Ident__VA_ARGS__)
+ II.setIsPoisoned(CurrentIsPoisoned);
}
// If this identifier was poisoned, and if it was not produced from a macro
@@ -622,14 +647,14 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
/*IsIncludeDirective=*/false);
}
-void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
+void Preprocessor::addCommentHandler(CommentHandler *Handler) {
assert(Handler && "NULL comment handler");
assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) ==
CommentHandlers.end() && "Comment handler already registered");
CommentHandlers.push_back(Handler);
}
-void Preprocessor::RemoveCommentHandler(CommentHandler *Handler) {
+void Preprocessor::removeCommentHandler(CommentHandler *Handler) {
std::vector<CommentHandler *>::iterator Pos
= std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
assert(Pos != CommentHandlers.end() && "Comment handler not registered");
diff --git a/lib/Lex/PreprocessorLexer.cpp b/lib/Lex/PreprocessorLexer.cpp
index a72bbca6bcff..a64c84d6bbd3 100644
--- a/lib/Lex/PreprocessorLexer.cpp
+++ b/lib/Lex/PreprocessorLexer.cpp
@@ -27,7 +27,7 @@ PreprocessorLexer::PreprocessorLexer(Preprocessor *pp, FileID fid)
InitialNumSLocEntries = pp->getSourceManager().local_sloc_entry_size();
}
-/// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
+/// \brief After the preprocessor has parsed a \#include, lex and
/// (potentially) macro expand the filename.
void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
assert(ParsingPreprocessorDirective &&
diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp
index 84a46ed3779b..dd7ebb0ce337 100644
--- a/lib/Lex/TokenConcatenation.cpp
+++ b/lib/Lex/TokenConcatenation.cpp
@@ -14,6 +14,7 @@
#include "clang/Lex/TokenConcatenation.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/ErrorHandling.h"
+#include <cctype>
using namespace clang;
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 696754c74167..ade40dad77d9 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -252,9 +252,9 @@ void TokenLexer::ExpandFunctionArguments() {
const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
unsigned NumToks = MacroArgs::getArgLength(ArgToks);
if (NumToks) { // Not an empty argument?
- // If this is the GNU ", ## __VA_ARG__" extension, and we just learned
- // that __VA_ARG__ expands to multiple tokens, avoid a pasting error when
- // the expander trys to paste ',' with the first token of the __VA_ARG__
+ // If this is the GNU ", ## __VA_ARGS__" extension, and we just learned
+ // that __VA_ARGS__ expands to multiple tokens, avoid a pasting error when
+ // the expander trys to paste ',' with the first token of the __VA_ARGS__
// expansion.
if (PasteBefore && ResultToks.size() >= 2 &&
ResultToks[ResultToks.size()-2].is(tok::comma) &&
@@ -568,8 +568,8 @@ bool TokenLexer::PasteTokens(Token &Tok) {
<< Buffer.str();
}
- // Do not consume the RHS.
- --CurToken;
+ // An error has occurred so exit loop.
+ break;
}
// Turn ## into 'unknown' to avoid # ## # from looking like a paste
@@ -578,7 +578,7 @@ bool TokenLexer::PasteTokens(Token &Tok) {
Result.setKind(tok::unknown);
}
- // Transfer properties of the LHS over the the Result.
+ // Transfer properties of the LHS over the Result.
Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());
Result.setFlagValue(Token::LeadingSpace, Tok.hasLeadingSpace());