summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex/Preprocessor.h
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-05-27 18:47:56 +0000
committerdim <dim@FreeBSD.org>2015-05-27 18:47:56 +0000
commit3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65 (patch)
treedbbd4047878da71c1a706e26ce05b4e7791b14cc /include/clang/Lex/Preprocessor.h
parent38d6f2e7f2ce51a5b3836d26596c6c34a3288752 (diff)
downloadFreeBSD-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.h321
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);
OpenPOWER on IntegriCloud