diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp | 149 |
1 files changed, 97 insertions, 52 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp index 31662ad..06e5685 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp @@ -40,7 +40,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/APFloat.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Capacity.h" @@ -54,18 +54,19 @@ Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup* IILookup, bool OwnsHeaders, - bool DelayInitialization) - : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()), + bool DelayInitialization, + bool IncrProcessing) + : Diags(&diags), LangOpts(opts), Target(target),FileMgr(Headers.getFileMgr()), SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), - ExternalSource(0), - Identifiers(opts, IILookup), CodeComplete(0), + ExternalSource(0), Identifiers(opts, IILookup), + IncrementalProcessing(IncrProcessing), 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); @@ -74,9 +75,6 @@ Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts, 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; @@ -133,11 +131,11 @@ void Preprocessor::Initialize(const TargetInfo &Target) { KeepComments = false; KeepMacroComments = false; SuppressIncludeNotFoundError = false; - AutoModuleImport = false; // Macro expansion is enabled. DisableMacroExpansion = false; InMacroArgs = false; + InMacroArgPreExpansion = false; NumCachedTokenLexers = 0; CachedLexPos = 0; @@ -157,7 +155,7 @@ void Preprocessor::Initialize(const TargetInfo &Target) { // Initialize builtin macros like __LINE__ and friends. RegisterBuiltinMacros(); - if(Features.Borland) { + if(LangOpts.Borland) { Ident__exception_info = getIdentifierInfo("_exception_info"); Ident___exception_info = getIdentifierInfo("__exception_info"); Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation"); @@ -171,7 +169,9 @@ void Preprocessor::Initialize(const TargetInfo &Target) { 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; - } + } + + HeaderInfo.setTarget(Target); } void Preprocessor::setPTHManager(PTHManager* pm) { @@ -270,6 +270,17 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const { return Macros.end(); } +void Preprocessor::recomputeCurLexerKind() { + if (CurLexer) + CurLexerKind = CLK_Lexer; + else if (CurPTHLexer) + CurLexerKind = CLK_PTHLexer; + else if (CurTokenLexer) + CurLexerKind = CLK_TokenLexer; + else + CurLexerKind = CLK_CachingLexer; +} + bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, unsigned CompleteLine, unsigned CompleteColumn) { @@ -372,7 +383,12 @@ void Preprocessor::CreateString(const char *Buf, unsigned Len, Token &Tok, Tok.setLiteralData(DestPtr); } - +Module *Preprocessor::getCurrentModule() { + if (getLangOpts().CurrentModule.empty()) + return 0; + + return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule); +} //===----------------------------------------------------------------------===// // Preprocessor Initialization Methods @@ -388,19 +404,23 @@ void Preprocessor::EnterMainSourceFile() { assert(NumEnteredSourceFiles == 0 && "Cannot reenter the main file!"); FileID MainFileID = SourceMgr.getMainFileID(); - // Enter the main file source buffer. - EnterSourceFile(MainFileID, 0, SourceLocation()); - - // If we've been asked to skip bytes in the main file (e.g., as part of a - // precompiled preamble), do so now. - if (SkipMainFilePreamble.first > 0) - CurLexer->SkipBytes(SkipMainFilePreamble.first, - SkipMainFilePreamble.second); + // If MainFileID is loaded it means we loaded an AST file, no need to enter + // a main file. + if (!SourceMgr.isLoadedFileID(MainFileID)) { + // Enter the main file source buffer. + EnterSourceFile(MainFileID, 0, SourceLocation()); - // Tell the header info that the main file was entered. If the file is later - // #imported, it won't be re-entered. - if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID)) - HeaderInfo.IncrementIncludeCount(FE); + // If we've been asked to skip bytes in the main file (e.g., as part of a + // precompiled preamble), do so now. + if (SkipMainFilePreamble.first > 0) + CurLexer->SkipBytes(SkipMainFilePreamble.first, + SkipMainFilePreamble.second); + + // Tell the header info that the main file was entered. If the file is later + // #imported, it won't be re-entered. + if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID)) + HeaderInfo.IncrementIncludeCount(FE); + } // Preprocess Predefines to populate the initial preprocessor state. llvm::MemoryBuffer *SB = @@ -437,7 +457,7 @@ IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier) const { Identifier.getLength())); } else { // Cleaning needed, alloca a buffer, clean into it, then use the buffer. - llvm::SmallString<64> IdentifierBuffer; + SmallString<64> IdentifierBuffer; StringRef CleanedStr = getSpelling(Identifier, IdentifierBuffer); II = getIdentifierInfo(CleanedStr); } @@ -492,6 +512,13 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { IdentifierInfo &II = *Identifier.getIdentifierInfo(); + // If the information about this identifier is out of date, update it from + // the external source. + if (II.isOutOfDate()) { + ExternalSource->updateOutOfDateIdentifier(II); + Identifier.setKind(II.getTokenID()); + } + // If this identifier was poisoned, and if it was not produced from a macro // expansion, emit an error. if (II.isPoisoned() && CurPPLexer) { @@ -500,8 +527,10 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { // If this is a macro to be expanded, do it. if (MacroInfo *MI = getMacroInfo(&II)) { - if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) { - if (MI->isEnabled()) { + if (!DisableMacroExpansion) { + if (Identifier.isExpandDisabled()) { + Diag(Identifier, diag::pp_disabled_macro_expansion); + } else if (MI->isEnabled()) { if (!HandleMacroExpandedIdentifier(Identifier, MI)) return; } else { @@ -509,6 +538,7 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { // expanded, even if it's in a context where it could be expanded in the // future. Identifier.setFlag(Token::DisableExpand); + Diag(Identifier, diag::pp_disabled_macro_expansion); } } } @@ -537,43 +567,59 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { 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) { + // If this is the '__experimental_modules_import' contextual keyword, note + // that the next token indicates a module name. + // + // Note that we do not treat '__experimental_modules_import' as a contextual + // keyword when we're in a caching lexer, because caching lexers only get + // used in contexts where import declarations are disallowed. + if (II.isModulesImport() && !InMacroArgs && !DisableMacroExpansion && + getLangOpts().Modules && CurLexerKind != CLK_CachingLexer) { ModuleImportLoc = Identifier.getLocation(); + ModuleImportPath.clear(); + ModuleImportExpectsIdentifier = true; CurLexerKind = CLK_LexAfterModuleImport; } } -/// \brief Lex a token following the __import_module__ keyword. +/// \brief Lex a token following the 'import' contextual 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; + recomputeCurLexerKind(); // Lex the next token. Lex(Result); // The token sequence // - // __import_module__ identifier + // import identifier (. 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) + // indicates a module import directive. We already saw the 'import' + // contextual keyword, so now we're looking for the identifiers. + if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) { + // We expected to see an identifier here, and we did; continue handling + // identifiers. + ModuleImportPath.push_back(std::make_pair(Result.getIdentifierInfo(), + Result.getLocation())); + ModuleImportExpectsIdentifier = false; + CurLexerKind = CLK_LexAfterModuleImport; return; + } - // Load the module. - (void)TheModuleLoader.loadModule(ModuleImportLoc, - *Result.getIdentifierInfo(), - Result.getLocation()); + // If we're expecting a '.' or a ';', and we got a '.', then wait until we + // see the next identifier. + if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) { + ModuleImportExpectsIdentifier = true; + CurLexerKind = CLK_LexAfterModuleImport; + return; + } + + // If we have a non-empty module path, load the named module. + if (!ModuleImportPath.empty()) + (void)TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath, + Module::MacrosVisible, + /*IsIncludeDirective=*/false); } void Preprocessor::AddCommentHandler(CommentHandler *Handler) { @@ -610,12 +656,11 @@ CommentHandler::~CommentHandler() { } CodeCompletionHandler::~CodeCompletionHandler() { } -void Preprocessor::createPreprocessingRecord( - bool IncludeNestedMacroExpansions) { +void Preprocessor::createPreprocessingRecord(bool RecordConditionalDirectives) { if (Record) return; Record = new PreprocessingRecord(getSourceManager(), - IncludeNestedMacroExpansions); + RecordConditionalDirectives); addPPCallbacks(Record); } |