diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 |
commit | 06d4ba388873e6d1cfa9cd715a8935ecc8cd2097 (patch) | |
tree | 3eb853da77d46cc77c4b017525a422f9ddb1385b /include/clang/Lex | |
parent | 30d791273d07fac9c0c1641a0731191bca6e8606 (diff) |
Notes
Diffstat (limited to 'include/clang/Lex')
-rw-r--r-- | include/clang/Lex/ExternalPreprocessorSource.h | 6 | ||||
-rw-r--r-- | include/clang/Lex/HeaderMap.h | 10 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 29 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearchOptions.h | 13 | ||||
-rw-r--r-- | include/clang/Lex/LexDiagnostic.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/Lexer.h | 10 | ||||
-rw-r--r-- | include/clang/Lex/LiteralSupport.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/MacroArgs.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/MacroInfo.h | 119 | ||||
-rw-r--r-- | include/clang/Lex/ModuleLoader.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/ModuleMap.h | 116 | ||||
-rw-r--r-- | include/clang/Lex/MultipleIncludeOpt.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/PPCallbacks.h | 11 | ||||
-rw-r--r-- | include/clang/Lex/PTHLexer.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/PTHManager.h | 32 | ||||
-rw-r--r-- | include/clang/Lex/Pragma.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 103 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessorLexer.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/ScratchBuffer.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/Token.h | 29 | ||||
-rw-r--r-- | include/clang/Lex/TokenConcatenation.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/TokenLexer.h | 4 |
22 files changed, 342 insertions, 180 deletions
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h index d9a4de4d99815..2f9231dc9f226 100644 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -11,8 +11,8 @@ // construction of macro definitions from some external source. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H -#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H +#ifndef LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H +#define LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H namespace clang { @@ -36,4 +36,4 @@ public: } -#endif // LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H +#endif diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 8e78b5ac98841..993c8612b0f89 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -16,6 +16,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/Support/Compiler.h" +#include <memory> namespace llvm { class MemoryBuffer; @@ -34,15 +35,12 @@ class HeaderMap { HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION; void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION; - const llvm::MemoryBuffer *FileBuffer; + std::unique_ptr<const llvm::MemoryBuffer> FileBuffer; bool NeedsBSwap; - HeaderMap(const llvm::MemoryBuffer *File, bool BSwap) - : FileBuffer(File), NeedsBSwap(BSwap) { - } + HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap) + : FileBuffer(std::move(File)), NeedsBSwap(BSwap) {} public: - ~HeaderMap(); - /// HeaderMap::Create - This attempts to load the specified file as a header /// map. If it doesn't look like a HeaderMap, it gives up and returns null. static const HeaderMap *Create(const FileEntry *FE, FileManager &FM); diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 0342629827708..158f67d40b494 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -231,7 +231,11 @@ class HeaderSearch { /// \brief Describes whether a given directory has a module map in it. llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap; - + + /// \brief Set of module map files we've already loaded, and a flag indicating + /// whether they were valid or not. + llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps; + /// \brief Uniqued set of framework names, which is used to track which /// headers were included as framework headers. llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames; @@ -248,7 +252,7 @@ class HeaderSearch { unsigned NumMultiIncludeFileOptzn; unsigned NumFrameworkLookups, NumSubFrameworkLookups; - bool EnabledModules; + const LangOptions &LangOpts; // HeaderSearch doesn't support default or copy construction. HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION; @@ -384,14 +388,12 @@ public: /// \param SuggestedModule If non-null, and the file found is semantically /// part of a known module, this will be set to the module that should /// be imported instead of preprocessing/parsing the file found. - const FileEntry *LookupFile(StringRef Filename, SourceLocation IncludeLoc, - bool isAngled, const DirectoryLookup *FromDir, - const DirectoryLookup *&CurDir, - ArrayRef<const FileEntry *> Includers, - SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, - ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache = false); + const FileEntry *LookupFile( + StringRef Filename, SourceLocation IncludeLoc, bool isAngled, + const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, + ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, + SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); /// \brief Look up a subframework for the specified \#include file. /// @@ -409,7 +411,7 @@ public: /// \brief Look up the specified framework name in our framework cache. /// \returns The DirectoryEntry it is in if we know, null otherwise. FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) { - return FrameworkMap.GetOrCreateValue(FWName).getValue(); + return FrameworkMap[FWName]; } /// \brief Mark the specified file as a target of of a \#include, @@ -477,7 +479,7 @@ public: const HeaderMap *CreateHeaderMap(const FileEntry *FE); /// Returns true if modules are enabled. - bool enabledModules() const { return EnabledModules; } + bool enabledModules() const { return LangOpts.Modules; } /// \brief Retrieve the name of the module file that should be used to /// load the given module. @@ -638,7 +640,8 @@ private: }; LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File, - bool IsSystem); + bool IsSystem, + const DirectoryEntry *Dir); /// \brief Try to load the module map file in the given directory. /// diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h index 06024b2e90f25..775943de81698 100644 --- a/include/clang/Lex/HeaderSearchOptions.h +++ b/include/clang/Lex/HeaderSearchOptions.h @@ -101,6 +101,15 @@ public: /// \brief Interpret module maps. This option is implied by full modules. unsigned ModuleMaps : 1; + /// \brief Set the 'home directory' of a module map file to the current + /// working directory (or the home directory of the module map file that + /// contained the 'extern module' directive importing this module map file + /// if any) rather than the directory containing the module map file. + // + /// The home directory is where we look for files named in the module map + /// file. + unsigned ModuleMapFileHomeIsCwd : 1; + /// \brief The interval (in seconds) between pruning operations. /// /// This operation is expensive, because it requires Clang to walk through @@ -129,9 +138,6 @@ public: /// of computing the module hash. llvm::SetVector<std::string> ModulesIgnoreMacros; - /// \brief The set of user-provided module-map-files. - llvm::SetVector<std::string> ModuleMapFiles; - /// \brief The set of user-provided virtual filesystem overlay files. std::vector<std::string> VFSOverlayFiles; @@ -161,6 +167,7 @@ public: public: HeaderSearchOptions(StringRef _Sysroot = "/") : Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0), + ModuleMapFileHomeIsCwd(0), ModuleCachePruneInterval(7*24*60*60), ModuleCachePruneAfter(31*24*60*60), BuildSessionTimestamp(0), diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h index 85424aa8a10f3..5d724c0de8799 100644 --- a/include/clang/Lex/LexDiagnostic.h +++ b/include/clang/Lex/LexDiagnostic.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_DIAGNOSTICLEX_H -#define LLVM_CLANG_DIAGNOSTICLEX_H +#ifndef LLVM_CLANG_LEX_LEXDIAGNOSTIC_H +#define LLVM_CLANG_LEX_LEXDIAGNOSTIC_H #include "clang/Basic/Diagnostic.h" diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index edcf883eced3f..c1f968be55845 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEXER_H -#define LLVM_CLANG_LEXER_H +#ifndef LLVM_CLANG_LEX_LEXER_H +#define LLVM_CLANG_LEX_LEXER_H #include "clang/Basic/LangOptions.h" #include "clang/Lex/PreprocessorLexer.h" @@ -405,9 +405,9 @@ public: /// \returns The offset into the file where the preamble ends and the rest /// of the file begins along with a boolean value indicating whether /// the preamble ends at the beginning of a new line. - static std::pair<unsigned, bool> - ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &LangOpts, - unsigned MaxLines = 0); + static std::pair<unsigned, bool> ComputePreamble(StringRef Buffer, + const LangOptions &LangOpts, + unsigned MaxLines = 0); /// \brief Checks that the given token is the first token that occurs after /// the given location (this excludes comments and whitespace). Returns the diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index b7fcc5d34de69..f60a152a0aa96 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_LITERALSUPPORT_H -#define CLANG_LITERALSUPPORT_H +#ifndef LLVM_CLANG_LEX_LITERALSUPPORT_H +#define LLVM_CLANG_LEX_LITERALSUPPORT_H #include "clang/Basic/CharInfo.h" #include "clang/Basic/LLVM.h" diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h index 4c0120c77f045..d858ec2b42927 100644 --- a/include/clang/Lex/MacroArgs.h +++ b/include/clang/Lex/MacroArgs.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_MACROARGS_H -#define LLVM_CLANG_MACROARGS_H +#ifndef LLVM_CLANG_LEX_MACROARGS_H +#define LLVM_CLANG_LEX_MACROARGS_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index e9a66e857dbcf..ca5d497048779 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -12,10 +12,11 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_MACROINFO_H -#define LLVM_CLANG_MACROINFO_H +#ifndef LLVM_CLANG_LEX_MACROINFO_H +#define LLVM_CLANG_LEX_MACROINFO_H #include "clang/Lex/Token.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include <cassert> @@ -45,7 +46,7 @@ class MacroInfo { /// \see ArgumentList unsigned NumArguments; - + /// \brief This is the list of tokens that the macro is defined to. SmallVector<Token, 8> ReplacementTokens; @@ -78,8 +79,7 @@ class MacroInfo { /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__" bool HasCommaPasting : 1; - -private: + //===--------------------------------------------------------------------===// // State that changes as the macro is used. @@ -107,28 +107,11 @@ private: /// \brief Whether this macro was used as header guard. bool UsedForHeaderGuard : 1; - ~MacroInfo() { - assert(!ArgumentList && "Didn't call destroy before dtor!"); - } - -public: + // Only the Preprocessor gets to create and destroy these. MacroInfo(SourceLocation DefLoc); - - /// \brief Free the argument list of the macro. - /// - /// This restores this MacroInfo to a state where it can be reused for other - /// devious purposes. - void FreeArgumentList() { - ArgumentList = nullptr; - NumArguments = 0; - } - - /// \brief Destroy this MacroInfo object. - void Destroy() { - FreeArgumentList(); - this->~MacroInfo(); - } + ~MacroInfo() {} +public: /// \brief Return the location that the macro was defined at. SourceLocation getDefinitionLoc() const { return Location; } @@ -350,9 +333,6 @@ protected: // Used by DefMacroDirective -----------------------------------------------// - /// \brief True if this macro was imported from a module. - bool IsImported : 1; - /// \brief Whether the definition of this macro is ambiguous, due to /// multiple definitions coming in from multiple modules. bool IsAmbiguous : 1; @@ -363,11 +343,35 @@ protected: /// module). bool IsPublic : 1; - MacroDirective(Kind K, SourceLocation Loc) - : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false), - IsImported(false), IsAmbiguous(false), - IsPublic(true) { - } + // 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) + : 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); + } + } public: Kind getKind() const { return Kind(MDKind); } @@ -390,6 +394,27 @@ 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; @@ -463,23 +488,22 @@ class DefMacroDirective : public MacroDirective { public: explicit DefMacroDirective(MacroInfo *MI) - : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) { + : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) { assert(MI && "MacroInfo is null"); } - DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported) - : MacroDirective(MD_Define, Loc), Info(MI) { + DefMacroDirective(MacroInfo *MI, SourceLocation Loc, + unsigned ImportedFromModuleID = 0, + ArrayRef<unsigned> Overrides = None) + : MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides), + Info(MI) { assert(MI && "MacroInfo is null"); - IsImported = isImported; } /// \brief The data for the macro definition. const MacroInfo *getInfo() const { return Info; } MacroInfo *getInfo() { return Info; } - /// \brief True if this macro was imported from a module. - bool isImported() const { return IsImported; } - /// \brief Determine whether this macro definition is ambiguous with /// other macro definitions. bool isAmbiguous() const { return IsAmbiguous; } @@ -496,9 +520,11 @@ public: /// \brief A directive for an undefined macro. class UndefMacroDirective : public MacroDirective { public: - explicit UndefMacroDirective(SourceLocation UndefLoc) - : MacroDirective(MD_Undefine, UndefLoc) { - assert(UndefLoc.isValid() && "Invalid UndefLoc!"); + explicit UndefMacroDirective(SourceLocation UndefLoc, + unsigned ImportedFromModuleID = 0, + ArrayRef<unsigned> Overrides = None) + : MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) { + assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!"); } static bool classof(const MacroDirective *MD) { @@ -525,6 +551,13 @@ 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(); diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index 7869799c2c541..36605c9c18c6d 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -11,8 +11,8 @@ // loading named modules. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H -#define LLVM_CLANG_LEX_MODULE_LOADER_H +#ifndef LLVM_CLANG_LEX_MODULELOADER_H +#define LLVM_CLANG_LEX_MODULELOADER_H #include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index a86a927499594..ed885a7410d50 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -65,19 +65,21 @@ private: llvm::StringMap<Module *> Modules; public: - /// \brief Describes the role of a module header. + /// \brief Flags describing the role of a module header. enum ModuleHeaderRole { /// \brief This header is normally included in the module. - NormalHeader, + NormalHeader = 0x0, /// \brief This header is included but private. - PrivateHeader, - /// \brief This header is explicitly excluded from the module. - ExcludedHeader + PrivateHeader = 0x1, + /// \brief This header is part of the module (for layering purposes) but + /// should be textually included. + TextualHeader = 0x2, // Caution: Adding an enumerator needs other changes. // Adjust the number of bits for KnownHeader::Storage. // Adjust the bitfield HeaderFileInfo::HeaderRole size. // Adjust the HeaderFileInfoTrait::ReadData streaming. // Adjust the HeaderFileInfoTrait::EmitData streaming. + // Adjust ModuleMap::addHeader. }; /// \brief A header that is known to reside within a given module, @@ -96,8 +98,8 @@ public: ModuleHeaderRole getRole() const { return Storage.getInt(); } /// \brief Whether this header is available in the module. - bool isAvailable() const { - return getRole() != ExcludedHeader && getModule()->isAvailable(); + bool isAvailable() const { + return getModule()->isAvailable(); } // \brief Whether this known header is valid (i.e., it has an @@ -107,6 +109,8 @@ public: } }; + typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet; + private: typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> > HeadersMap; @@ -123,15 +127,29 @@ private: /// header. llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs; + /// \brief The set of attributes that can be attached to a module. + struct Attributes { + Attributes() : IsSystem(), IsExternC(), IsExhaustive() {} + + /// \brief Whether this is a system module. + unsigned IsSystem : 1; + + /// \brief Whether this is an extern "C" module. + unsigned IsExternC : 1; + + /// \brief Whether this is an exhaustive set of configuration macros. + unsigned IsExhaustive : 1; + }; + /// \brief A directory for which framework modules can be inferred. struct InferredDirectory { - InferredDirectory() : InferModules(), InferSystemModules() { } + InferredDirectory() : InferModules() {} /// \brief Whether to infer modules from this directory. unsigned InferModules : 1; - /// \brief Whether the modules we infer are [system] modules. - unsigned InferSystemModules : 1; + /// \brief The attributes to use for inferred modules. + Attributes Attrs; /// \brief If \c InferModules is non-zero, the module map file that allowed /// inferred modules. Otherwise, nullptr. @@ -146,6 +164,12 @@ private: /// framework modules from within those directories. llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories; + /// A mapping from an inferred module to the module map that allowed the + /// inference. + llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy; + + llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps; + /// \brief Describes whether we haved parsed a particular file as a module /// map. llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap; @@ -204,6 +228,10 @@ private: return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs)); } + Module *inferFrameworkModule(StringRef ModuleName, + const DirectoryEntry *FrameworkDir, + Attributes Attrs, Module *Parent); + public: /// \brief Construct a new module map. /// @@ -241,11 +269,16 @@ public: /// used from. Used to disambiguate if a header is present in multiple /// modules. /// + /// \param IncludeTextualHeaders If \c true, also find textual headers. By + /// default, these are treated like excluded headers and result in no known + /// header being found. + /// /// \returns The module KnownHeader, which provides the module that owns the /// given header file. The KnownHeader is default constructed to indicate /// that no module owns this header file. KnownHeader findModuleForHeader(const FileEntry *File, - Module *RequestingModule = nullptr); + Module *RequestingModule = nullptr, + bool IncludeTextualHeaders = false); /// \brief Reports errors if a module must not include a specific file. /// @@ -306,9 +339,6 @@ public: /// \param Parent The module that will act as the parent of this submodule, /// or NULL to indicate that this is a top-level module. /// - /// \param ModuleMap The module map that defines or allows the inference of - /// this module. - /// /// \param IsFramework Whether this is a framework module. /// /// \param IsExplicit Whether this is an explicit submodule. @@ -316,26 +346,9 @@ public: /// \returns The found or newly-created module, along with a boolean value /// that will be true if the module is newly-created. std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, - const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit); - /// \brief Determine whether we can infer a framework module a framework - /// with the given name in the given - /// - /// \param ParentDir The directory that is the parent of the framework - /// directory. - /// - /// \param Name The name of the module. - /// - /// \param IsSystem Will be set to 'true' if the inferred module must be a - /// system module. - /// - /// \returns true if we are allowed to infer a framework module, and false - /// otherwise. - bool canInferFrameworkModule(const DirectoryEntry *ParentDir, - StringRef Name, bool &IsSystem) const; - /// \brief Infer the contents of a framework module map from the given /// framework directory. Module *inferFrameworkModule(StringRef ModuleName, @@ -349,7 +362,35 @@ public: /// /// \returns The file entry for the module map file containing the given /// module, or NULL if the module definition was inferred. - const FileEntry *getContainingModuleMapFile(Module *Module) const; + const FileEntry *getContainingModuleMapFile(const Module *Module) const; + + /// \brief Get the module map file that (along with the module name) uniquely + /// identifies this module. + /// + /// The particular module that \c Name refers to may depend on how the module + /// was found in header search. However, the combination of \c Name and + /// this module map will be globally unique for top-level modules. In the case + /// of inferred modules, returns the module map that allowed the inference + /// (e.g. contained 'module *'). Otherwise, returns + /// getContainingModuleMapFile(). + const FileEntry *getModuleMapFileForUniquing(const Module *M) const; + + void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap); + + /// \brief Get any module map files other than getModuleMapFileForUniquing(M) + /// that define submodules of a top-level module \p M. This is cheaper than + /// getting the module map file for each submodule individually, since the + /// expected number of results is very small. + AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) { + auto I = AdditionalModMaps.find(M); + if (I == AdditionalModMaps.end()) + return nullptr; + return &I->second; + } + + void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap) { + AdditionalModMaps[M].insert(ModuleMap); + } /// \brief Resolve all of the unresolved exports in the given module. /// @@ -401,9 +442,12 @@ public: /// \brief Adds this header to the given module. /// \param Role The role of the header wrt the module. - void addHeader(Module *Mod, const FileEntry *Header, + void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role); + /// \brief Marks this header as being excluded from the given module. + void excludeHeader(Module *Mod, Module::Header Header); + /// \brief Parse the given module map file, and record any modules we /// encounter. /// @@ -412,8 +456,12 @@ public: /// \param IsSystem Whether this module map file is in a system header /// directory, and therefore should be considered a system module. /// + /// \param HomeDir The directory in which relative paths within this module + /// map file will be resolved. + /// /// \returns true if an error occurred, false otherwise. - bool parseModuleMapFile(const FileEntry *File, bool IsSystem); + bool parseModuleMapFile(const FileEntry *File, bool IsSystem, + const DirectoryEntry *HomeDir); /// \brief Dump the contents of the module map, for debugging purposes. void dump(); diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h index e3c6de555b358..83e6f99078dfd 100644 --- a/include/clang/Lex/MultipleIncludeOpt.h +++ b/include/clang/Lex/MultipleIncludeOpt.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H -#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H +#ifndef LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H +#define LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H #include "clang/Basic/SourceLocation.h" diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 7f1ea34a460ea..056c58aa33488 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -322,15 +322,12 @@ public: /// \brief Simple wrapper class for chaining callbacks. class PPChainedCallbacks : public PPCallbacks { virtual void anchor(); - PPCallbacks *First, *Second; + std::unique_ptr<PPCallbacks> First, Second; public: - PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second) - : First(_First), Second(_Second) {} - ~PPChainedCallbacks() { - delete Second; - delete First; - } + PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First, + std::unique_ptr<PPCallbacks> _Second) + : First(std::move(_First)), Second(std::move(_Second)) {} void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h index 2352ccea1853e..54c91f6b0860c 100644 --- a/include/clang/Lex/PTHLexer.h +++ b/include/clang/Lex/PTHLexer.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_PTHLEXER_H -#define LLVM_CLANG_PTHLEXER_H +#ifndef LLVM_CLANG_LEX_PTHLEXER_H +#define LLVM_CLANG_LEX_PTHLEXER_H #include "clang/Lex/PreprocessorLexer.h" diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h index 11b5ceaad1dec..64ecf5f575f30 100644 --- a/include/clang/Lex/PTHManager.h +++ b/include/clang/Lex/PTHManager.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_PTHMANAGER_H -#define LLVM_CLANG_PTHMANAGER_H +#ifndef LLVM_CLANG_LEX_PTHMANAGER_H +#define LLVM_CLANG_LEX_PTHMANAGER_H #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" @@ -20,6 +20,7 @@ #include "clang/Lex/PTHLexer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/OnDiskHashTable.h" #include <string> namespace llvm { @@ -36,19 +37,26 @@ class FileSystemStatCache; class PTHManager : public IdentifierInfoLookup { friend class PTHLexer; + friend class PTHStatCache; + + class PTHStringLookupTrait; + class PTHFileLookupTrait; + typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup; + typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup; + /// The memory mapped PTH file. - const llvm::MemoryBuffer* Buf; + std::unique_ptr<const llvm::MemoryBuffer> Buf; /// Alloc - Allocator used for IdentifierInfo objects. llvm::BumpPtrAllocator Alloc; /// IdMap - A lazily generated cache mapping from persistent identifiers to /// IdentifierInfo*. - IdentifierInfo** PerIDCache; + std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> PerIDCache; /// FileLookup - Abstract data structure used for mapping between files /// and token data in the PTH file. - void* FileLookup; + std::unique_ptr<PTHFileLookup> FileLookup; /// IdDataTable - Array representing the mapping from persistent IDs to the /// data offset within the PTH file containing the information to @@ -57,7 +65,7 @@ class PTHManager : public IdentifierInfoLookup { /// SortedIdTable - Abstract data structure mapping from strings to /// persistent IDs. This is used by get(). - void* StringIdLookup; + std::unique_ptr<PTHStringIdLookup> StringIdLookup; /// NumIds - The number of identifiers in the PTH file. const unsigned NumIds; @@ -76,10 +84,12 @@ class PTHManager : public IdentifierInfoLookup { /// This constructor is intended to only be called by the static 'Create' /// method. - PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup, - const unsigned char* idDataTable, IdentifierInfo** perIDCache, - void* stringIdLookup, unsigned numIds, - const unsigned char* spellingBase, const char *originalSourceFile); + PTHManager(std::unique_ptr<const llvm::MemoryBuffer> buf, + std::unique_ptr<PTHFileLookup> fileLookup, + const unsigned char *idDataTable, + std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> perIDCache, + 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; @@ -131,7 +141,7 @@ public: /// FileManager objects. These objects use the PTH data to speed up /// calls to stat by memoizing their results from when the PTH file /// was generated. - FileSystemStatCache *createStatCache(); + std::unique_ptr<FileSystemStatCache> createStatCache(); }; } // end namespace clang diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h index 4a695a0e901cf..4123bae2ea3af 100644 --- a/include/clang/Lex/Pragma.h +++ b/include/clang/Lex/Pragma.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_PRAGMA_H -#define LLVM_CLANG_PRAGMA_H +#ifndef LLVM_CLANG_LEX_PRAGMA_H +#define LLVM_CLANG_LEX_PRAGMA_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index d4b4ba246961b..326f519e914e1 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -79,6 +79,13 @@ public: } }; +/// \brief Context in which macro name is used. +enum MacroUse { + MU_Other = 0, // other than #define or #undef + MU_Define = 1, // macro name specified in #define + MU_Undef = 2 // macro name specified in #undef +}; + /// \brief Engages in a tight little dance with the lexer to efficiently /// preprocess tokens. /// @@ -92,7 +99,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { const TargetInfo *Target; FileManager &FileMgr; SourceManager &SourceMgr; - ScratchBuffer *ScratchBuf; + std::unique_ptr<ScratchBuffer> ScratchBuf; HeaderSearch &HeaderInfo; ModuleLoader &TheModuleLoader; @@ -128,6 +135,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> { IdentifierInfo *Ident__is_identifier; // __is_identifier IdentifierInfo *Ident__building_module; // __building_module IdentifierInfo *Ident__MODULE__; // __MODULE__ + IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute + IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute SourceLocation DATELoc, TIMELoc; unsigned CounterValue; // Next __COUNTER__ value. @@ -192,7 +201,11 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief Tracks all of the pragmas that the client registered /// with this preprocessor. - PragmaNamespace *PragmaHandlers; + std::unique_ptr<PragmaNamespace> PragmaHandlers; + + /// \brief Pragma handlers of the original source is stored here during the + /// parsing of a model file. + std::unique_ptr<PragmaNamespace> PragmaHandlersBackup; /// \brief Tracks all of the comment handlers that the client registered /// with this preprocessor. @@ -245,12 +258,17 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief True if we hit the code-completion point. bool CodeCompletionReached; + /// \brief The directory that the main file should be considered to occupy, + /// if it does not correspond to a real file (as happens when building a + /// module). + const DirectoryEntry *MainFileDir; + /// \brief The number of bytes that we will initially skip when entering the /// main file, along with a flag that indicates whether skipping this number /// of bytes will place the lexer at the start of a line. /// /// This is used when loading a precompiled preamble. - std::pair<unsigned, bool> SkipMainFilePreamble; + std::pair<int, bool> SkipMainFilePreamble; /// \brief The current top of the stack that we're lexing from if /// not expanding a macro and we are lexing directly from source code. @@ -334,7 +352,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief Actions invoked when some preprocessor activity is /// encountered (e.g. a file is \#included, etc). - PPCallbacks *Callbacks; + std::unique_ptr<PPCallbacks> Callbacks; struct MacroExpandsInfo { Token Tok; @@ -391,7 +409,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief Cache of macro expanders to reduce malloc traffic. enum { TokenLexerCacheSize = 8 }; unsigned NumCachedTokenLexers; - TokenLexer *TokenLexerCache[TokenLexerCacheSize]; + std::unique_ptr<TokenLexer> TokenLexerCache[TokenLexerCacheSize]; /// \} /// \brief Keeps macro expanded tokens for TokenLexers. @@ -433,17 +451,12 @@ private: // Cached tokens state. struct MacroInfoChain { MacroInfo MI; MacroInfoChain *Next; - MacroInfoChain *Prev; }; /// MacroInfos are managed as a chain for easy disposal. This is the head /// of that list. MacroInfoChain *MIChainHead; - /// A "freelist" of MacroInfo objects that can be reused for quick - /// allocation. - MacroInfoChain *MICache; - struct DeserializedMacroInfoChain { MacroInfo MI; unsigned OwningModuleID; // MUST be immediately after the MacroInfo object @@ -469,6 +482,17 @@ public: /// lifetime of the preprocessor. void Initialize(const TargetInfo &Target); + /// \brief Initialize the preprocessor to parse a model file + /// + /// To parse model files the preprocessor of the original source is reused to + /// preserver the identifier table. However to avoid some duplicate + /// information in the preprocessor some cleanup is needed before it is used + /// to parse model files. This method does that cleanup. + void InitializeForModelFile(); + + /// \brief Cleanup after model file parsing + void FinalizeForModelFile(); + /// \brief Retrieve the preprocessor options used to initialize this /// preprocessor. PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; } @@ -557,6 +581,9 @@ public: /// expansions going on at the time. PreprocessorLexer *getCurrentFileLexer() const; + /// \brief Return the submodule owning the file being lexed. + Module *getCurrentSubmodule() const { return CurSubmodule; } + /// \brief Returns the FileID for the preprocessor predefines. FileID getPredefinesFileID() const { return PredefinesFileID; } @@ -565,11 +592,12 @@ public: /// /// Note that this class takes ownership of any PPCallbacks object given to /// it. - PPCallbacks *getPPCallbacks() const { return Callbacks; } - void addPPCallbacks(PPCallbacks *C) { + PPCallbacks *getPPCallbacks() const { return Callbacks.get(); } + void addPPCallbacks(std::unique_ptr<PPCallbacks> C) { if (Callbacks) - C = new PPChainedCallbacks(C, Callbacks); - Callbacks = C; + C = llvm::make_unique<PPChainedCallbacks>(std::move(C), + std::move(Callbacks)); + Callbacks = std::move(C); } /// \} @@ -605,13 +633,15 @@ public: void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD); DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc, - bool isImported) { - DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported); + unsigned ImportedFromModuleID, + ArrayRef<unsigned> Overrides) { + DefMacroDirective *MD = + AllocateDefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides); appendMacroDirective(II, MD); return MD; } DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){ - return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false); + return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), 0, None); } /// \brief Set a MacroDirective that was loaded from a PCH file. void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD); @@ -990,6 +1020,12 @@ public: PragmaARCCFCodeAuditedLoc = Loc; } + /// \brief Set the directory in which the main file should be considered + /// to have been found, if it is not a real file. + void setMainFileDir(const DirectoryEntry *Dir) { + MainFileDir = Dir; + } + /// \brief Instruct the preprocessor to skip part of the main source file. /// /// \param Bytes The number of bytes in the preamble to skip. @@ -1307,6 +1343,7 @@ public: /// reference is for system \#include's or not (i.e. using <> instead of ""). const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, + const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, @@ -1343,11 +1380,13 @@ public: /// followed by EOD. Return true if the token is not a valid on-off-switch. bool LexOnOffSwitch(tok::OnOffSwitch &OOS); - bool CheckMacroName(Token &MacroNameTok, char isDefineUndef); + bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, + bool *ShadowFlag = nullptr); private: void PushIncludeMacroStack() { + assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer"); IncludeMacroStack.push_back(IncludeStackInfo( CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer), CurPPLexer, std::move(CurTokenLexer), CurDirLookup)); @@ -1370,24 +1409,29 @@ private: /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); - DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI, - SourceLocation Loc, - bool isImported); - UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc); + DefMacroDirective * + AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, + unsigned ImportedFromModuleID = 0, + ArrayRef<unsigned> Overrides = None); + UndefMacroDirective * + AllocateUndefMacroDirective(SourceLocation UndefLoc, + unsigned ImportedFromModuleID = 0, + ArrayRef<unsigned> Overrides = None); VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc, bool isPublic); - /// \brief Release the specified MacroInfo for re-use. - /// - /// This memory will be reused for allocating new MacroInfo objects. - void ReleaseMacroInfo(MacroInfo* MI); - /// \brief Lex and validate a macro name, which occurs after a - /// \#define or \#undef. + /// \#define or \#undef. + /// + /// \param MacroNameTok Token that represents the name defined or undefined. + /// \param IsDefineUndef Kind if preprocessor directive. + /// \param ShadowFlag Points to flag that is set if macro name shadows + /// a keyword. /// /// This emits a diagnostic, sets the token kind to eod, /// and discards the rest of the macro line if the macro name is invalid. - void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0); + void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other, + bool *ShadowFlag = nullptr); /// The ( starting an argument list of a macro definition has just been read. /// Lex the rest of the arguments and the closing ), updating \p MI with @@ -1521,6 +1565,7 @@ private: void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok, const DirectoryLookup *LookupFrom = nullptr, + const FileEntry *LookupFromFile = nullptr, bool isImport = false); void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok); void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok); diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h index ed226ae9a3f66..3a91fa72f2e55 100644 --- a/include/clang/Lex/PreprocessorLexer.h +++ b/include/clang/Lex/PreprocessorLexer.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_PreprocessorLexer_H -#define LLVM_CLANG_PreprocessorLexer_H +#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H +#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H #include "clang/Lex/MultipleIncludeOpt.h" #include "clang/Lex/Token.h" diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h index f03515ffc1428..a3d6096821e7d 100644 --- a/include/clang/Lex/ScratchBuffer.h +++ b/include/clang/Lex/ScratchBuffer.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SCRATCHBUFFER_H -#define LLVM_CLANG_SCRATCHBUFFER_H +#ifndef LLVM_CLANG_LEX_SCRATCHBUFFER_H +#define LLVM_CLANG_LEX_SCRATCHBUFFER_H #include "clang/Basic/SourceLocation.h" diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index c8b77d11747ea..4a53c9c1bb190 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOKEN_H -#define LLVM_CLANG_TOKEN_H +#ifndef LLVM_CLANG_LEX_TOKEN_H +#define LLVM_CLANG_LEX_TOKEN_H #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" @@ -58,6 +58,8 @@ class Token { /// may be dirty (have trigraphs / escaped newlines). /// Annotations (resolved type names, C++ scopes, etc): isAnnotation(). /// This is a pointer to sema-specific data for the annotation token. + /// Eof: + // This is a pointer to a Decl. /// Other: /// This is null. void *PtrData; @@ -66,7 +68,7 @@ class Token { tok::TokenKind Kind; /// Flags - Bits we track about this token, members of the TokenFlags enum. - unsigned char Flags; + unsigned short Flags; public: // Various flags set per token: @@ -80,7 +82,9 @@ public: LeadingEmptyMacro = 0x10, // Empty macro exists before this token. HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. HasUCN = 0x40, // This identifier contains a UCN. - IgnoredComma = 0x80 // This comma is not a macro argument separator (MS). + IgnoredComma = 0x80, // This comma is not a macro argument separator (MS). + StringifiedInMacro = 0x100, // This string or character literal is formed by + // macro stringizing or charizing operator. }; tok::TokenKind getKind() const { return Kind; } @@ -162,12 +166,23 @@ public: assert(!isAnnotation() && "getIdentifierInfo() on an annotation token!"); if (isLiteral()) return nullptr; + if (is(tok::eof)) return nullptr; return (IdentifierInfo*) PtrData; } void setIdentifierInfo(IdentifierInfo *II) { PtrData = (void*) II; } + const void *getEofData() const { + assert(is(tok::eof)); + return reinterpret_cast<const void *>(PtrData); + } + void setEofData(const void *D) { + assert(is(tok::eof)); + assert(!PtrData); + PtrData = const_cast<void *>(D); + } + /// getRawIdentifier - For a raw identifier token (i.e., an identifier /// lexed in raw mode), returns a reference to the text substring in the /// buffer if known. @@ -262,6 +277,12 @@ public: /// Returns true if this token contains a universal character name. bool hasUCN() const { return (Flags & HasUCN) ? true : false; } + + /// Returns true if this token is formed by macro by stringizing or charizing + /// operator. + bool stringifiedInMacro() const { + return (Flags & StringifiedInMacro) ? true : false; + } }; /// \brief Information about the conditional stack (\#if directives) diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h index 551300f402c2e..a2d98b0d473a3 100644 --- a/include/clang/Lex/TokenConcatenation.h +++ b/include/clang/Lex/TokenConcatenation.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_LEX_TOKEN_CONCATENATION_H -#define CLANG_LEX_TOKEN_CONCATENATION_H +#ifndef LLVM_CLANG_LEX_TOKENCONCATENATION_H +#define LLVM_CLANG_LEX_TOKENCONCATENATION_H #include "clang/Basic/TokenKinds.h" diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index a873a2e275089..306f98e2609a7 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOKENLEXER_H -#define LLVM_CLANG_TOKENLEXER_H +#ifndef LLVM_CLANG_LEX_TOKENLEXER_H +#define LLVM_CLANG_LEX_TOKENLEXER_H #include "clang/Basic/SourceLocation.h" |