diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp | 42 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Lexer.cpp | 91 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp | 154 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp | 183 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp | 46 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp | 6 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Pragma.cpp | 78 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp | 127 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PreprocessorLexer.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp | 12 |
13 files changed, 464 insertions, 284 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp index d688e23..bb3a673 100644 --- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp index 535a852..5212dd8 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp index c1d228b..9e3c778 100644 --- a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp index 625a204..74b9cbc 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp index b6689df..e824320 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index fe70585..ebdb644 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp index f104f96..67738e9 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp @@ -452,14 +452,14 @@ PTHManager *PTHManager::Create(const std::string &file, const unsigned char *BufEnd = (unsigned char*)File->getBufferEnd(); // Check the prologue of the file. - if ((BufEnd - BufBeg) < (signed)(sizeof("cfe-pth") + 3 + 4) || - memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) { + if ((BufEnd - BufBeg) < (signed)(sizeof("cfe-pth") + 4 + 4) || + memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth")) != 0) { Diags.Report(diag::err_invalid_pth_file) << file; return 0; } // Read the PTH version. - const unsigned char *p = BufBeg + (sizeof("cfe-pth") - 1); + const unsigned char *p = BufBeg + (sizeof("cfe-pth")); unsigned Version = ReadLE32(p); if (Version < PTHManager::Version) { diff --git a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp index e2a192b..c9cc4ad 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp b/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp index 89d19fd..dfdeba3 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp index 06e5685..614530c 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/PreprocessorLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/PreprocessorLexer.cpp index a72bbca..a64c84d 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PreprocessorLexer.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp b/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp index 84a46ed..dd7ebb0 100644 --- a/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp +++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp index 696754c..ade40da 100644 --- a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp +++ b/contrib/llvm/tools/clang/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()); |