diff options
author | dim <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
commit | 3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65 (patch) | |
tree | dbbd4047878da71c1a706e26ce05b4e7791b14cc /include/clang/Lex/Preprocessor.h | |
parent | 38d6f2e7f2ce51a5b3836d26596c6c34a3288752 (diff) | |
download | FreeBSD-src-3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65.zip FreeBSD-src-3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65.tar.gz |
Vendor import of clang trunk r238337:
https://llvm.org/svn/llvm-project/cfe/trunk@238337
Diffstat (limited to 'include/clang/Lex/Preprocessor.h')
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 321 |
1 files changed, 280 insertions, 41 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 326f519..ea15dbd 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -31,6 +31,7 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" #include <memory> #include <vector> @@ -356,19 +357,185 @@ class Preprocessor : public RefCountedBase<Preprocessor> { struct MacroExpandsInfo { Token Tok; - MacroDirective *MD; + MacroDefinition MD; SourceRange Range; - MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range) + MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range) : Tok(Tok), MD(MD), Range(Range) { } }; SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks; + /// Information about a name that has been used to define a module macro. + struct ModuleMacroInfo { + ModuleMacroInfo(MacroDirective *MD) + : MD(MD), ActiveModuleMacrosGeneration(0), IsAmbiguous(false) {} + + /// The most recent macro directive for this identifier. + MacroDirective *MD; + /// The active module macros for this identifier. + llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros; + /// The generation number at which we last updated ActiveModuleMacros. + /// \see Preprocessor::VisibleModules. + unsigned ActiveModuleMacrosGeneration; + /// Whether this macro name is ambiguous. + bool IsAmbiguous; + /// The module macros that are overridden by this macro. + llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros; + }; + + /// The state of a macro for an identifier. + class MacroState { + mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State; + + ModuleMacroInfo *getModuleInfo(Preprocessor &PP, + const IdentifierInfo *II) const { + // FIXME: Find a spare bit on IdentifierInfo and store a + // HasModuleMacros flag. + if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules || + !PP.CurSubmoduleState->VisibleModules.getGeneration()) + return nullptr; + + auto *Info = State.dyn_cast<ModuleMacroInfo*>(); + if (!Info) { + Info = new (PP.getPreprocessorAllocator()) + ModuleMacroInfo(State.get<MacroDirective *>()); + State = Info; + } + + if (PP.CurSubmoduleState->VisibleModules.getGeneration() != + Info->ActiveModuleMacrosGeneration) + PP.updateModuleMacroInfo(II, *Info); + return Info; + } + + public: + MacroState() : MacroState(nullptr) {} + MacroState(MacroDirective *MD) : State(MD) {} + MacroState(MacroState &&O) LLVM_NOEXCEPT : State(O.State) { + O.State = (MacroDirective *)nullptr; + } + MacroState &operator=(MacroState &&O) LLVM_NOEXCEPT { + auto S = O.State; + O.State = (MacroDirective *)nullptr; + State = S; + return *this; + } + ~MacroState() { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + Info->~ModuleMacroInfo(); + } + + MacroDirective *getLatest() const { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + return Info->MD; + return State.get<MacroDirective*>(); + } + void setLatest(MacroDirective *MD) { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + Info->MD = MD; + else + State = MD; + } + + bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const { + auto *Info = getModuleInfo(PP, II); + return Info ? Info->IsAmbiguous : false; + } + ArrayRef<ModuleMacro *> + getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const { + if (auto *Info = getModuleInfo(PP, II)) + return Info->ActiveModuleMacros; + return None; + } + + MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc, + SourceManager &SourceMgr) const { + // FIXME: Incorporate module macros into the result of this. + return getLatest()->findDirectiveAtLoc(Loc, SourceMgr); + } + + void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) { + if (auto *Info = getModuleInfo(PP, II)) { + for (auto *Active : Info->ActiveModuleMacros) + Info->OverriddenMacros.push_back(Active); + Info->ActiveModuleMacros.clear(); + Info->IsAmbiguous = false; + } + } + ArrayRef<ModuleMacro*> getOverriddenMacros() const { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + return Info->OverriddenMacros; + return None; + } + void setOverriddenMacros(Preprocessor &PP, + ArrayRef<ModuleMacro *> Overrides) { + auto *Info = State.dyn_cast<ModuleMacroInfo*>(); + if (!Info) { + if (Overrides.empty()) + return; + Info = new (PP.getPreprocessorAllocator()) + ModuleMacroInfo(State.get<MacroDirective *>()); + State = Info; + } + Info->OverriddenMacros.clear(); + Info->OverriddenMacros.insert(Info->OverriddenMacros.end(), + Overrides.begin(), Overrides.end()); + Info->ActiveModuleMacrosGeneration = 0; + } + }; + /// For each IdentifierInfo that was associated with a macro, we /// keep a mapping to the history of all macro definitions and #undefs in /// the reverse order (the latest one is in the head of the list). - llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros; + /// + /// This mapping lives within the \p CurSubmoduleState. + typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap; + friend class ASTReader; - + + struct SubmoduleState; + + /// \brief Information about a submodule that we're currently building. + struct BuildingSubmoduleInfo { + BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, + SubmoduleState *OuterSubmoduleState) + : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) { + } + + /// The module that we are building. + Module *M; + /// The location at which the module was included. + SourceLocation ImportLoc; + /// The previous SubmoduleState. + SubmoduleState *OuterSubmoduleState; + }; + SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack; + + /// \brief Information about a submodule's preprocessor state. + struct SubmoduleState { + /// The macros for the submodule. + MacroMap Macros; + /// The set of modules that are visible within the submodule. + VisibleModuleSet VisibleModules; + // FIXME: CounterValue? + // FIXME: PragmaPushMacroInfo? + }; + std::map<Module*, SubmoduleState> Submodules; + + /// The preprocessor state for preprocessing outside of any submodule. + SubmoduleState NullSubmoduleState; + + /// The current submodule state. Will be \p NullSubmoduleState if we're not + /// in a submodule. + SubmoduleState *CurSubmoduleState; + + /// The set of known macros exported from modules. + llvm::FoldingSet<ModuleMacro> ModuleMacros; + + /// The list of module macros, for each identifier, that are not overridden by + /// any other module macro. + llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>> + LeafModuleMacros; + /// \brief Macros that we want to warn because they are not used at the end /// of the translation unit. /// @@ -427,7 +594,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \c createPreprocessingRecord() prior to preprocessing. PreprocessingRecord *Record; -private: // Cached tokens state. + /// Cached tokens state. typedef SmallVector<Token, 1> CachedTokensTy; /// \brief Cached tokens are stored here when we do backtracking or @@ -507,6 +674,7 @@ public: HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; } IdentifierTable &getIdentifierTable() { return Identifiers; } + const IdentifierTable &getIdentifierTable() const { return Identifiers; } SelectorTable &getSelectorTable() { return Selectors; } Builtin::Context &getBuiltinInfo() { return BuiltinInfo; } llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; } @@ -601,59 +769,114 @@ public: } /// \} - /// \brief Given an identifier, return its latest MacroDirective if it is - /// \#defined or null if it isn't \#define'd. - MacroDirective *getMacroDirective(IdentifierInfo *II) const { + bool isMacroDefined(StringRef Id) { + return isMacroDefined(&Identifiers.get(Id)); + } + bool isMacroDefined(const IdentifierInfo *II) { + return II->hasMacroDefinition() && + (!getLangOpts().Modules || (bool)getMacroDefinition(II)); + } + + MacroDefinition getMacroDefinition(const IdentifierInfo *II) { + if (!II->hasMacroDefinition()) + return MacroDefinition(); + + MacroState &S = CurSubmoduleState->Macros[II]; + auto *MD = S.getLatest(); + while (MD && isa<VisibilityMacroDirective>(MD)) + MD = MD->getPrevious(); + return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD), + S.getActiveModuleMacros(*this, II), + S.isAmbiguous(*this, II)); + } + + MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II, + SourceLocation Loc) { + if (!II->hadMacroDefinition()) + return MacroDefinition(); + + MacroState &S = CurSubmoduleState->Macros[II]; + MacroDirective::DefInfo DI; + if (auto *MD = S.getLatest()) + DI = MD->findDirectiveAtLoc(Loc, getSourceManager()); + // FIXME: Compute the set of active module macros at the specified location. + return MacroDefinition(DI.getDirective(), + S.getActiveModuleMacros(*this, II), + S.isAmbiguous(*this, II)); + } + + /// \brief Given an identifier, return its latest non-imported MacroDirective + /// if it is \#define'd and not \#undef'd, or null if it isn't \#define'd. + MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const { if (!II->hasMacroDefinition()) return nullptr; - MacroDirective *MD = getMacroDirectiveHistory(II); - assert(MD->isDefined() && "Macro is undefined!"); + auto *MD = getLocalMacroDirectiveHistory(II); + if (!MD || MD->getDefinition().isUndefined()) + return nullptr; + return MD; } - const MacroInfo *getMacroInfo(IdentifierInfo *II) const { + const MacroInfo *getMacroInfo(const IdentifierInfo *II) const { return const_cast<Preprocessor*>(this)->getMacroInfo(II); } - MacroInfo *getMacroInfo(IdentifierInfo *II) { - if (MacroDirective *MD = getMacroDirective(II)) - return MD->getMacroInfo(); + MacroInfo *getMacroInfo(const IdentifierInfo *II) { + if (!II->hasMacroDefinition()) + return nullptr; + if (auto MD = getMacroDefinition(II)) + return MD.getMacroInfo(); return nullptr; } - /// \brief Given an identifier, return the (probably #undef'd) MacroInfo - /// representing the most recent macro definition. + /// \brief Given an identifier, return the latest non-imported macro + /// directive for that identifier. /// - /// One can iterate over all previous macro definitions from the most recent - /// one. This should only be called for identifiers that hadMacroDefinition(). - MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const; + /// One can iterate over all previous macro directives from the most recent + /// one. + MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const; /// \brief Add a directive to the macro directive history for this identifier. void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD); DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, - SourceLocation Loc, - unsigned ImportedFromModuleID, - ArrayRef<unsigned> Overrides) { - DefMacroDirective *MD = - AllocateDefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides); + SourceLocation Loc) { + DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc); appendMacroDirective(II, MD); return MD; } - DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){ - return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), 0, None); + DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, + MacroInfo *MI) { + return appendDefMacroDirective(II, MI, MI->getDefinitionLoc()); } /// \brief Set a MacroDirective that was loaded from a PCH file. void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD); + /// \brief Register an exported macro for a module and identifier. + ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides, bool &IsNew); + ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II); + + /// \brief Get the list of leaf (non-overridden) module macros for a name. + ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const { + auto I = LeafModuleMacros.find(II); + if (I != LeafModuleMacros.end()) + return I->second; + return None; + } + /// \{ /// Iterators for the macro history table. Currently defined macros have /// IdentifierInfo::hasMacroDefinition() set and an empty /// MacroInfo::getUndefLoc() at the head of the list. - typedef llvm::DenseMap<const IdentifierInfo *, - MacroDirective*>::const_iterator macro_iterator; + typedef MacroMap::const_iterator macro_iterator; macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; + llvm::iterator_range<macro_iterator> + macros(bool IncludeExternalMacros = true) const { + return llvm::make_range(macro_begin(IncludeExternalMacros), + macro_end(IncludeExternalMacros)); + } /// \} /// \brief Return the name of the macro defined before \p Loc that has @@ -806,6 +1029,12 @@ public: void LexAfterModuleImport(Token &Result); + void makeModuleVisible(Module *M, SourceLocation Loc); + + SourceLocation getModuleImportLoc(Module *M) const { + return CurSubmoduleState->VisibleModules.getImportLoc(M); + } + /// \brief Lex a string literal, which may be the concatenation of multiple /// string literals and may even come from macro expansion. /// \returns true on success, false if a error diagnostic has been generated. @@ -923,7 +1152,7 @@ public: /// location of an annotation token. SourceLocation getLastCachedTokenLocation() const { assert(CachedLexPos != 0); - return CachedTokens[CachedLexPos-1].getLocation(); + return CachedTokens[CachedLexPos-1].getLastLoc(); } /// \brief Replace the last token with an annotation token. @@ -1188,6 +1417,7 @@ public: void DumpToken(const Token &Tok, bool DumpFlags = false) const; void DumpLocation(SourceLocation Loc) const; void DumpMacro(const MacroInfo &MI) const; + void dumpMacroInfo(const IdentifierInfo *II); /// \brief Given a location that specifies the start of a /// token, return a new location that specifies a character within the token. @@ -1406,17 +1636,19 @@ private: void PropagateLineStartLeadingSpaceInfo(Token &Result); + void EnterSubmodule(Module *M, SourceLocation ImportLoc); + void LeaveSubmodule(); + + /// Update the set of active module macros and ambiguity flag for a module + /// macro name. + void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info); + /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); - DefMacroDirective * - AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None); - UndefMacroDirective * - AllocateUndefMacroDirective(SourceLocation UndefLoc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None); + DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI, + SourceLocation Loc); + UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc); VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc, bool isPublic); @@ -1470,7 +1702,7 @@ private: /// If an identifier token is read that is to be expanded as a macro, handle /// it and return the next token as 'Tok'. If we lexed a token, return true; /// otherwise the caller should lex again. - bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD); + bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD); /// \brief Cache macro expanded tokens for TokenLexers. // @@ -1572,11 +1804,18 @@ private: void HandleImportDirective(SourceLocation HashLoc, Token &Tok); void HandleMicrosoftImportDirective(Token &Tok); +public: // Module inclusion testing. - /// \brief Find the module for the source or header file that \p FilenameLoc - /// points to. - Module *getModuleForLocation(SourceLocation FilenameLoc); + /// \brief Find the module that owns the source or header file that + /// \p Loc points to. If the location is in a file that was included + /// into a module, or is outside any module, returns nullptr. + Module *getModuleForLocation(SourceLocation Loc); + + /// \brief Find the module that contains the specified location, either + /// directly or indirectly. + Module *getModuleContainingLocation(SourceLocation Loc); +private: // Macro handling. void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); void HandleUndefDirective(Token &Tok); |