diff options
Diffstat (limited to 'include/clang/Lex')
| -rw-r--r-- | include/clang/Lex/ExternalPreprocessorSource.h | 4 | ||||
| -rw-r--r-- | include/clang/Lex/HeaderMap.h | 4 | ||||
| -rw-r--r-- | include/clang/Lex/HeaderSearch.h | 12 | ||||
| -rw-r--r-- | include/clang/Lex/Lexer.h | 24 | ||||
| -rw-r--r-- | include/clang/Lex/LiteralSupport.h | 14 | ||||
| -rw-r--r-- | include/clang/Lex/MacroArgs.h | 3 | ||||
| -rw-r--r-- | include/clang/Lex/MacroInfo.h | 236 | ||||
| -rw-r--r-- | include/clang/Lex/ModuleLoader.h | 3 | ||||
| -rw-r--r-- | include/clang/Lex/ModuleMap.h | 11 | ||||
| -rw-r--r-- | include/clang/Lex/PPCallbacks.h | 44 | ||||
| -rw-r--r-- | include/clang/Lex/PPConditionalDirectiveRecord.h | 4 | ||||
| -rw-r--r-- | include/clang/Lex/PTHLexer.h | 7 | ||||
| -rw-r--r-- | include/clang/Lex/PTHManager.h | 7 | ||||
| -rw-r--r-- | include/clang/Lex/Pragma.h | 2 | ||||
| -rw-r--r-- | include/clang/Lex/PreprocessingRecord.h | 226 | ||||
| -rw-r--r-- | include/clang/Lex/Preprocessor.h | 321 | ||||
| -rw-r--r-- | include/clang/Lex/PreprocessorLexer.h | 4 | ||||
| -rw-r--r-- | include/clang/Lex/Token.h | 19 | ||||
| -rw-r--r-- | include/clang/Lex/TokenLexer.h | 4 |
19 files changed, 593 insertions, 356 deletions
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h index 2f9231dc9f22..33e7a2d84b88 100644 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -17,6 +17,7 @@ namespace clang { class IdentifierInfo; +class Module; /// \brief Abstract interface for external sources of preprocessor /// information. @@ -32,6 +33,9 @@ public: /// \brief Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0; + + /// \brief Map a module ID to a module. + virtual Module *getModule(unsigned ModuleID) = 0; }; } diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 993c8612b0f8..183361e4f8c0 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -32,8 +32,8 @@ namespace clang { /// symlinks to files. Its advantages are that it is dense and more efficient /// to create and process than a directory of symlinks. class HeaderMap { - HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION; - void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION; + HeaderMap(const HeaderMap &) = delete; + void operator=(const HeaderMap &) = delete; std::unique_ptr<const llvm::MemoryBuffer> FileBuffer; bool NeedsBSwap; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 158f67d40b49..0406c6d586ff 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -32,6 +32,7 @@ class FileEntry; class FileManager; class HeaderSearchOptions; class IdentifierInfo; +class Preprocessor; /// \brief The preprocessor keeps track of this information for each /// file that is \#included. @@ -255,8 +256,8 @@ class HeaderSearch { const LangOptions &LangOpts; // HeaderSearch doesn't support default or copy construction. - HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION; - void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION; + HeaderSearch(const HeaderSearch&) = delete; + void operator=(const HeaderSearch&) = delete; friend class DirectoryLookup; @@ -419,8 +420,8 @@ public: /// /// \return false if \#including the file will have no effect or true /// if we should include it. - bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport); - + bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File, + bool isImport); /// \brief Return whether the specified file is a normal header, /// a system header, or a C++ friendly system header. @@ -478,9 +479,6 @@ public: /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); - /// Returns true if modules are enabled. - bool enabledModules() const { return LangOpts.Modules; } - /// \brief Retrieve the name of the module file that should be used to /// load the given module. /// diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index c1f968be5584..07564b9de784 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -89,8 +89,8 @@ class Lexer : public PreprocessorLexer { // CurrentConflictMarkerState - The kind of conflict marker we are handling. ConflictMarkerKind CurrentConflictMarkerState; - Lexer(const Lexer &) LLVM_DELETED_FUNCTION; - void operator=(const Lexer &) LLVM_DELETED_FUNCTION; + Lexer(const Lexer &) = delete; + void operator=(const Lexer &) = delete; friend class Preprocessor; void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd); @@ -323,6 +323,26 @@ public: const SourceManager &SM, const LangOptions &LangOpts); + /// \brief Given a token range, produce a corresponding CharSourceRange that + /// is not a token range. This allows the source range to be used by + /// components that don't have access to the lexer and thus can't find the + /// end of the range for themselves. + static CharSourceRange getAsCharRange(SourceRange Range, + const SourceManager &SM, + const LangOptions &LangOpts) { + SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts); + return End.isInvalid() ? CharSourceRange() + : CharSourceRange::getCharRange( + Range.getBegin(), End.getLocWithOffset(-1)); + } + static CharSourceRange getAsCharRange(CharSourceRange Range, + const SourceManager &SM, + const LangOptions &LangOpts) { + return Range.isTokenRange() + ? getAsCharRange(Range.getAsRange(), SM, LangOpts) + : Range; + } + /// \brief Returns true if the given MacroID location points at the first /// token of the macro expansion. /// diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index f60a152a0aa9..5210e3f2e1c5 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -57,13 +57,13 @@ public: NumericLiteralParser(StringRef TokSpelling, SourceLocation TokLoc, Preprocessor &PP); - bool hadError; - bool isUnsigned; - bool isLong; // This is *not* set for long long. - bool isLongLong; - bool isFloat; // 1.0f - bool isImaginary; // 1.0i - uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. + bool hadError : 1; + bool isUnsigned : 1; + bool isLong : 1; // This is *not* set for long long. + bool isLongLong : 1; + bool isFloat : 1; // 1.0f + bool isImaginary : 1; // 1.0i + uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. bool isIntegerLiteral() const { return !saw_period && !saw_exponent; diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h index d858ec2b4292..243b143f7af6 100644 --- a/include/clang/Lex/MacroArgs.h +++ b/include/clang/Lex/MacroArgs.h @@ -56,7 +56,8 @@ class MacroArgs { MacroArgs(unsigned NumToks, bool varargsElided) : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(nullptr) {} - ~MacroArgs() {} + ~MacroArgs() = default; + public: /// MacroArgs ctor function - Create a new MacroArgs object with the specified /// macro and argument info. diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index ca5d49704877..81d075cb000c 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -17,11 +17,15 @@ #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include <cassert> namespace clang { +class Module; +class ModuleMacro; class Preprocessor; /// \brief Encapsulates the data about a macro definition (e.g. its tokens). @@ -109,7 +113,7 @@ class MacroInfo { // Only the Preprocessor gets to create and destroy these. MacroInfo(SourceLocation DefLoc); - ~MacroInfo() {} + ~MacroInfo() = default; public: /// \brief Return the location that the macro was defined at. @@ -241,6 +245,7 @@ public: tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } tokens_iterator tokens_end() const { return ReplacementTokens.end(); } bool tokens_empty() const { return ReplacementTokens.empty(); } + ArrayRef<Token> tokens() const { return ReplacementTokens; } /// \brief Add the specified token to the replacement text for the macro. void AddTokenToBody(const Token &Tok) { @@ -302,15 +307,8 @@ class DefMacroDirective; /// /// MacroDirectives, associated with an identifier, are used to model the macro /// history. Usually a macro definition (MacroInfo) is where a macro name -/// becomes active (MacroDirective) but modules can have their own macro -/// history, separate from the local (current translation unit) macro history. -/// -/// For example, if "@import A;" imports macro FOO, there will be a new local -/// MacroDirective created to indicate that "FOO" became active at the import -/// location. Module "A" itself will contain another MacroDirective in its macro -/// history (at the point of the definition of FOO) and both MacroDirectives -/// will point to the same MacroInfo object. -/// +/// becomes active (MacroDirective) but #pragma push_macro / pop_macro can +/// create additional DefMacroDirectives for the same MacroInfo. class MacroDirective { public: enum Kind { @@ -331,47 +329,15 @@ protected: /// \brief True if the macro directive was loaded from a PCH file. bool IsFromPCH : 1; - // Used by DefMacroDirective -----------------------------------------------// - - /// \brief Whether the definition of this macro is ambiguous, due to - /// multiple definitions coming in from multiple modules. - bool IsAmbiguous : 1; - // Used by VisibilityMacroDirective ----------------------------------------// /// \brief Whether the macro has public visibility (when described in a /// module). bool IsPublic : 1; - // Used by DefMacroDirective and UndefMacroDirective -----------------------// - - /// \brief True if this macro was imported from a module. - bool IsImported : 1; - - /// \brief For an imported directive, the number of modules whose macros are - /// overridden by this directive. Only used if IsImported. - unsigned NumOverrides : 26; - - unsigned *getModuleDataStart(); - const unsigned *getModuleDataStart() const { - return const_cast<MacroDirective*>(this)->getModuleDataStart(); - } - - MacroDirective(Kind K, SourceLocation Loc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None) + MacroDirective(Kind K, SourceLocation Loc) : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false), - IsAmbiguous(false), IsPublic(true), IsImported(ImportedFromModuleID), - NumOverrides(Overrides.size()) { - assert(NumOverrides == Overrides.size() && "too many overrides"); - assert((IsImported || !NumOverrides) && "overrides for non-module macro"); - - if (IsImported) { - unsigned *Extra = getModuleDataStart(); - *Extra++ = ImportedFromModuleID; - std::copy(Overrides.begin(), Overrides.end(), Extra); - } - } + IsPublic(true) {} public: Kind getKind() const { return Kind(MDKind); } @@ -394,34 +360,13 @@ public: void setIsFromPCH() { IsFromPCH = true; } - /// \brief True if this macro was imported from a module. - /// Note that this is never the case for a VisibilityMacroDirective. - bool isImported() const { return IsImported; } - - /// \brief If this directive was imported from a module, get the submodule - /// whose directive this is. Note that this may be different from the module - /// that owns the MacroInfo for a DefMacroDirective due to #pragma pop_macro - /// and similar effects. - unsigned getOwningModuleID() const { - if (isImported()) - return *getModuleDataStart(); - return 0; - } - - /// \brief Get the module IDs of modules whose macros are overridden by this - /// directive. Only valid if this is an imported directive. - ArrayRef<unsigned> getOverriddenModules() const { - assert(IsImported && "can only get overridden modules for imported macro"); - return llvm::makeArrayRef(getModuleDataStart() + 1, NumOverrides); - } - class DefInfo { DefMacroDirective *DefDirective; SourceLocation UndefLoc; bool IsPublic; public: - DefInfo() : DefDirective(nullptr) { } + DefInfo() : DefDirective(nullptr), IsPublic(true) { } DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc, bool isPublic) @@ -444,7 +389,7 @@ public: bool isValid() const { return DefDirective != nullptr; } bool isInvalid() const { return !isValid(); } - LLVM_EXPLICIT operator bool() const { return isValid(); } + explicit operator bool() const { return isValid(); } inline DefInfo getPreviousDefinition(); const DefInfo getPreviousDefinition() const { @@ -487,30 +432,17 @@ class DefMacroDirective : public MacroDirective { MacroInfo *Info; public: - explicit DefMacroDirective(MacroInfo *MI) - : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) { - assert(MI && "MacroInfo is null"); - } - - DefMacroDirective(MacroInfo *MI, SourceLocation Loc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None) - : MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides), - Info(MI) { + DefMacroDirective(MacroInfo *MI, SourceLocation Loc) + : MacroDirective(MD_Define, Loc), Info(MI) { assert(MI && "MacroInfo is null"); } + explicit DefMacroDirective(MacroInfo *MI) + : DefMacroDirective(MI, MI->getDefinitionLoc()) {} /// \brief The data for the macro definition. const MacroInfo *getInfo() const { return Info; } MacroInfo *getInfo() { return Info; } - /// \brief Determine whether this macro definition is ambiguous with - /// other macro definitions. - bool isAmbiguous() const { return IsAmbiguous; } - - /// \brief Set whether this macro definition is ambiguous. - void setAmbiguous(bool Val) { IsAmbiguous = Val; } - static bool classof(const MacroDirective *MD) { return MD->getKind() == MD_Define; } @@ -520,11 +452,9 @@ public: /// \brief A directive for an undefined macro. class UndefMacroDirective : public MacroDirective { public: - explicit UndefMacroDirective(SourceLocation UndefLoc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None) - : MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) { - assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!"); + explicit UndefMacroDirective(SourceLocation UndefLoc) + : MacroDirective(MD_Undefine, UndefLoc) { + assert(UndefLoc.isValid() && "Invalid UndefLoc!"); } static bool classof(const MacroDirective *MD) { @@ -537,7 +467,7 @@ public: class VisibilityMacroDirective : public MacroDirective { public: explicit VisibilityMacroDirective(SourceLocation Loc, bool Public) - : MacroDirective(MD_Visibility, Loc) { + : MacroDirective(MD_Visibility, Loc) { IsPublic = Public; } @@ -551,13 +481,6 @@ public: static bool classof(const VisibilityMacroDirective *) { return true; } }; -inline unsigned *MacroDirective::getModuleDataStart() { - if (auto *Def = dyn_cast<DefMacroDirective>(this)) - return reinterpret_cast<unsigned*>(Def + 1); - else - return reinterpret_cast<unsigned*>(cast<UndefMacroDirective>(this) + 1); -} - inline SourceLocation MacroDirective::DefInfo::getLocation() const { if (isInvalid()) return SourceLocation(); @@ -577,6 +500,123 @@ MacroDirective::DefInfo::getPreviousDefinition() { return DefDirective->getPrevious()->getDefinition(); } -} // end namespace clang +/// \brief Represents a macro directive exported by a module. +/// +/// There's an instance of this class for every macro #define or #undef that is +/// the final directive for a macro name within a module. These entities also +/// represent the macro override graph. +/// +/// These are stored in a FoldingSet in the preprocessor. +class ModuleMacro : public llvm::FoldingSetNode { + /// The name defined by the macro. + IdentifierInfo *II; + /// The body of the #define, or nullptr if this is a #undef. + MacroInfo *Macro; + /// The module that exports this macro. + Module *OwningModule; + /// The number of module macros that override this one. + unsigned NumOverriddenBy; + /// The number of modules whose macros are directly overridden by this one. + unsigned NumOverrides; + //ModuleMacro *OverriddenMacros[NumOverrides]; + + friend class Preprocessor; + + ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides) + : II(II), Macro(Macro), OwningModule(OwningModule), + NumOverriddenBy(0), NumOverrides(Overrides.size()) { + std::copy(Overrides.begin(), Overrides.end(), + reinterpret_cast<ModuleMacro **>(this + 1)); + } + +public: + static ModuleMacro *create(Preprocessor &PP, Module *OwningModule, + IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides); + + void Profile(llvm::FoldingSetNodeID &ID) const { + return Profile(ID, OwningModule, II); + } + static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule, + IdentifierInfo *II) { + ID.AddPointer(OwningModule); + ID.AddPointer(II); + } + + /// Get the ID of the module that exports this macro. + Module *getOwningModule() const { return OwningModule; } + + /// Get definition for this exported #define, or nullptr if this + /// represents a #undef. + MacroInfo *getMacroInfo() const { return Macro; } + + /// Iterators over the overridden module IDs. + /// \{ + typedef ModuleMacro *const *overrides_iterator; + overrides_iterator overrides_begin() const { + return reinterpret_cast<overrides_iterator>(this + 1); + } + overrides_iterator overrides_end() const { + return overrides_begin() + NumOverrides; + } + ArrayRef<ModuleMacro *> overrides() const { + return llvm::makeArrayRef(overrides_begin(), overrides_end()); + } + /// \} + + /// Get the number of macros that override this one. + unsigned getNumOverridingMacros() const { return NumOverriddenBy; } +}; + +/// \brief A description of the current definition of a macro. +/// +/// The definition of a macro comprises a set of (at least one) defining +/// entities, which are either local MacroDirectives or imported ModuleMacros. +class MacroDefinition { + llvm::PointerIntPair<DefMacroDirective *, 1, bool> LatestLocalAndAmbiguous; + ArrayRef<ModuleMacro *> ModuleMacros; + +public: + MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {} + MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs, + bool IsAmbiguous) + : LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {} + + /// \brief Determine whether there is a definition of this macro. + explicit operator bool() const { + return getLocalDirective() || !ModuleMacros.empty(); + } + + /// \brief Get the MacroInfo that should be used for this definition. + MacroInfo *getMacroInfo() const { + if (!ModuleMacros.empty()) + return ModuleMacros.back()->getMacroInfo(); + if (auto *MD = getLocalDirective()) + return MD->getMacroInfo(); + return nullptr; + } + + /// \brief \c true if the definition is ambiguous, \c false otherwise. + bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); } + + /// \brief Get the latest non-imported, non-\#undef'd macro definition + /// for this macro. + DefMacroDirective *getLocalDirective() const { + return LatestLocalAndAmbiguous.getPointer(); + } + + /// \brief Get the active module macros for this macro. + ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; } + + template <typename Fn> void forAllDefinitions(Fn F) const { + if (auto *MD = getLocalDirective()) + F(MD->getMacroInfo()); + for (auto *MM : getModuleMacros()) + F(MM->getMacroInfo()); + } +}; + +} // end namespace clang #endif diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index 36605c9c18c6..ae79650d1fd0 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -99,8 +99,7 @@ public: /// \brief Make the given module visible. virtual void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain) = 0; + SourceLocation ImportLoc) = 0; /// \brief Load, create, or return global module. /// This function returns an existing global module index, if one diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index ed885a7410d5..83a410dfc9e8 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -64,6 +64,9 @@ private: /// \brief The top-level modules that are known. llvm::StringMap<Module *> Modules; + /// \brief The number of modules we have created in total. + unsigned NumCreatedModules; + public: /// \brief Flags describing the role of a module header. enum ModuleHeaderRole { @@ -104,7 +107,7 @@ public: // \brief Whether this known header is valid (i.e., it has an // associated module). - LLVM_EXPLICIT operator bool() const { + explicit operator bool() const { return Storage.getPointer() != nullptr; } }; @@ -434,11 +437,13 @@ public: /// \brief Sets the umbrella header of the given module to the given /// header. - void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader); + void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, + Twine NameAsWritten); /// \brief Sets the umbrella directory of the given module to the given /// directory. - void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir); + void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, + Twine NameAsWritten); /// \brief Adds this header to the given module. /// \param Role The role of the header wrt the module. diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 056c58aa3348..1ddb5d61eff5 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -27,6 +27,7 @@ namespace clang { class SourceLocation; class Token; class IdentifierInfo; + class MacroDefinition; class MacroDirective; class MacroArgs; @@ -54,11 +55,12 @@ public: /// \brief Callback invoked whenever a source file is skipped as the result /// of header guard optimization. /// - /// \param ParentFile The file that \#included the skipped file. + /// \param SkippedFile The file that is skipped instead of entering \#include /// - /// \param FilenameTok The token in ParentFile that indicates the - /// skipped file. - virtual void FileSkipped(const FileEntry &ParentFile, + /// \param FilenameTok The file name token in \#include "FileName" directive + /// or macro expanded file name token from \#include MACRO(PARAMS) directive. + /// Note that FilenameTok contains corresponding quotes/angles symbols. + virtual void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) { } @@ -238,9 +240,9 @@ public: /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a /// macro invocation is found. - virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range, const MacroArgs *Args) { - } + virtual void MacroExpands(const Token &MacroNameTok, + const MacroDefinition &MD, SourceRange Range, + const MacroArgs *Args) {} /// \brief Hook called whenever a macro definition is seen. virtual void MacroDefined(const Token &MacroNameTok, @@ -251,12 +253,12 @@ public: /// /// MD is released immediately following this callback. virtual void MacroUndefined(const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { } /// \brief Hook called whenever the 'defined' operator is seen. /// \param MD The MacroDirective if the name was a macro, null otherwise. - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) { } @@ -293,17 +295,17 @@ public: /// \brief Hook called whenever an \#ifdef is seen. /// \param Loc the source location of the directive. /// \param MacroNameTok Information on the token being tested. - /// \param MD The MacroDirective if the name was a macro, null otherwise. + /// \param MD The MacroDefinition if the name was a macro, null otherwise. virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { } /// \brief Hook called whenever an \#ifndef is seen. /// \param Loc the source location of the directive. /// \param MacroNameTok Information on the token being tested. - /// \param MD The MacroDirective if the name was a macro, null otherwise. + /// \param MD The MacroDefiniton if the name was a macro, null otherwise. virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { } /// \brief Hook called whenever an \#else is seen. @@ -336,11 +338,11 @@ public: Second->FileChanged(Loc, Reason, FileType, PrevFID); } - void FileSkipped(const FileEntry &ParentFile, + void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) override { - First->FileSkipped(ParentFile, FilenameTok, FileType); - Second->FileSkipped(ParentFile, FilenameTok, FileType); + First->FileSkipped(SkippedFile, FilenameTok, FileType); + Second->FileSkipped(SkippedFile, FilenameTok, FileType); } bool FileNotFound(StringRef FileName, @@ -434,7 +436,7 @@ public: Second->PragmaWarningPop(Loc); } - void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, + void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { First->MacroExpands(MacroNameTok, MD, Range, Args); Second->MacroExpands(MacroNameTok, MD, Range, Args); @@ -446,12 +448,12 @@ public: } void MacroUndefined(const Token &MacroNameTok, - const MacroDirective *MD) override { + const MacroDefinition &MD) override { First->MacroUndefined(MacroNameTok, MD); Second->MacroUndefined(MacroNameTok, MD); } - void Defined(const Token &MacroNameTok, const MacroDirective *MD, + void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) override { First->Defined(MacroNameTok, MD, Range); Second->Defined(MacroNameTok, MD, Range); @@ -478,14 +480,14 @@ public: /// \brief Hook called whenever an \#ifdef is seen. void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override { + const MacroDefinition &MD) override { First->Ifdef(Loc, MacroNameTok, MD); Second->Ifdef(Loc, MacroNameTok, MD); } /// \brief Hook called whenever an \#ifndef is seen. void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override { + const MacroDefinition &MD) override { First->Ifndef(Loc, MacroNameTok, MD); Second->Ifndef(Loc, MacroNameTok, MD); } diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h index 00d2d5797359..8c5227561b83 100644 --- a/include/clang/Lex/PPConditionalDirectiveRecord.h +++ b/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -91,9 +91,9 @@ private: void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue, SourceLocation IfLoc) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; void Else(SourceLocation Loc, SourceLocation IfLoc) override; void Endif(SourceLocation Loc, SourceLocation IfLoc) override; }; diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h index 54c91f6b0860..904be792b2a9 100644 --- a/include/clang/Lex/PTHLexer.h +++ b/include/clang/Lex/PTHLexer.h @@ -44,8 +44,8 @@ class PTHLexer : public PreprocessorLexer { /// to process when doing quick skipping of preprocessor blocks. const unsigned char* CurPPCondPtr; - PTHLexer(const PTHLexer &) LLVM_DELETED_FUNCTION; - void operator=(const PTHLexer &) LLVM_DELETED_FUNCTION; + PTHLexer(const PTHLexer &) = delete; + void operator=(const PTHLexer &) = delete; /// ReadToken - Used by PTHLexer to read tokens TokBuf. void ReadToken(Token& T); @@ -64,8 +64,7 @@ protected: PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D, const unsigned char* ppcond, PTHManager &PM); public: - - ~PTHLexer() {} + ~PTHLexer() override {} /// Lex - Return the next token. bool Lex(Token &Tok); diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h index 64ecf5f575f3..a4198f890e13 100644 --- a/include/clang/Lex/PTHManager.h +++ b/include/clang/Lex/PTHManager.h @@ -19,6 +19,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Lex/PTHLexer.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/OnDiskHashTable.h" #include <string> @@ -91,8 +92,8 @@ class PTHManager : public IdentifierInfoLookup { std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds, const unsigned char *spellingBase, const char *originalSourceFile); - PTHManager(const PTHManager &) LLVM_DELETED_FUNCTION; - void operator=(const PTHManager &) LLVM_DELETED_FUNCTION; + PTHManager(const PTHManager &) = delete; + void operator=(const PTHManager &) = delete; /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached /// spelling for a token. @@ -112,7 +113,7 @@ public: // The current PTH version. enum { Version = 10 }; - ~PTHManager(); + ~PTHManager() override; /// getOriginalSourceFile - Return the full path to the original header /// file name that was used to generate the PTH cache. diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h index 4123bae2ea3a..70fcfda6e754 100644 --- a/include/clang/Lex/Pragma.h +++ b/include/clang/Lex/Pragma.h @@ -93,7 +93,7 @@ class PragmaNamespace : public PragmaHandler { llvm::StringMap<PragmaHandler*> Handlers; public: explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {} - virtual ~PragmaNamespace(); + ~PragmaNamespace() override; /// FindHandler - Check to see if there is already a handler for the /// specified name. If not, return the handler for the null name if it diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index 4609fe3c68f8..53367ab854f2 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include <vector> @@ -35,11 +36,11 @@ void* operator new(size_t bytes, clang::PreprocessingRecord& PR, unsigned alignment = 8) throw(); /// \brief Frees memory allocated in a Clang preprocessing record. -void operator delete(void* ptr, clang::PreprocessingRecord& PR, +void operator delete(void *ptr, clang::PreprocessingRecord &PR, unsigned) throw(); namespace clang { - class MacroDefinition; + class MacroDefinitionRecord; class FileEntry; /// \brief Base class that describes a preprocessed entity, which may be a @@ -132,19 +133,20 @@ namespace clang { PD->getKind() <= LastPreprocessingDirective; } }; - + /// \brief Record the location of a macro definition. - class MacroDefinition : public PreprocessingDirective { + class MacroDefinitionRecord : public PreprocessingDirective { /// \brief The name of the macro being defined. const IdentifierInfo *Name; public: - explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range) - : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { } - + explicit MacroDefinitionRecord(const IdentifierInfo *Name, + SourceRange Range) + : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {} + /// \brief Retrieve the name of the macro being defined. const IdentifierInfo *getName() const { return Name; } - + /// \brief Retrieve the location of the macro name in the definition. SourceLocation getLocation() const { return getSourceRange().getBegin(); } @@ -158,31 +160,31 @@ namespace clang { class MacroExpansion : public PreprocessedEntity { /// \brief The definition of this macro or the name of the macro if it is /// a builtin macro. - llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef; + llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef; public: MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) - : PreprocessedEntity(MacroExpansionKind, Range), - NameOrDef(BuiltinName) { } + : PreprocessedEntity(MacroExpansionKind, Range), + NameOrDef(BuiltinName) {} - MacroExpansion(MacroDefinition *Definition, SourceRange Range) - : PreprocessedEntity(MacroExpansionKind, Range), - NameOrDef(Definition) { } + MacroExpansion(MacroDefinitionRecord *Definition, SourceRange Range) + : PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) { + } /// \brief True if it is a builtin macro. bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); } - + /// \brief The name of the macro being expanded. const IdentifierInfo *getName() const { - if (MacroDefinition *Def = getDefinition()) + if (MacroDefinitionRecord *Def = getDefinition()) return Def->getName(); - return NameOrDef.get<IdentifierInfo*>(); + return NameOrDef.get<IdentifierInfo *>(); } - + /// \brief The definition of the macro being expanded. May return null if /// this is a builtin macro. - MacroDefinition *getDefinition() const { - return NameOrDef.dyn_cast<MacroDefinition *>(); + MacroDefinitionRecord *getDefinition() const { + return NameOrDef.dyn_cast<MacroDefinitionRecord *>(); } // Implement isa/cast/dyncast/etc. @@ -329,7 +331,7 @@ namespace clang { } /// \brief Mapping from MacroInfo structures to their definitions. - llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions; + llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions; /// \brief External source of preprocessed entities. ExternalPreprocessingRecordSource *ExternalSource; @@ -360,12 +362,12 @@ namespace clang { unsigned allocateLoadedEntities(unsigned NumEntities); /// \brief Register a new macro definition. - void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def); - + void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def); + public: /// \brief Construct a new preprocessing record. explicit PreprocessingRecord(SourceManager &SM); - + /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { return BumpAlloc.Allocate(Size, Align); @@ -378,125 +380,44 @@ namespace clang { SourceManager &getSourceManager() const { return SourceMgr; } - // Iteration over the preprocessed entities. - class iterator { + /// Iteration over the preprocessed entities. + /// + /// In a complete iteration, the iterator walks the range [-M, N), + /// where negative values are used to indicate preprocessed entities + /// loaded from the external source while non-negative values are used to + /// indicate preprocessed entities introduced by the current preprocessor. + /// However, to provide iteration in source order (for, e.g., chained + /// precompiled headers), dereferencing the iterator flips the negative + /// values (corresponding to loaded entities), so that position -M + /// corresponds to element 0 in the loaded entities vector, position -M+1 + /// corresponds to element 1 in the loaded entities vector, etc. This + /// gives us a reasonably efficient, source-order walk. + /// + /// We define this as a wrapping iterator around an int. The + /// iterator_adaptor_base class forwards the iterator methods to basic + /// integer arithmetic. + class iterator : public llvm::iterator_adaptor_base< + iterator, int, std::random_access_iterator_tag, + PreprocessedEntity *, int, PreprocessedEntity *, + PreprocessedEntity *> { PreprocessingRecord *Self; - - /// \brief Position within the preprocessed entity sequence. - /// - /// In a complete iteration, the Position field walks the range [-M, N), - /// where negative values are used to indicate preprocessed entities - /// loaded from the external source while non-negative values are used to - /// indicate preprocessed entities introduced by the current preprocessor. - /// However, to provide iteration in source order (for, e.g., chained - /// precompiled headers), dereferencing the iterator flips the negative - /// values (corresponding to loaded entities), so that position -M - /// corresponds to element 0 in the loaded entities vector, position -M+1 - /// corresponds to element 1 in the loaded entities vector, etc. This - /// gives us a reasonably efficient, source-order walk. - int Position; - - public: - typedef PreprocessedEntity *value_type; - typedef value_type& reference; - typedef value_type* pointer; - typedef std::random_access_iterator_tag iterator_category; - typedef int difference_type; - - iterator() : Self(nullptr), Position(0) { } - + iterator(PreprocessingRecord *Self, int Position) - : Self(Self), Position(Position) { } - - value_type operator*() const { - bool isLoaded = Position < 0; + : iterator::iterator_adaptor_base(Position), Self(Self) {} + friend class PreprocessingRecord; + + public: + iterator() : iterator(nullptr, 0) {} + + PreprocessedEntity *operator*() const { + bool isLoaded = this->I < 0; unsigned Index = isLoaded ? - Self->LoadedPreprocessedEntities.size() + Position : Position; + Self->LoadedPreprocessedEntities.size() + this->I : this->I; PPEntityID ID = Self->getPPEntityID(Index, isLoaded); return Self->getPreprocessedEntity(ID); } - - value_type operator[](difference_type D) { - return *(*this + D); - } - - iterator &operator++() { - ++Position; - return *this; - } - - iterator operator++(int) { - iterator Prev(*this); - ++Position; - return Prev; - } - - iterator &operator--() { - --Position; - return *this; - } - - iterator operator--(int) { - iterator Prev(*this); - --Position; - return Prev; - } - - friend bool operator==(const iterator &X, const iterator &Y) { - return X.Position == Y.Position; - } - - friend bool operator!=(const iterator &X, const iterator &Y) { - return X.Position != Y.Position; - } - - friend bool operator<(const iterator &X, const iterator &Y) { - return X.Position < Y.Position; - } - - friend bool operator>(const iterator &X, const iterator &Y) { - return X.Position > Y.Position; - } - - friend bool operator<=(const iterator &X, const iterator &Y) { - return X.Position < Y.Position; - } - - friend bool operator>=(const iterator &X, const iterator &Y) { - return X.Position > Y.Position; - } - - friend iterator& operator+=(iterator &X, difference_type D) { - X.Position += D; - return X; - } - - friend iterator& operator-=(iterator &X, difference_type D) { - X.Position -= D; - return X; - } - - friend iterator operator+(iterator X, difference_type D) { - X.Position += D; - return X; - } - - friend iterator operator+(difference_type D, iterator X) { - X.Position += D; - return X; - } - - friend difference_type operator-(const iterator &X, const iterator &Y) { - return X.Position - Y.Position; - } - - friend iterator operator-(iterator X, difference_type D) { - X.Position -= D; - return X; - } - friend class PreprocessingRecord; + PreprocessedEntity *operator->() const { return **this; } }; - friend class iterator; /// \brief Begin iterator for all preprocessed entities. iterator begin() { @@ -518,23 +439,24 @@ namespace clang { return iterator(this, PreprocessedEntities.size()); } - /// \brief begin/end iterator pair for the given range of loaded + /// \brief iterator range for the given range of loaded /// preprocessed entities. - std::pair<iterator, iterator> - getIteratorsForLoadedRange(unsigned start, unsigned count) { + llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start, + unsigned count) { unsigned end = start + count; assert(end <= LoadedPreprocessedEntities.size()); - return std::make_pair( - iterator(this, int(start)-LoadedPreprocessedEntities.size()), - iterator(this, int(end)-LoadedPreprocessedEntities.size())); + return llvm::make_range( + iterator(this, int(start) - LoadedPreprocessedEntities.size()), + iterator(this, int(end) - LoadedPreprocessedEntities.size())); } - /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities - /// that source range \p R encompasses. + /// \brief Returns a range of preprocessed entities that source range \p R + /// encompasses. /// /// \param R the range to look for preprocessed entities. /// - std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R); + llvm::iterator_range<iterator> + getPreprocessedEntitiesInRange(SourceRange R); /// \brief Returns true if the preprocessed entity that \p PPEI iterator /// points to is coming from the file \p FID. @@ -555,10 +477,10 @@ namespace clang { ExternalPreprocessingRecordSource *getExternalSource() const { return ExternalSource; } - + /// \brief Retrieve the macro definition that corresponds to the given /// \c MacroInfo. - MacroDefinition *findMacroDefinition(const MacroInfo *MI); + MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI); /// \brief Retrieve all ranges that got skipped while preprocessing. const std::vector<SourceRange> &getSkippedRanges() const { @@ -566,10 +488,10 @@ namespace clang { } private: - void MacroExpands(const Token &Id, const MacroDirective *MD, + void MacroExpands(const Token &Id, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override; void MacroDefined(const Token &Id, const MacroDirective *MD) override; - void MacroUndefined(const Token &Id, const MacroDirective *MD) override; + void MacroUndefined(const Token &Id, const MacroDefinition &MD) override; void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, @@ -577,11 +499,11 @@ namespace clang { StringRef RelativePath, const Module *Imported) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; /// \brief Hook called whenever the 'defined' operator is seen. - void Defined(const Token &MacroNameTok, const MacroDirective *MD, + void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) override; void SourceRangeSkipped(SourceRange Range) override; 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; + + auto *MD = getLocalMacroDirectiveHistory(II); + if (!MD || MD->getDefinition().isUndefined()) return nullptr; - MacroDirective *MD = getMacroDirectiveHistory(II); - assert(MD->isDefined() && "Macro is undefined!"); 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); diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h index 3a91fa72f2e5..6d6cf05a96c4 100644 --- a/include/clang/Lex/PreprocessorLexer.h +++ b/include/clang/Lex/PreprocessorLexer.h @@ -69,8 +69,8 @@ protected: /// we are currently in. SmallVector<PPConditionalInfo, 4> ConditionalStack; - PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; - void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; + PreprocessorLexer(const PreprocessorLexer &) = delete; + void operator=(const PreprocessorLexer &) = delete; friend class Preprocessor; PreprocessorLexer(Preprocessor *pp, FileID fid); diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index 4a53c9c1bb19..e0878093402a 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -35,8 +35,8 @@ class IdentifierInfo; /// can be represented by a single typename annotation token that carries /// information about the SourceRange of the tokens and the type object. class Token { - /// The location of the token. - SourceLocation Loc; + /// The location of the token. This is actually a SourceLocation. + unsigned Loc; // Conceptually these next two fields could be in a union. However, this // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical @@ -114,13 +114,15 @@ public: /// \brief Return a source location identifier for the specified /// offset in the current file. - SourceLocation getLocation() const { return Loc; } + SourceLocation getLocation() const { + return SourceLocation::getFromRawEncoding(Loc); + } unsigned getLength() const { assert(!isAnnotation() && "Annotation tokens have no length field"); return UintData; } - void setLocation(SourceLocation L) { Loc = L; } + void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } void setLength(unsigned Len) { assert(!isAnnotation() && "Annotation tokens have no length field"); UintData = Len; @@ -128,7 +130,7 @@ public: SourceLocation getAnnotationEndLoc() const { assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); - return SourceLocation::getFromRawEncoding(UintData); + return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); } void setAnnotationEndLoc(SourceLocation L) { assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); @@ -139,6 +141,11 @@ public: return isAnnotation() ? getAnnotationEndLoc() : getLocation(); } + SourceLocation getEndLoc() const { + return isAnnotation() ? getAnnotationEndLoc() + : getLocation().getLocWithOffset(getLength()); + } + /// \brief SourceRange of the group of tokens that this annotation token /// represents. SourceRange getAnnotationRange() const { @@ -157,7 +164,7 @@ public: Flags = 0; PtrData = nullptr; UintData = 0; - Loc = SourceLocation(); + Loc = SourceLocation().getRawEncoding(); } IdentifierInfo *getIdentifierInfo() const { diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index 306f98e2609a..31197367c422 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -99,8 +99,8 @@ class TokenLexer { /// should not be subject to further macro expansion. bool DisableMacroExpansion : 1; - TokenLexer(const TokenLexer &) LLVM_DELETED_FUNCTION; - void operator=(const TokenLexer &) LLVM_DELETED_FUNCTION; + TokenLexer(const TokenLexer &) = delete; + void operator=(const TokenLexer &) = delete; public: /// Create a TokenLexer for the specified macro with the specified actual /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. |
