From c0c7bca4e5b8d12699dc93a0da49e9e4bb79671b Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Sun, 21 Mar 2010 10:50:08 +0000 Subject: Update clang to r99115. --- lib/Lex/CMakeLists.txt | 1 + lib/Lex/Lexer.cpp | 6 +- lib/Lex/MacroArgs.cpp | 31 ++++++---- lib/Lex/PPDirectives.cpp | 28 +++++++-- lib/Lex/PPLexerChange.cpp | 6 +- lib/Lex/PPMacroExpansion.cpp | 8 ++- lib/Lex/Pragma.cpp | 5 +- lib/Lex/PreprocessingRecord.cpp | 128 ++++++++++++++++++++++++++++++++++++++++ lib/Lex/Preprocessor.cpp | 30 ++++++---- lib/Lex/TokenLexer.cpp | 11 +++- 10 files changed, 217 insertions(+), 37 deletions(-) create mode 100644 lib/Lex/PreprocessingRecord.cpp (limited to 'lib/Lex') diff --git a/lib/Lex/CMakeLists.txt b/lib/Lex/CMakeLists.txt index 81a1e01f964d..632fbc6340cc 100644 --- a/lib/Lex/CMakeLists.txt +++ b/lib/Lex/CMakeLists.txt @@ -16,6 +16,7 @@ add_clang_library(clangLex PPMacroExpansion.cpp PTHLexer.cpp Pragma.cpp + PreprocessingRecord.cpp Preprocessor.cpp PreprocessorLexer.cpp ScratchBuffer.cpp diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 6cdb96f37de4..2f89142409a0 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1036,7 +1036,11 @@ bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) { // If this BCPL-style comment is in a macro definition, transmogrify it into // a C-style block comment. - std::string Spelling = PP->getSpelling(Result); + bool Invalid = false; + std::string Spelling = PP->getSpelling(Result, &Invalid); + if (Invalid) + return true; + assert(Spelling[0] == '/' && Spelling[1] == '/' && "Not bcpl comment?"); Spelling[1] = '*'; // Change prefix to "/*". Spelling += "*/"; // add suffix. diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp index 2f1a34c83297..89f6368a277f 100644 --- a/lib/Lex/MacroArgs.cpp +++ b/lib/Lex/MacroArgs.cpp @@ -208,24 +208,31 @@ Token MacroArgs::StringifyArgument(const Token *ArgToks, if (Tok.is(tok::string_literal) || // "foo" Tok.is(tok::wide_string_literal) || // L"foo" Tok.is(tok::char_constant)) { // 'x' and L'x'. - std::string Str = Lexer::Stringify(PP.getSpelling(Tok)); - Result.append(Str.begin(), Str.end()); + bool Invalid = false; + std::string TokStr = PP.getSpelling(Tok, &Invalid); + if (!Invalid) { + std::string Str = Lexer::Stringify(TokStr); + Result.append(Str.begin(), Str.end()); + } } else { // Otherwise, just append the token. Do some gymnastics to get the token // in place and avoid copies where possible. unsigned CurStrLen = Result.size(); Result.resize(CurStrLen+Tok.getLength()); const char *BufPtr = &Result[CurStrLen]; - unsigned ActualTokLen = PP.getSpelling(Tok, BufPtr); - - // If getSpelling returned a pointer to an already uniqued version of the - // string instead of filling in BufPtr, memcpy it onto our string. - if (BufPtr != &Result[CurStrLen]) - memcpy(&Result[CurStrLen], BufPtr, ActualTokLen); - - // If the token was dirty, the spelling may be shorter than the token. - if (ActualTokLen != Tok.getLength()) - Result.resize(CurStrLen+ActualTokLen); + bool Invalid = false; + unsigned ActualTokLen = PP.getSpelling(Tok, BufPtr, &Invalid); + + if (!Invalid) { + // If getSpelling returned a pointer to an already uniqued version of + // the string instead of filling in BufPtr, memcpy it onto our string. + if (BufPtr != &Result[CurStrLen]) + memcpy(&Result[CurStrLen], BufPtr, ActualTokLen); + + // If the token was dirty, the spelling may be shorter than the token. + if (ActualTokLen != Tok.getLength()) + Result.resize(CurStrLen+ActualTokLen); + } } } diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index cddc6cff727a..7b601010b20d 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -71,7 +71,11 @@ void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) { IdentifierInfo *II = MacroNameTok.getIdentifierInfo(); if (II == 0) { - std::string Spelling = getSpelling(MacroNameTok); + bool Invalid = false; + std::string Spelling = getSpelling(MacroNameTok, &Invalid); + if (Invalid) + return; + const IdentifierInfo &Info = Identifiers.get(Spelling); if (Info.isCPlusPlusOperatorKeyword()) // C++ 2.5p2: Alternative tokens behave the same as its primary token @@ -204,7 +208,12 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, // to spell an i/e in a strange way that is another letter. Skipping this // allows us to avoid looking up the identifier info for #define/#undef and // other common directives. - const char *RawCharData = SourceMgr.getCharacterData(Tok.getLocation()); + bool Invalid = false; + const char *RawCharData = SourceMgr.getCharacterData(Tok.getLocation(), + &Invalid); + if (Invalid) + return; + char FirstChar = RawCharData[0]; if (FirstChar >= 'a' && FirstChar <= 'z' && FirstChar != 'i' && FirstChar != 'e') { @@ -614,8 +623,11 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val, llvm::SmallString<64> IntegerBuffer; IntegerBuffer.resize(DigitTok.getLength()); const char *DigitTokBegin = &IntegerBuffer[0]; - unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin); - + bool Invalid = false; + unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin, &Invalid); + if (Invalid) + return true; + // Verify that we have a simple digit-sequence, and compute the value. This // is always a simple digit string computed in decimal, so we do this manually // here. @@ -900,8 +912,12 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) { // Verify that there is nothing after the string, other than EOM. CheckEndOfDirective("ident"); - if (Callbacks) - Callbacks->Ident(Tok.getLocation(), getSpelling(StrTok)); + if (Callbacks) { + bool Invalid = false; + std::string Str = getSpelling(StrTok, &Invalid); + if (!Invalid) + Callbacks->Ident(Tok.getLocation(), Str); + } } //===----------------------------------------------------------------------===// diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index 81e6bf809025..6d1c132fc0a9 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -80,8 +80,10 @@ bool Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir, } // Get the MemoryBuffer for this FID, if it fails, we fail. - const llvm::MemoryBuffer *InputFile = getSourceManager().getBuffer(FID); - if (!InputFile) + bool Invalid = false; + const llvm::MemoryBuffer *InputFile = getSourceManager().getBuffer(FID, + &Invalid); + if (Invalid) return true; EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir); diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 5fe2ef172e2f..ffae8ab6afb1 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -542,9 +542,13 @@ static bool EvaluateHasIncludeCommon(bool &Result, Token &Tok, return false; case tok::angle_string_literal: - case tok::string_literal: - Filename = PP.getSpelling(Tok, FilenameBuffer); + case tok::string_literal: { + bool Invalid = false; + Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid); + if (Invalid) + return false; break; + } case tok::less: // This could be a file coming from a macro expansion. In this diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 654d4606a959..92332a006861 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -287,7 +287,10 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) { // Reserve a buffer to get the spelling. llvm::SmallString<128> FilenameBuffer; - llvm::StringRef Filename = getSpelling(FilenameTok, FilenameBuffer); + bool Invalid = false; + llvm::StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid); + if (Invalid) + return; bool isAngled = GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename); diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp new file mode 100644 index 000000000000..6966c38b23d8 --- /dev/null +++ b/lib/Lex/PreprocessingRecord.cpp @@ -0,0 +1,128 @@ +//===--- PreprocessingRecord.cpp - Record of Preprocessing ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the PreprocessingRecord class, which maintains a record +// of what occurred during preprocessing, and its helpers. +// +//===----------------------------------------------------------------------===// +#include "clang/Lex/PreprocessingRecord.h" +#include "clang/Lex/MacroInfo.h" +#include "clang/Lex/Token.h" + +using namespace clang; + +ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { } + +void PreprocessingRecord::MaybeLoadPreallocatedEntities() const { + if (!ExternalSource || LoadedPreallocatedEntities) + return; + + LoadedPreallocatedEntities = true; + ExternalSource->ReadPreprocessedEntities(); +} + +PreprocessingRecord::PreprocessingRecord() + : ExternalSource(0), NumPreallocatedEntities(0), + LoadedPreallocatedEntities(false) +{ +} + +PreprocessingRecord::iterator +PreprocessingRecord::begin(bool OnlyLocalEntities) { + if (OnlyLocalEntities) + return PreprocessedEntities.begin() + NumPreallocatedEntities; + + MaybeLoadPreallocatedEntities(); + return PreprocessedEntities.begin(); +} + +PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) { + if (!OnlyLocalEntities) + MaybeLoadPreallocatedEntities(); + + return PreprocessedEntities.end(); +} + +PreprocessingRecord::const_iterator +PreprocessingRecord::begin(bool OnlyLocalEntities) const { + if (OnlyLocalEntities) + return PreprocessedEntities.begin() + NumPreallocatedEntities; + + MaybeLoadPreallocatedEntities(); + return PreprocessedEntities.begin(); +} + +PreprocessingRecord::const_iterator +PreprocessingRecord::end(bool OnlyLocalEntities) const { + if (!OnlyLocalEntities) + MaybeLoadPreallocatedEntities(); + + return PreprocessedEntities.end(); +} + +void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) { + PreprocessedEntities.push_back(Entity); +} + +void PreprocessingRecord::SetExternalSource( + ExternalPreprocessingRecordSource &Source, + unsigned NumPreallocatedEntities) { + assert(!ExternalSource && + "Preprocessing record already has an external source"); + ExternalSource = &Source; + this->NumPreallocatedEntities = NumPreallocatedEntities; + PreprocessedEntities.insert(PreprocessedEntities.begin(), + NumPreallocatedEntities, 0); +} + +void PreprocessingRecord::SetPreallocatedEntity(unsigned Index, + PreprocessedEntity *Entity) { + assert(Index < NumPreallocatedEntities &&"Out-of-bounds preallocated entity"); + PreprocessedEntities[Index] = Entity; +} + +void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro, + MacroDefinition *MD) { + MacroDefinitions[Macro] = MD; +} + +MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) { + llvm::DenseMap::iterator Pos + = MacroDefinitions.find(MI); + if (Pos == MacroDefinitions.end()) + return 0; + + return Pos->second; +} + +void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI) { + if (MacroDefinition *Def = findMacroDefinition(MI)) + PreprocessedEntities.push_back( + new (*this) MacroInstantiation(Id.getIdentifierInfo(), + Id.getLocation(), + Def)); +} + +void PreprocessingRecord::MacroDefined(const IdentifierInfo *II, + const MacroInfo *MI) { + SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); + MacroDefinition *Def + = new (*this) MacroDefinition(II, MI->getDefinitionLoc(), R); + MacroDefinitions[MI] = Def; + PreprocessedEntities.push_back(Def); +} + +void PreprocessingRecord::MacroUndefined(const IdentifierInfo *II, + const MacroInfo *MI) { + llvm::DenseMap::iterator Pos + = MacroDefinitions.find(MI); + if (Pos != MacroDefinitions.end()) + MacroDefinitions.erase(Pos); +} + diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 5584b18da15f..9d59300d213e 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -31,6 +31,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Pragma.h" +#include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/ScratchBuffer.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Basic/SourceManager.h" @@ -53,7 +54,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()), SourceMgr(SM), HeaderInfo(Headers), ExternalSource(0), Identifiers(opts, IILookup), BuiltinInfo(Target), CodeCompletionFile(0), - CurPPLexer(0), CurDirLookup(0), Callbacks(0), MacroArgCache(0) { + CurPPLexer(0), CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0) { ScratchBuf = new ScratchBuffer(SourceMgr); CounterValue = 0; // __COUNTER__ starts at 0. OwnsHeaderSearch = OwnsHeaders; @@ -232,8 +233,9 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, return false; // Load the actual file's contents. - const MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File); - if (!Buffer) + bool Invalid = false; + const MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File, &Invalid); + if (Invalid) return true; // Find the byte position of the truncation point. @@ -427,10 +429,11 @@ SourceLocation Preprocessor::AdvanceToTokenCharacter(SourceLocation TokStart, // Figure out how many physical characters away the specified instantiation // character is. This needs to take into consideration newlines and // trigraphs. - const char *TokPtr = SourceMgr.getCharacterData(TokStart); + bool Invalid = false; + const char *TokPtr = SourceMgr.getCharacterData(TokStart, &Invalid); // If they request the first char of the token, we're trivially done. - if (CharNo == 0 && Lexer::isObviouslySimpleCharacter(*TokPtr)) + if (Invalid || (CharNo == 0 && Lexer::isObviouslySimpleCharacter(*TokPtr))) return TokStart; unsigned PhysOffset = 0; @@ -486,7 +489,7 @@ SourceLocation Preprocessor::getLocForEndOfToken(SourceLocation Loc, /// EnterMainSourceFile - Enter the specified FileID as the main source file, /// which implicitly adds the builtin defines etc. -void Preprocessor::EnterMainSourceFile() { +bool Preprocessor::EnterMainSourceFile() { // We do not allow the preprocessor to reenter the main file. Doing so will // cause FileID's to accumulate information from both runs (e.g. #line // information) and predefined macros aren't guaranteed to be set properly. @@ -495,8 +498,8 @@ void Preprocessor::EnterMainSourceFile() { // Enter the main file source buffer. std::string ErrorStr; - bool Res = EnterSourceFile(MainFileID, 0, ErrorStr); - assert(!Res && "Entering main file should not fail!"); + if (EnterSourceFile(MainFileID, 0, ErrorStr)) + return true; // Tell the header info that the main file was entered. If the file is later // #imported, it won't be re-entered. @@ -513,8 +516,7 @@ void Preprocessor::EnterMainSourceFile() { assert(!FID.isInvalid() && "Could not create FileID for predefines?"); // Start parsing the predefines. - Res = EnterSourceFile(FID, 0, ErrorStr); - assert(!Res && "Entering predefines should not fail!"); + return EnterSourceFile(FID, 0, ErrorStr); } @@ -626,3 +628,11 @@ bool Preprocessor::HandleComment(Token &result, SourceRange Comment) { } CommentHandler::~CommentHandler() { } + +void Preprocessor::createPreprocessingRecord() { + if (Record) + return; + + Record = new PreprocessingRecord; + addPPCallbacks(Record); +} diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp index dbd1b8400de3..56bb073e5919 100644 --- a/lib/Lex/TokenLexer.cpp +++ b/lib/Lex/TokenLexer.cpp @@ -396,12 +396,17 @@ bool TokenLexer::PasteTokens(Token &Tok) { // Get the spelling of the LHS token in Buffer. const char *BufPtr = &Buffer[0]; - unsigned LHSLen = PP.getSpelling(Tok, BufPtr); + bool Invalid = false; + unsigned LHSLen = PP.getSpelling(Tok, BufPtr, &Invalid); if (BufPtr != &Buffer[0]) // Really, we want the chars in Buffer! memcpy(&Buffer[0], BufPtr, LHSLen); - + if (Invalid) + return true; + BufPtr = &Buffer[LHSLen]; - unsigned RHSLen = PP.getSpelling(RHS, BufPtr); + unsigned RHSLen = PP.getSpelling(RHS, BufPtr, &Invalid); + if (Invalid) + return true; if (BufPtr != &Buffer[LHSLen]) // Really, we want the chars in Buffer! memcpy(&Buffer[LHSLen], BufPtr, RHSLen); -- cgit v1.2.3