diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
commit | 36981b17ed939300f6f8fc2355a255f711fcef71 (patch) | |
tree | ee2483e98b09cac943dc93a6969d83ca737ff139 /lib/Lex/Preprocessor.cpp | |
parent | 180abc3db9ae3b4fc63cd65b15697e6ffcc8a657 (diff) | |
download | src-36981b17ed939300f6f8fc2355a255f711fcef71.tar.gz src-36981b17ed939300f6f8fc2355a255f711fcef71.zip |
Vendor import of clang release_30 branch r142614:vendor/clang/clang-r142614
Notes
Notes:
svn path=/vendor/clang/dist/; revision=226586
svn path=/vendor/clang/clang-r142614/; revision=226587; tag=vendor/clang/clang-r142614
Diffstat (limited to 'lib/Lex/Preprocessor.cpp')
-rw-r--r-- | lib/Lex/Preprocessor.cpp | 268 |
1 files changed, 173 insertions, 95 deletions
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index e7aa286a16bf..31662ad0c116 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -35,6 +35,7 @@ #include "clang/Lex/ScratchBuffer.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/CodeCompletionHandler.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/TargetInfo.h" @@ -42,27 +43,83 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Capacity.h" using namespace clang; //===----------------------------------------------------------------------===// ExternalPreprocessorSource::~ExternalPreprocessorSource() { } -Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, - const TargetInfo &target, SourceManager &SM, - HeaderSearch &Headers, +Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts, + const TargetInfo *target, SourceManager &SM, + HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup* IILookup, - bool OwnsHeaders) + bool OwnsHeaders, + bool DelayInitialization) : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()), - SourceMgr(SM), - HeaderInfo(Headers), ExternalSource(0), - Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0), - CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), - CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0), - MICache(0) { - ScratchBuf = new ScratchBuffer(SourceMgr); - CounterValue = 0; // __COUNTER__ starts at 0. + SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), + ExternalSource(0), + Identifiers(opts, IILookup), CodeComplete(0), + CodeCompletionFile(0), CodeCompletionOffset(0), CodeCompletionReached(0), + SkipMainFilePreamble(0, true), CurPPLexer(0), + CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0), MacroArgCache(0), + 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!"); + assert(((MacroExpandingLexersStack.empty() && MacroExpandedTokens.empty()) || + isCodeCompletionReached()) && + "Preprocessor::HandleEndOfTokenLexer should have cleared those"); + + 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. + // Clear stats. NumDirectives = NumDefined = NumUndefined = NumPragma = 0; NumIf = NumElse = NumEndif = 0; @@ -71,33 +128,35 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, NumFastMacroExpanded = NumTokenPaste = NumFastTokenPaste = 0; MaxIncludeStackDepth = 0; NumSkipped = 0; - + // Default to discarding comments. KeepComments = false; KeepMacroComments = false; - + SuppressIncludeNotFoundError = false; + AutoModuleImport = false; + // Macro expansion is enabled. DisableMacroExpansion = false; InMacroArgs = false; NumCachedTokenLexers = 0; - + CachedLexPos = 0; - + // We haven't read anything from the external source. ReadMacrosFromExternalSource = false; - + // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro. // This gets unpoisoned where it is allowed. (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned(); SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use); - + // Initialize the pragma handlers. - PragmaHandlers = new PragmaNamespace(llvm::StringRef()); + PragmaHandlers = new PragmaNamespace(StringRef()); RegisterBuiltinPragmas(); - + // Initialize builtin macros like __LINE__ and friends. RegisterBuiltinMacros(); - + if(Features.Borland) { Ident__exception_info = getIdentifierInfo("_exception_info"); Ident___exception_info = getIdentifierInfo("__exception_info"); @@ -112,44 +171,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, Ident__exception_info = Ident__exception_code = Ident__abnormal_termination = 0; Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0; Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0; - } - -} - -Preprocessor::~Preprocessor() { - assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); - assert(MacroExpandingLexersStack.empty() && MacroExpandedTokens.empty() && - "Preprocessor::HandleEndOfTokenLexer should have cleared those"); - - 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::setPTHManager(PTHManager* pm) { @@ -172,7 +194,7 @@ void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const { llvm::errs() << " [ExpandDisabled]"; if (Tok.needsCleaning()) { const char *Start = SourceMgr.getCharacterData(Tok.getLocation()); - llvm::errs() << " [UnClean='" << llvm::StringRef(Start, Tok.getLength()) + llvm::errs() << " [UnClean='" << StringRef(Start, Tok.getLength()) << "']"; } @@ -228,7 +250,13 @@ Preprocessor::macro_begin(bool IncludeExternalMacros) const { } size_t Preprocessor::getTotalMemory() const { - return BP.getTotalMemory() + MacroExpandedTokens.capacity()*sizeof(Token); + return BP.getTotalMemory() + + llvm::capacity_in_bytes(MacroExpandedTokens) + + Predefines.capacity() /* Predefines buffer. */ + + llvm::capacity_in_bytes(Macros) + + llvm::capacity_in_bytes(PragmaPushMacroInfo) + + llvm::capacity_in_bytes(PoisonReasons) + + llvm::capacity_in_bytes(CommentHandlers); } Preprocessor::macro_iterator @@ -243,15 +271,13 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const { } bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, - unsigned TruncateAtLine, - unsigned TruncateAtColumn) { - using llvm::MemoryBuffer; - - CodeCompletionFile = File; + unsigned CompleteLine, + unsigned CompleteColumn) { + assert(File); + assert(CompleteLine && CompleteColumn && "Starts from 1:1"); + assert(!CodeCompletionFile && "Already set"); - // Okay to clear out the code-completion point by passing NULL. - if (!CodeCompletionFile) - return false; + using llvm::MemoryBuffer; // Load the actual file's contents. bool Invalid = false; @@ -261,7 +287,7 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, // Find the byte position of the truncation point. const char *Position = Buffer->getBufferStart(); - for (unsigned Line = 1; Line < TruncateAtLine; ++Line) { + for (unsigned Line = 1; Line < CompleteLine; ++Line) { for (; *Position; ++Position) { if (*Position != '\r' && *Position != '\n') continue; @@ -275,38 +301,37 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, } } - Position += TruncateAtColumn - 1; + Position += CompleteColumn - 1; - // Truncate the buffer. + // Insert '\0' at the code-completion point. if (Position < Buffer->getBufferEnd()) { - llvm::StringRef Data(Buffer->getBufferStart(), - Position-Buffer->getBufferStart()); - MemoryBuffer *TruncatedBuffer - = MemoryBuffer::getMemBufferCopy(Data, Buffer->getBufferIdentifier()); - SourceMgr.overrideFileContents(File, TruncatedBuffer); + CodeCompletionFile = File; + CodeCompletionOffset = Position - Buffer->getBufferStart(); + + MemoryBuffer *NewBuffer = + MemoryBuffer::getNewUninitMemBuffer(Buffer->getBufferSize() + 1, + Buffer->getBufferIdentifier()); + char *NewBuf = const_cast<char*>(NewBuffer->getBufferStart()); + char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); + *NewPos = '\0'; + std::copy(Position, Buffer->getBufferEnd(), NewPos+1); + SourceMgr.overrideFileContents(File, NewBuffer); } return false; } -bool Preprocessor::isCodeCompletionFile(SourceLocation FileLoc) const { - return CodeCompletionFile && FileLoc.isFileID() && - SourceMgr.getFileEntryForID(SourceMgr.getFileID(FileLoc)) - == CodeCompletionFile; -} - void Preprocessor::CodeCompleteNaturalLanguage() { - SetCodeCompletionPoint(0, 0, 0); - getDiagnostics().setSuppressAllDiagnostics(true); if (CodeComplete) CodeComplete->CodeCompleteNaturalLanguage(); + setCodeCompletionReached(); } /// getSpelling - This method is used to get the spelling of a token into a /// SmallVector. Note that the returned StringRef may not point to the /// supplied buffer if a copy can be avoided. -llvm::StringRef Preprocessor::getSpelling(const Token &Tok, - llvm::SmallVectorImpl<char> &Buffer, +StringRef Preprocessor::getSpelling(const Token &Tok, + SmallVectorImpl<char> &Buffer, bool *Invalid) const { // NOTE: this has to be checked *before* testing for an IdentifierInfo. if (Tok.isNot(tok::raw_identifier)) { @@ -321,22 +346,23 @@ llvm::StringRef Preprocessor::getSpelling(const Token &Tok, const char *Ptr = Buffer.data(); unsigned Len = getSpelling(Tok, Ptr, Invalid); - return llvm::StringRef(Ptr, Len); + return StringRef(Ptr, Len); } /// CreateString - Plop the specified string into a scratch buffer and return a /// location for it. If specified, the source location provides a source /// location for the token. void Preprocessor::CreateString(const char *Buf, unsigned Len, Token &Tok, - SourceLocation ExpansionLoc) { + SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd) { Tok.setLength(Len); const char *DestPtr; SourceLocation Loc = ScratchBuf->getToken(Buf, Len, DestPtr); - if (ExpansionLoc.isValid()) - Loc = SourceMgr.createInstantiationLoc(Loc, ExpansionLoc, - ExpansionLoc, Len); + if (ExpansionLocStart.isValid()) + Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLocStart, + ExpansionLocEnd, Len); Tok.setLocation(Loc); // If this is a raw identifier or a literal token, set the pointer data. @@ -407,12 +433,12 @@ IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier) const { IdentifierInfo *II; if (!Identifier.needsCleaning()) { // No cleaning needed, just use the characters from the lexed buffer. - II = getIdentifierInfo(llvm::StringRef(Identifier.getRawIdentifierData(), + II = getIdentifierInfo(StringRef(Identifier.getRawIdentifierData(), Identifier.getLength())); } else { // Cleaning needed, alloca a buffer, clean into it, then use the buffer. llvm::SmallString<64> IdentifierBuffer; - llvm::StringRef CleanedStr = getSpelling(Identifier, IdentifierBuffer); + StringRef CleanedStr = getSpelling(Identifier, IdentifierBuffer); II = getIdentifierInfo(CleanedStr); } @@ -487,6 +513,17 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { } } + // If this identifier is a keyword in C++11, produce a warning. Don't warn if + // we're not considering macro expansion, since this identifier might be the + // name of a macro. + // FIXME: This warning is disabled in cases where it shouldn't be, like + // "#define constexpr constexpr", "int constexpr;" + if (II.isCXX11CompatKeyword() & !DisableMacroExpansion) { + Diag(Identifier, diag::warn_cxx11_keyword) << II.getName(); + // Don't diagnose this keyword again in this translation unit. + II.setIsCXX11CompatKeyword(false); + } + // C++ 2.11p2: If this is an alternative representation of a C++ operator, // then we act as if it is the actual operator and not the textual // representation of it. @@ -499,6 +536,44 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { // like "#define TY typeof", "TY(1) x". if (II.isExtensionToken() && !DisableMacroExpansion) Diag(Identifier, diag::ext_token_used); + + // If this is the '__import_module__' keyword, note that the next token + // indicates a module name. + if (II.getTokenID() == tok::kw___import_module__ && + !InMacroArgs && !DisableMacroExpansion) { + ModuleImportLoc = Identifier.getLocation(); + CurLexerKind = CLK_LexAfterModuleImport; + } +} + +/// \brief Lex a token following the __import_module__ keyword. +void Preprocessor::LexAfterModuleImport(Token &Result) { + // Figure out what kind of lexer we actually have. + if (CurLexer) + CurLexerKind = CLK_Lexer; + else if (CurPTHLexer) + CurLexerKind = CLK_PTHLexer; + else if (CurTokenLexer) + CurLexerKind = CLK_TokenLexer; + else + CurLexerKind = CLK_CachingLexer; + + // Lex the next token. + Lex(Result); + + // The token sequence + // + // __import_module__ identifier + // + // indicates a module import directive. We already saw the __import_module__ + // keyword, so now we're looking for the identifier. + if (Result.getKind() != tok::identifier) + return; + + // Load the module. + (void)TheModuleLoader.loadModule(ModuleImportLoc, + *Result.getIdentifierInfo(), + Result.getLocation()); } void Preprocessor::AddCommentHandler(CommentHandler *Handler) { @@ -529,6 +604,8 @@ bool Preprocessor::HandleComment(Token &result, SourceRange Comment) { return true; } +ModuleLoader::~ModuleLoader() { } + CommentHandler::~CommentHandler() { } CodeCompletionHandler::~CodeCompletionHandler() { } @@ -538,6 +615,7 @@ void Preprocessor::createPreprocessingRecord( if (Record) return; - Record = new PreprocessingRecord(IncludeNestedMacroExpansions); + Record = new PreprocessingRecord(getSourceManager(), + IncludeNestedMacroExpansions); addPPCallbacks(Record); } |