diff options
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 326f519e914e..ea15dbdf2144 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); | 
