diff options
Diffstat (limited to 'include/clang/Lex')
27 files changed, 0 insertions, 8255 deletions
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h deleted file mode 100644 index 91c3b78..0000000 --- a/include/clang/Lex/CodeCompletionHandler.h +++ /dev/null @@ -1,71 +0,0 @@ -//===--- CodeCompletionHandler.h - Preprocessor code completion -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the CodeCompletionHandler interface, which provides -// code-completion callbacks for the preprocessor. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H -#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H - -namespace clang { - -class IdentifierInfo; -class MacroInfo; - -/// \brief Callback handler that receives notifications when performing code -/// completion within the preprocessor. -class CodeCompletionHandler { -public: - virtual ~CodeCompletionHandler(); - - /// \brief Callback invoked when performing code completion for a preprocessor - /// directive. - /// - /// This callback will be invoked when the preprocessor processes a '#' at the - /// start of a line, followed by the code-completion token. - /// - /// \param InConditional Whether we're inside a preprocessor conditional - /// already. - virtual void CodeCompleteDirective(bool InConditional) { } - - /// \brief Callback invoked when performing code completion within a block of - /// code that was excluded due to preprocessor conditionals. - virtual void CodeCompleteInConditionalExclusion() { } - - /// \brief Callback invoked when performing code completion in a context - /// where the name of a macro is expected. - /// - /// \param IsDefinition Whether this is the definition of a macro, e.g., - /// in a \#define. - virtual void CodeCompleteMacroName(bool IsDefinition) { } - - /// \brief Callback invoked when performing code completion in a preprocessor - /// expression, such as the condition of an \#if or \#elif directive. - virtual void CodeCompletePreprocessorExpression() { } - - /// \brief Callback invoked when performing code completion inside a - /// function-like macro argument. - /// - /// There will be another callback invocation after the macro arguments are - /// parsed, so this callback should generally be used to note that the next - /// callback is invoked inside a macro argument. - virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro, - MacroInfo *MacroInfo, - unsigned ArgumentIndex) { } - - /// \brief Callback invoked when performing code completion in a part of the - /// file where we expect natural language, e.g., a comment, string, or - /// \#error directive. - virtual void CodeCompleteNaturalLanguage() { } -}; - -} - -#endif // LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h deleted file mode 100644 index 20c4bb0..0000000 --- a/include/clang/Lex/DirectoryLookup.h +++ /dev/null @@ -1,196 +0,0 @@ -//===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the DirectoryLookup interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H -#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H - -#include "clang/Basic/LLVM.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/ModuleMap.h" - -namespace clang { -class HeaderMap; -class DirectoryEntry; -class FileEntry; -class HeaderSearch; -class Module; - -/// DirectoryLookup - This class represents one entry in the search list that -/// specifies the search order for directories in \#include directives. It -/// represents either a directory, a framework, or a headermap. -/// -class DirectoryLookup { -public: - enum LookupType_t { - LT_NormalDir, - LT_Framework, - LT_HeaderMap - }; -private: - union { // This union is discriminated by isHeaderMap. - /// Dir - This is the actual directory that we're referring to for a normal - /// directory or a framework. - const DirectoryEntry *Dir; - - /// Map - This is the HeaderMap if this is a headermap lookup. - /// - const HeaderMap *Map; - } u; - - /// DirCharacteristic - The type of directory this is: this is an instance of - /// SrcMgr::CharacteristicKind. - unsigned DirCharacteristic : 2; - - /// LookupType - This indicates whether this DirectoryLookup object is a - /// normal directory, a framework, or a headermap. - unsigned LookupType : 2; - - /// \brief Whether this is a header map used when building a framework. - unsigned IsIndexHeaderMap : 1; - - /// \brief Whether we've performed an exhaustive search for module maps - /// within the subdirectories of this directory. - unsigned SearchedAllModuleMaps : 1; - -public: - /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of - /// 'dir'. - DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT, - bool isFramework) - : DirCharacteristic(DT), - LookupType(isFramework ? LT_Framework : LT_NormalDir), - IsIndexHeaderMap(false), SearchedAllModuleMaps(false) { - u.Dir = dir; - } - - /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of - /// 'map'. - DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT, - bool isIndexHeaderMap) - : DirCharacteristic(DT), LookupType(LT_HeaderMap), - IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) { - u.Map = map; - } - - /// getLookupType - Return the kind of directory lookup that this is: either a - /// normal directory, a framework path, or a HeaderMap. - LookupType_t getLookupType() const { return (LookupType_t)LookupType; } - - /// getName - Return the directory or filename corresponding to this lookup - /// object. - const char *getName() const; - - /// getDir - Return the directory that this entry refers to. - /// - const DirectoryEntry *getDir() const { - return isNormalDir() ? u.Dir : nullptr; - } - - /// getFrameworkDir - Return the directory that this framework refers to. - /// - const DirectoryEntry *getFrameworkDir() const { - return isFramework() ? u.Dir : nullptr; - } - - /// getHeaderMap - Return the directory that this entry refers to. - /// - const HeaderMap *getHeaderMap() const { - return isHeaderMap() ? u.Map : nullptr; - } - - /// isNormalDir - Return true if this is a normal directory, not a header map. - bool isNormalDir() const { return getLookupType() == LT_NormalDir; } - - /// isFramework - True if this is a framework directory. - /// - bool isFramework() const { return getLookupType() == LT_Framework; } - - /// isHeaderMap - Return true if this is a header map, not a normal directory. - bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; } - - /// \brief Determine whether we have already searched this entire - /// directory for module maps. - bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; } - - /// \brief Specify whether we have already searched all of the subdirectories - /// for module maps. - void setSearchedAllModuleMaps(bool SAMM) { - SearchedAllModuleMaps = SAMM; - } - - /// DirCharacteristic - The type of directory this is, one of the DirType enum - /// values. - SrcMgr::CharacteristicKind getDirCharacteristic() const { - return (SrcMgr::CharacteristicKind)DirCharacteristic; - } - - /// \brief Whether this describes a system header directory. - bool isSystemHeaderDirectory() const { - return getDirCharacteristic() != SrcMgr::C_User; - } - - /// \brief Whether this header map is building a framework or not. - bool isIndexHeaderMap() const { - return isHeaderMap() && IsIndexHeaderMap; - } - - /// LookupFile - Lookup the specified file in this search path, returning it - /// if it exists or returning null if not. - /// - /// \param Filename The file to look up relative to the search paths. - /// - /// \param HS The header search instance to search with. - /// - /// \param SearchPath If not NULL, will be set to the search path relative - /// to which the file was found. - /// - /// \param RelativePath If not NULL, will be set to the path relative to - /// SearchPath at which the file was found. This only differs from the - /// Filename for framework includes. - /// - /// \param RequestingModule The module in which the lookup was performed. - /// - /// \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. - /// - /// \param [out] InUserSpecifiedSystemFramework If the file is found, - /// set to true if the file is located in a framework that has been - /// user-specified to be treated as a system framework. - /// - /// \param [out] MappedName if this is a headermap which maps the filename to - /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this - /// vector and point Filename to it. - const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS, - SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, - Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, - bool &InUserSpecifiedSystemFramework, - bool &HasBeenMapped, - SmallVectorImpl<char> &MappedName) const; - -private: - const FileEntry *DoFrameworkLookup( - StringRef Filename, HeaderSearch &HS, - SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, - Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, - bool &InUserSpecifiedSystemHeader) const; - -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h deleted file mode 100644 index adf8e71..0000000 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ /dev/null @@ -1,48 +0,0 @@ -//===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ExternalPreprocessorSource interface, which enables -// construction of macro definitions from some external source. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H -#define LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H - -namespace clang { - -class IdentifierInfo; -class Module; - -/// \brief Abstract interface for external sources of preprocessor -/// information. -/// -/// This abstract class allows an external sources (such as the \c ASTReader) -/// to provide additional preprocessing information. -class ExternalPreprocessorSource { -public: - virtual ~ExternalPreprocessorSource(); - - /// \brief Read the set of macros defined by this external macro source. - virtual void ReadDefinedMacros() = 0; - - /// \brief Update an out-of-date identifier. - virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0; - - /// \brief Return the identifier associated with the given ID number. - /// - /// The ID 0 is associated with the NULL identifier. - virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0; - - /// \brief Map a module ID to a module. - virtual Module *getModule(unsigned ModuleID) = 0; -}; - -} - -#endif diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h deleted file mode 100644 index 183361e..0000000 --- a/include/clang/Lex/HeaderMap.h +++ /dev/null @@ -1,76 +0,0 @@ -//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the HeaderMap interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_HEADERMAP_H -#define LLVM_CLANG_LEX_HEADERMAP_H - -#include "clang/Basic/LLVM.h" -#include "llvm/Support/Compiler.h" -#include <memory> - -namespace llvm { - class MemoryBuffer; -} -namespace clang { - class FileEntry; - class FileManager; - struct HMapBucket; - struct HMapHeader; - -/// This class represents an Apple concept known as a 'header map'. To the -/// \#include file resolution process, it basically acts like a directory of -/// 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 &) = delete; - void operator=(const HeaderMap &) = delete; - - std::unique_ptr<const llvm::MemoryBuffer> FileBuffer; - bool NeedsBSwap; - - HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap) - : FileBuffer(std::move(File)), NeedsBSwap(BSwap) {} -public: - /// 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); - - /// LookupFile - Check to see if the specified relative filename is located in - /// this HeaderMap. If so, open it and return its FileEntry. - /// If RawPath is not NULL and the file is found, RawPath will be set to the - /// raw path at which the file was found in the file system. For example, - /// for a search path ".." and a filename "../file.h" this would be - /// "../../file.h". - const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const; - - /// If the specified relative filename is located in this HeaderMap return - /// the filename it is mapped to, otherwise return an empty StringRef. - StringRef lookupFilename(StringRef Filename, - SmallVectorImpl<char> &DestPath) const; - - /// getFileName - Return the filename of the headermap. - const char *getFileName() const; - - /// dump - Print the contents of this headermap to stderr. - void dump() const; - -private: - unsigned getEndianAdjustedWord(unsigned X) const; - const HMapHeader &getHeader() const; - HMapBucket getBucket(unsigned BucketNo) const; - const char *getString(unsigned StrTabIdx) const; -}; - -} // end namespace clang. - -#endif diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h deleted file mode 100644 index 6d592e1..0000000 --- a/include/clang/Lex/HeaderSearch.h +++ /dev/null @@ -1,688 +0,0 @@ -//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the HeaderSearch interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H -#define LLVM_CLANG_LEX_HEADERSEARCH_H - -#include "clang/Lex/DirectoryLookup.h" -#include "clang/Lex/ModuleMap.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Allocator.h" -#include <memory> -#include <vector> - -namespace clang { - -class DiagnosticsEngine; -class ExternalPreprocessorSource; -class FileEntry; -class FileManager; -class HeaderSearchOptions; -class IdentifierInfo; -class Preprocessor; - -/// \brief The preprocessor keeps track of this information for each -/// file that is \#included. -struct HeaderFileInfo { - /// \brief True if this is a \#import'd or \#pragma once file. - unsigned isImport : 1; - - /// \brief True if this is a \#pragma once file. - unsigned isPragmaOnce : 1; - - /// DirInfo - Keep track of whether this is a system header, and if so, - /// whether it is C++ clean or not. This can be set by the include paths or - /// by \#pragma gcc system_header. This is an instance of - /// SrcMgr::CharacteristicKind. - unsigned DirInfo : 2; - - /// \brief Whether this header file info was supplied by an external source, - /// and has not changed since. - unsigned External : 1; - - /// \brief Whether this header is part of a module. - unsigned isModuleHeader : 1; - - /// \brief Whether this header is part of the module that we are building. - unsigned isCompilingModuleHeader : 1; - - /// \brief Whether this structure is considered to already have been - /// "resolved", meaning that it was loaded from the external source. - unsigned Resolved : 1; - - /// \brief Whether this is a header inside a framework that is currently - /// being built. - /// - /// When a framework is being built, the headers have not yet been placed - /// into the appropriate framework subdirectories, and therefore are - /// provided via a header map. This bit indicates when this is one of - /// those framework headers. - unsigned IndexHeaderMapHeader : 1; - - /// \brief Whether this file has been looked up as a header. - unsigned IsValid : 1; - - /// \brief The number of times the file has been included already. - unsigned short NumIncludes; - - /// \brief The ID number of the controlling macro. - /// - /// This ID number will be non-zero when there is a controlling - /// macro whose IdentifierInfo may not yet have been loaded from - /// external storage. - unsigned ControllingMacroID; - - /// If this file has a \#ifndef XXX (or equivalent) guard that - /// protects the entire contents of the file, this is the identifier - /// for the macro that controls whether or not it has any effect. - /// - /// Note: Most clients should use getControllingMacro() to access - /// the controlling macro of this header, since - /// getControllingMacro() is able to load a controlling macro from - /// external storage. - const IdentifierInfo *ControllingMacro; - - /// \brief If this header came from a framework include, this is the name - /// of the framework. - StringRef Framework; - - HeaderFileInfo() - : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), - External(false), isModuleHeader(false), isCompilingModuleHeader(false), - Resolved(false), IndexHeaderMapHeader(false), IsValid(0), - NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr) {} - - /// \brief Retrieve the controlling macro for this header file, if - /// any. - const IdentifierInfo * - getControllingMacro(ExternalPreprocessorSource *External); - - /// \brief Determine whether this is a non-default header file info, e.g., - /// it corresponds to an actual header we've included or tried to include. - bool isNonDefault() const { - return isImport || isPragmaOnce || NumIncludes || ControllingMacro || - ControllingMacroID; - } -}; - -/// \brief An external source of header file information, which may supply -/// information about header files already included. -class ExternalHeaderFileInfoSource { -public: - virtual ~ExternalHeaderFileInfoSource(); - - /// \brief Retrieve the header file information for the given file entry. - /// - /// \returns Header file information for the given file entry, with the - /// \c External bit set. If the file entry is not known, return a - /// default-constructed \c HeaderFileInfo. - virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0; -}; - -/// \brief Encapsulates the information needed to find the file referenced -/// by a \#include or \#include_next, (sub-)framework lookup, etc. -class HeaderSearch { - /// This structure is used to record entries in our framework cache. - struct FrameworkCacheEntry { - /// The directory entry which should be used for the cached framework. - const DirectoryEntry *Directory; - - /// Whether this framework has been "user-specified" to be treated as if it - /// were a system framework (even if it was found outside a system framework - /// directory). - bool IsUserSpecifiedSystemFramework; - }; - - /// \brief Header-search options used to initialize this header search. - IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts; - - DiagnosticsEngine &Diags; - FileManager &FileMgr; - /// \#include search path information. Requests for \#include "x" search the - /// directory of the \#including file first, then each directory in SearchDirs - /// consecutively. Requests for <x> search the current dir first, then each - /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If - /// NoCurDirSearch is true, then the check for the file in the current - /// directory is suppressed. - std::vector<DirectoryLookup> SearchDirs; - unsigned AngledDirIdx; - unsigned SystemDirIdx; - bool NoCurDirSearch; - - /// \brief \#include prefixes for which the 'system header' property is - /// overridden. - /// - /// For a \#include "x" or \#include \<x> directive, the last string in this - /// list which is a prefix of 'x' determines whether the file is treated as - /// a system header. - std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes; - - /// \brief The path to the module cache. - std::string ModuleCachePath; - - /// \brief All of the preprocessor-specific data about files that are - /// included, indexed by the FileEntry's UID. - mutable std::vector<HeaderFileInfo> FileInfo; - - /// Keeps track of each lookup performed by LookupFile. - struct LookupFileCacheInfo { - /// Starting index in SearchDirs that the cached search was performed from. - /// If there is a hit and this value doesn't match the current query, the - /// cache has to be ignored. - unsigned StartIdx; - /// The entry in SearchDirs that satisfied the query. - unsigned HitIdx; - /// This is non-null if the original filename was mapped to a framework - /// include via a headermap. - const char *MappedName; - - /// Default constructor -- Initialize all members with zero. - LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {} - - void reset(unsigned StartIdx) { - this->StartIdx = StartIdx; - this->MappedName = nullptr; - } - }; - llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache; - - /// \brief Collection mapping a framework or subframework - /// name like "Carbon" to the Carbon.framework directory. - llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap; - - /// IncludeAliases - maps include file names (including the quotes or - /// angle brackets) to other include file names. This is used to support the - /// include_alias pragma for Microsoft compatibility. - typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator> - IncludeAliasMap; - std::unique_ptr<IncludeAliasMap> IncludeAliases; - - /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing - /// headermaps. This vector owns the headermap. - std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps; - - /// \brief The mapping between modules and headers. - mutable ModuleMap ModMap; - - /// \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; - - /// \brief Entity used to resolve the identifier IDs of controlling - /// macros into IdentifierInfo pointers, and keep the identifire up to date, - /// as needed. - ExternalPreprocessorSource *ExternalLookup; - - /// \brief Entity used to look up stored header file information. - ExternalHeaderFileInfoSource *ExternalSource; - - // Various statistics we track for performance analysis. - unsigned NumIncluded; - unsigned NumMultiIncludeFileOptzn; - unsigned NumFrameworkLookups, NumSubFrameworkLookups; - - const LangOptions &LangOpts; - - // HeaderSearch doesn't support default or copy construction. - HeaderSearch(const HeaderSearch&) = delete; - void operator=(const HeaderSearch&) = delete; - - friend class DirectoryLookup; - -public: - HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, - SourceManager &SourceMgr, DiagnosticsEngine &Diags, - const LangOptions &LangOpts, const TargetInfo *Target); - ~HeaderSearch(); - - /// \brief Retrieve the header-search options with which this header search - /// was initialized. - HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; } - - FileManager &getFileMgr() const { return FileMgr; } - - /// \brief Interface for setting the file search paths. - void SetSearchPaths(const std::vector<DirectoryLookup> &dirs, - unsigned angledDirIdx, unsigned systemDirIdx, - bool noCurDirSearch) { - assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && - "Directory indicies are unordered"); - SearchDirs = dirs; - AngledDirIdx = angledDirIdx; - SystemDirIdx = systemDirIdx; - NoCurDirSearch = noCurDirSearch; - //LookupFileCache.clear(); - } - - /// \brief Add an additional search path. - void AddSearchPath(const DirectoryLookup &dir, bool isAngled) { - unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx; - SearchDirs.insert(SearchDirs.begin() + idx, dir); - if (!isAngled) - AngledDirIdx++; - SystemDirIdx++; - } - - /// \brief Set the list of system header prefixes. - void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) { - SystemHeaderPrefixes.assign(P.begin(), P.end()); - } - - /// \brief Checks whether the map exists or not. - bool HasIncludeAliasMap() const { return (bool)IncludeAliases; } - - /// \brief Map the source include name to the dest include name. - /// - /// The Source should include the angle brackets or quotes, the dest - /// should not. This allows for distinction between <> and "" headers. - void AddIncludeAlias(StringRef Source, StringRef Dest) { - if (!IncludeAliases) - IncludeAliases.reset(new IncludeAliasMap); - (*IncludeAliases)[Source] = Dest; - } - - /// MapHeaderToIncludeAlias - Maps one header file name to a different header - /// file name, for use with the include_alias pragma. Note that the source - /// file name should include the angle brackets or quotes. Returns StringRef - /// as null if the header cannot be mapped. - StringRef MapHeaderToIncludeAlias(StringRef Source) { - assert(IncludeAliases && "Trying to map headers when there's no map"); - - // Do any filename replacements before anything else - IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source); - if (Iter != IncludeAliases->end()) - return Iter->second; - return StringRef(); - } - - /// \brief Set the path to the module cache. - void setModuleCachePath(StringRef CachePath) { - ModuleCachePath = CachePath; - } - - /// \brief Retrieve the path to the module cache. - StringRef getModuleCachePath() const { return ModuleCachePath; } - - /// \brief Consider modules when including files from this directory. - void setDirectoryHasModuleMap(const DirectoryEntry* Dir) { - DirectoryHasModuleMap[Dir] = true; - } - - /// \brief Forget everything we know about headers so far. - void ClearFileInfo() { - FileInfo.clear(); - } - - void SetExternalLookup(ExternalPreprocessorSource *EPS) { - ExternalLookup = EPS; - } - - ExternalPreprocessorSource *getExternalLookup() const { - return ExternalLookup; - } - - /// \brief Set the external source of header information. - void SetExternalSource(ExternalHeaderFileInfoSource *ES) { - ExternalSource = ES; - } - - /// \brief Set the target information for the header search, if not - /// already known. - void setTarget(const TargetInfo &Target); - - /// \brief Given a "foo" or \<foo> reference, look up the indicated file, - /// return null on failure. - /// - /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member - /// the file was found in, or null if not applicable. - /// - /// \param IncludeLoc Used for diagnostics if valid. - /// - /// \param isAngled indicates whether the file reference is a <> reference. - /// - /// \param CurDir If non-null, the file was found in the specified directory - /// search location. This is used to implement \#include_next. - /// - /// \param Includers Indicates where the \#including file(s) are, in case - /// relative searches are needed. In reverse order of inclusion. - /// - /// \param SearchPath If non-null, will be set to the search path relative - /// to which the file was found. If the include path is absolute, SearchPath - /// will be set to an empty string. - /// - /// \param RelativePath If non-null, will be set to the path relative to - /// SearchPath at which the file was found. This only differs from the - /// Filename for framework includes. - /// - /// \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<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, - SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache = false); - - /// \brief Look up a subframework for the specified \#include file. - /// - /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from - /// within ".../Carbon.framework/Headers/Carbon.h", check to see if - /// HIToolbox is a subframework within Carbon.framework. If so, return - /// the FileEntry for the designated file, otherwise return null. - const FileEntry *LookupSubframeworkHeader( - StringRef Filename, const FileEntry *RelativeFileEnt, - SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule); - - /// \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[FWName]; - } - - /// \brief Mark the specified file as a target of of a \#include, - /// \#include_next, or \#import directive. - /// - /// \return false if \#including the file will have no effect or true - /// if we should include it. - bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File, - bool isImport, Module *CorrespondingModule); - - /// \brief Return whether the specified file is a normal header, - /// a system header, or a C++ friendly system header. - SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) { - return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo; - } - - /// \brief Mark the specified file as a "once only" file, e.g. due to - /// \#pragma once. - void MarkFileIncludeOnce(const FileEntry *File) { - HeaderFileInfo &FI = getFileInfo(File); - FI.isImport = true; - FI.isPragmaOnce = true; - } - - /// \brief Mark the specified file as a system header, e.g. due to - /// \#pragma GCC system_header. - void MarkFileSystemHeader(const FileEntry *File) { - getFileInfo(File).DirInfo = SrcMgr::C_System; - } - - /// \brief Mark the specified file as part of a module. - void MarkFileModuleHeader(const FileEntry *File, - ModuleMap::ModuleHeaderRole Role, - bool IsCompiledModuleHeader); - - /// \brief Increment the count for the number of times the specified - /// FileEntry has been entered. - void IncrementIncludeCount(const FileEntry *File) { - ++getFileInfo(File).NumIncludes; - } - - /// \brief Mark the specified file as having a controlling macro. - /// - /// This is used by the multiple-include optimization to eliminate - /// no-op \#includes. - void SetFileControllingMacro(const FileEntry *File, - const IdentifierInfo *ControllingMacro) { - getFileInfo(File).ControllingMacro = ControllingMacro; - } - - /// \brief Return true if this is the first time encountering this header. - bool FirstTimeLexingFile(const FileEntry *File) { - return getFileInfo(File).NumIncludes == 1; - } - - /// \brief Determine whether this file is intended to be safe from - /// multiple inclusions, e.g., it has \#pragma once or a controlling - /// macro. - /// - /// This routine does not consider the effect of \#import - bool isFileMultipleIncludeGuarded(const FileEntry *File); - - /// CreateHeaderMap - This method returns a HeaderMap for the specified - /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. - const HeaderMap *CreateHeaderMap(const FileEntry *FE); - - /// \brief Retrieve the name of the module file that should be used to - /// load the given module. - /// - /// \param Module The module whose module file name will be returned. - /// - /// \returns The name of the module file that corresponds to this module, - /// or an empty string if this module does not correspond to any module file. - std::string getModuleFileName(Module *Module); - - /// \brief Retrieve the name of the module file that should be used to - /// load a module with the given name. - /// - /// \param ModuleName The module whose module file name will be returned. - /// - /// \param ModuleMapPath A path that when combined with \c ModuleName - /// uniquely identifies this module. See Module::ModuleMap. - /// - /// \returns The name of the module file that corresponds to this module, - /// or an empty string if this module does not correspond to any module file. - std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath); - - /// \brief Lookup a module Search for a module with the given name. - /// - /// \param ModuleName The name of the module we're looking for. - /// - /// \param AllowSearch Whether we are allowed to search in the various - /// search directories to produce a module definition. If not, this lookup - /// will only return an already-known module. - /// - /// \returns The module with the given name. - Module *lookupModule(StringRef ModuleName, bool AllowSearch = true); - - /// \brief Try to find a module map file in the given directory, returning - /// \c nullptr if none is found. - const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir, - bool IsFramework); - - void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } - - /// \brief Determine whether there is a module map that may map the header - /// with the given file name to a (sub)module. - /// Always returns false if modules are disabled. - /// - /// \param Filename The name of the file. - /// - /// \param Root The "root" directory, at which we should stop looking for - /// module maps. - /// - /// \param IsSystem Whether the directories we're looking at are system - /// header directories. - bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root, - bool IsSystem); - - /// \brief Retrieve the module that corresponds to the given file, if any. - /// - /// \param File The header that we wish to map to a module. - ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const; - - /// \brief Read the contents of the given module map file. - /// - /// \param File The module map file. - /// \param IsSystem Whether this file is in a system header directory. - /// - /// \returns true if an error occurred, false otherwise. - bool loadModuleMapFile(const FileEntry *File, bool IsSystem); - - /// \brief Collect the set of all known, top-level modules. - /// - /// \param Modules Will be filled with the set of known, top-level modules. - void collectAllModules(SmallVectorImpl<Module *> &Modules); - - /// \brief Load all known, top-level system modules. - void loadTopLevelSystemModules(); - -private: - /// \brief Retrieve a module with the given name, which may be part of the - /// given framework. - /// - /// \param Name The name of the module to retrieve. - /// - /// \param Dir The framework directory (e.g., ModuleName.framework). - /// - /// \param IsSystem Whether the framework directory is part of the system - /// frameworks. - /// - /// \returns The module, if found; otherwise, null. - Module *loadFrameworkModule(StringRef Name, - const DirectoryEntry *Dir, - bool IsSystem); - - /// \brief Load all of the module maps within the immediate subdirectories - /// of the given search directory. - void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir); - - /// \brief Find and suggest a usable module for the given file. - /// - /// \return \c true if the file can be used, \c false if we are not permitted to - /// find this file due to requirements from \p RequestingModule. - bool findUsableModuleForHeader(const FileEntry *File, - const DirectoryEntry *Root, - Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, - bool IsSystemHeaderDir); - - /// \brief Find and suggest a usable module for the given file, which is part of - /// the specified framework. - /// - /// \return \c true if the file can be used, \c false if we are not permitted to - /// find this file due to requirements from \p RequestingModule. - bool findUsableModuleForFrameworkHeader( - const FileEntry *File, StringRef FrameworkDir, Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework); - - /// \brief Look up the file with the specified name and determine its owning - /// module. - const FileEntry * - getFileAndSuggestModule(StringRef FileName, const DirectoryEntry *Dir, - bool IsSystemHeaderDir, Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule); - -public: - /// \brief Retrieve the module map. - ModuleMap &getModuleMap() { return ModMap; } - - /// \brief Retrieve the module map. - const ModuleMap &getModuleMap() const { return ModMap; } - - unsigned header_file_size() const { return FileInfo.size(); } - - /// \brief Return the HeaderFileInfo structure for the specified FileEntry, - /// in preparation for updating it in some way. - HeaderFileInfo &getFileInfo(const FileEntry *FE); - - /// \brief Return the HeaderFileInfo structure for the specified FileEntry, - /// if it has ever been filled in. - /// \param WantExternal Whether the caller wants purely-external header file - /// info (where \p External is true). - const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE, - bool WantExternal = true) const; - - // Used by external tools - typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator; - search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); } - search_dir_iterator search_dir_end() const { return SearchDirs.end(); } - unsigned search_dir_size() const { return SearchDirs.size(); } - - search_dir_iterator quoted_dir_begin() const { - return SearchDirs.begin(); - } - search_dir_iterator quoted_dir_end() const { - return SearchDirs.begin() + AngledDirIdx; - } - - search_dir_iterator angled_dir_begin() const { - return SearchDirs.begin() + AngledDirIdx; - } - search_dir_iterator angled_dir_end() const { - return SearchDirs.begin() + SystemDirIdx; - } - - search_dir_iterator system_dir_begin() const { - return SearchDirs.begin() + SystemDirIdx; - } - search_dir_iterator system_dir_end() const { return SearchDirs.end(); } - - /// \brief Retrieve a uniqued framework name. - StringRef getUniqueFrameworkName(StringRef Framework); - - void PrintStats(); - - size_t getTotalMemory() const; - - static std::string NormalizeDashIncludePath(StringRef File, - FileManager &FileMgr); - -private: - /// \brief Describes what happened when we tried to load a module map file. - enum LoadModuleMapResult { - /// \brief The module map file had already been loaded. - LMM_AlreadyLoaded, - /// \brief The module map file was loaded by this invocation. - LMM_NewlyLoaded, - /// \brief There is was directory with the given name. - LMM_NoDirectory, - /// \brief There was either no module map file or the module map file was - /// invalid. - LMM_InvalidModuleMap - }; - - LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File, - bool IsSystem, - const DirectoryEntry *Dir); - - /// \brief Try to load the module map file in the given directory. - /// - /// \param DirName The name of the directory where we will look for a module - /// map file. - /// \param IsSystem Whether this is a system header directory. - /// \param IsFramework Whether this is a framework directory. - /// - /// \returns The result of attempting to load the module map file from the - /// named directory. - LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem, - bool IsFramework); - - /// \brief Try to load the module map file in the given directory. - /// - /// \param Dir The directory where we will look for a module map file. - /// \param IsSystem Whether this is a system header directory. - /// \param IsFramework Whether this is a framework directory. - /// - /// \returns The result of attempting to load the module map file from the - /// named directory. - LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir, - bool IsSystem, bool IsFramework); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h deleted file mode 100644 index 915dbf7..0000000 --- a/include/clang/Lex/HeaderSearchOptions.h +++ /dev/null @@ -1,206 +0,0 @@ -//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H -#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/StringRef.h" -#include <string> -#include <vector> - -namespace clang { - -namespace frontend { - /// IncludeDirGroup - Identifies the group an include Entry belongs to, - /// representing its relative positive in the search list. - /// \#include directives whose paths are enclosed by string quotes ("") - /// start searching at the Quoted group (specified by '-iquote'), - /// then search the Angled group, then the System group, etc. - enum IncludeDirGroup { - Quoted = 0, ///< '\#include ""' paths, added by 'gcc -iquote'. - Angled, ///< Paths for '\#include <>' added by '-I'. - IndexHeaderMap, ///< Like Angled, but marks header maps used when - /// building frameworks. - System, ///< Like Angled, but marks system directories. - ExternCSystem, ///< Like System, but headers are implicitly wrapped in - /// extern "C". - CSystem, ///< Like System, but only used for C. - CXXSystem, ///< Like System, but only used for C++. - ObjCSystem, ///< Like System, but only used for ObjC. - ObjCXXSystem, ///< Like System, but only used for ObjC++. - After ///< Like System, but searched after the system directories. - }; -} - -/// HeaderSearchOptions - Helper class for storing options related to the -/// initialization of the HeaderSearch object. -class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> { -public: - struct Entry { - std::string Path; - frontend::IncludeDirGroup Group; - unsigned IsFramework : 1; - - /// IgnoreSysRoot - This is false if an absolute path should be treated - /// relative to the sysroot, or true if it should always be the absolute - /// path. - unsigned IgnoreSysRoot : 1; - - Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework, - bool ignoreSysRoot) - : Path(path), Group(group), IsFramework(isFramework), - IgnoreSysRoot(ignoreSysRoot) {} - }; - - struct SystemHeaderPrefix { - /// A prefix to be matched against paths in \#include directives. - std::string Prefix; - - /// True if paths beginning with this prefix should be treated as system - /// headers. - bool IsSystemHeader; - - SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) - : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {} - }; - - /// If non-empty, the directory to use as a "virtual system root" for include - /// paths. - std::string Sysroot; - - /// User specified include entries. - std::vector<Entry> UserEntries; - - /// User-specified system header prefixes. - std::vector<SystemHeaderPrefix> SystemHeaderPrefixes; - - /// The directory which holds the compiler resource files (builtin includes, - /// etc.). - std::string ResourceDir; - - /// \brief The directory used for the module cache. - std::string ModuleCachePath; - - /// \brief The directory used for a user build. - std::string ModuleUserBuildPath; - - /// The module/pch container format. - std::string ModuleFormat; - - /// \brief Whether we should disable the use of the hash string within the - /// module cache. - /// - /// Note: Only used for testing! - unsigned DisableModuleHash : 1; - - /// \brief Implicit module maps. This option is enabld by default when - /// modules is enabled. - unsigned ImplicitModuleMaps : 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 - /// the directory structure of the module cache, stat()'ing and removing - /// files. - /// - /// The default value is large, e.g., the operation runs once a week. - unsigned ModuleCachePruneInterval; - - /// \brief The time (in seconds) after which an unused module file will be - /// considered unused and will, therefore, be pruned. - /// - /// When the module cache is pruned, any module file that has not been - /// accessed in this many seconds will be removed. The default value is - /// large, e.g., a month, to avoid forcing infrequently-used modules to be - /// regenerated often. - unsigned ModuleCachePruneAfter; - - /// \brief The time in seconds when the build session started. - /// - /// This time is used by other optimizations in header search and module - /// loading. - uint64_t BuildSessionTimestamp; - - /// \brief The set of macro names that should be ignored for the purposes - /// of computing the module hash. - llvm::SmallSetVector<std::string, 16> ModulesIgnoreMacros; - - /// \brief The set of user-provided virtual filesystem overlay files. - std::vector<std::string> VFSOverlayFiles; - - /// Include the compiler builtin includes. - unsigned UseBuiltinIncludes : 1; - - /// Include the system standard include search directories. - unsigned UseStandardSystemIncludes : 1; - - /// Include the system standard C++ library include search directories. - unsigned UseStandardCXXIncludes : 1; - - /// Use libc++ instead of the default libstdc++. - unsigned UseLibcxx : 1; - - /// Whether header search information should be output as for -v. - unsigned Verbose : 1; - - /// \brief If true, skip verifying input files used by modules if the - /// module was already verified during this build session (see - /// \c BuildSessionTimestamp). - unsigned ModulesValidateOncePerBuildSession : 1; - - /// \brief Whether to validate system input files when a module is loaded. - unsigned ModulesValidateSystemHeaders : 1; - - /// Whether the module includes debug information (-gmodules). - unsigned UseDebugInfo : 1; - - HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0), - ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0), - ModuleCachePruneInterval(7 * 24 * 60 * 60), - ModuleCachePruneAfter(31 * 24 * 60 * 60), BuildSessionTimestamp(0), - UseBuiltinIncludes(true), UseStandardSystemIncludes(true), - UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), - ModulesValidateOncePerBuildSession(false), - ModulesValidateSystemHeaders(false), - UseDebugInfo(false) {} - - /// AddPath - Add the \p Path path to the specified \p Group list. - void AddPath(StringRef Path, frontend::IncludeDirGroup Group, - bool IsFramework, bool IgnoreSysRoot) { - UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot); - } - - /// AddSystemHeaderPrefix - Override whether \#include directives naming a - /// path starting with \p Prefix should be considered as naming a system - /// header. - void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { - SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader); - } - - void AddVFSOverlayFile(StringRef Name) { - VFSOverlayFiles.push_back(Name); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h deleted file mode 100644 index 5d724c0..0000000 --- a/include/clang/Lex/LexDiagnostic.h +++ /dev/null @@ -1,28 +0,0 @@ -//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_LEXDIAGNOSTIC_H -#define LLVM_CLANG_LEX_LEXDIAGNOSTIC_H - -#include "clang/Basic/Diagnostic.h" - -namespace clang { - namespace diag { - enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, -#define LEXSTART -#include "clang/Basic/DiagnosticLexKinds.inc" -#undef DIAG - NUM_BUILTIN_LEX_DIAGNOSTICS - }; - } // end namespace diag -} // end namespace clang - -#endif diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h deleted file mode 100644 index 12565d0..0000000 --- a/include/clang/Lex/Lexer.h +++ /dev/null @@ -1,665 +0,0 @@ -//===--- Lexer.h - C Language Family Lexer ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the Lexer interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_LEXER_H -#define LLVM_CLANG_LEX_LEXER_H - -#include "clang/Basic/LangOptions.h" -#include "clang/Lex/PreprocessorLexer.h" -#include "llvm/ADT/SmallVector.h" -#include <cassert> -#include <string> - -namespace clang { -class DiagnosticsEngine; -class SourceManager; -class Preprocessor; -class DiagnosticBuilder; - -/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be -/// recovering from. -enum ConflictMarkerKind { - /// Not within a conflict marker. - CMK_None, - /// A normal or diff3 conflict marker, initiated by at least 7 "<"s, - /// separated by at least 7 "="s or "|"s, and terminated by at least 7 ">"s. - CMK_Normal, - /// A Perforce-style conflict marker, initiated by 4 ">"s, - /// separated by 4 "="s, and terminated by 4 "<"s. - CMK_Perforce -}; - -/// Lexer - This provides a simple interface that turns a text buffer into a -/// stream of tokens. This provides no support for file reading or buffering, -/// or buffering/seeking of tokens, only forward lexing is supported. It relies -/// on the specified Preprocessor object to handle preprocessor directives, etc. -class Lexer : public PreprocessorLexer { - void anchor() override; - - //===--------------------------------------------------------------------===// - // Constant configuration values for this lexer. - const char *BufferStart; // Start of the buffer. - const char *BufferEnd; // End of the buffer. - SourceLocation FileLoc; // Location for start of file. - LangOptions LangOpts; // LangOpts enabled by this language (cache). - bool Is_PragmaLexer; // True if lexer for _Pragma handling. - - //===--------------------------------------------------------------------===// - // Context-specific lexing flags set by the preprocessor. - // - - /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace - /// and return them as tokens. This is used for -C and -CC modes, and - /// whitespace preservation can be useful for some clients that want to lex - /// the file in raw mode and get every character from the file. - /// - /// When this is set to 2 it returns comments and whitespace. When set to 1 - /// it returns comments, when it is set to 0 it returns normal tokens only. - unsigned char ExtendedTokenMode; - - //===--------------------------------------------------------------------===// - // Context that changes as the file is lexed. - // NOTE: any state that mutates when in raw mode must have save/restore code - // in Lexer::isNextPPTokenLParen. - - // BufferPtr - Current pointer into the buffer. This is the next character - // to be lexed. - const char *BufferPtr; - - // IsAtStartOfLine - True if the next lexed token should get the "start of - // line" flag set on it. - bool IsAtStartOfLine; - - bool IsAtPhysicalStartOfLine; - - bool HasLeadingSpace; - - bool HasLeadingEmptyMacro; - - // CurrentConflictMarkerState - The kind of conflict marker we are handling. - ConflictMarkerKind CurrentConflictMarkerState; - - Lexer(const Lexer &) = delete; - void operator=(const Lexer &) = delete; - friend class Preprocessor; - - void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd); -public: - - /// Lexer constructor - Create a new lexer object for the specified buffer - /// with the specified preprocessor managing the lexing process. This lexer - /// assumes that the associated file buffer and Preprocessor objects will - /// outlive it, so it doesn't take ownership of either of them. - Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, Preprocessor &PP); - - /// Lexer constructor - Create a new raw lexer object. This object is only - /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the - /// text range will outlive it, so it doesn't take ownership of it. - Lexer(SourceLocation FileLoc, const LangOptions &LangOpts, - const char *BufStart, const char *BufPtr, const char *BufEnd); - - /// Lexer constructor - Create a new raw lexer object. This object is only - /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the - /// text range will outlive it, so it doesn't take ownership of it. - Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, - const SourceManager &SM, const LangOptions &LangOpts); - - /// Create_PragmaLexer: Lexer constructor - Create a new lexer object for - /// _Pragma expansion. This has a variety of magic semantics that this method - /// sets up. It returns a new'd Lexer that must be delete'd when done. - static Lexer *Create_PragmaLexer(SourceLocation SpellingLoc, - SourceLocation ExpansionLocStart, - SourceLocation ExpansionLocEnd, - unsigned TokLen, Preprocessor &PP); - - - /// getLangOpts - Return the language features currently enabled. - /// NOTE: this lexer modifies features as a file is parsed! - const LangOptions &getLangOpts() const { return LangOpts; } - - /// getFileLoc - Return the File Location for the file we are lexing out of. - /// The physical location encodes the location where the characters come from, - /// the virtual location encodes where we should *claim* the characters came - /// from. Currently this is only used by _Pragma handling. - SourceLocation getFileLoc() const { return FileLoc; } - -private: - /// Lex - Return the next token in the file. If this is the end of file, it - /// return the tok::eof token. This implicitly involves the preprocessor. - bool Lex(Token &Result); - -public: - /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma. - bool isPragmaLexer() const { return Is_PragmaLexer; } - -private: - /// IndirectLex - An indirect call to 'Lex' that can be invoked via - /// the PreprocessorLexer interface. - void IndirectLex(Token &Result) override { Lex(Result); } - -public: - /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no - /// associated preprocessor object. Return true if the 'next character to - /// read' pointer points at the end of the lexer buffer, false otherwise. - bool LexFromRawLexer(Token &Result) { - assert(LexingRawMode && "Not already in raw mode!"); - Lex(Result); - // Note that lexing to the end of the buffer doesn't implicitly delete the - // lexer when in raw mode. - return BufferPtr == BufferEnd; - } - - /// isKeepWhitespaceMode - Return true if the lexer should return tokens for - /// every character in the file, including whitespace and comments. This - /// should only be used in raw mode, as the preprocessor is not prepared to - /// deal with the excess tokens. - bool isKeepWhitespaceMode() const { - return ExtendedTokenMode > 1; - } - - /// SetKeepWhitespaceMode - This method lets clients enable or disable - /// whitespace retention mode. - void SetKeepWhitespaceMode(bool Val) { - assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) && - "Can only retain whitespace in raw mode or -traditional-cpp"); - ExtendedTokenMode = Val ? 2 : 0; - } - - /// inKeepCommentMode - Return true if the lexer should return comments as - /// tokens. - bool inKeepCommentMode() const { - return ExtendedTokenMode > 0; - } - - /// SetCommentRetentionMode - Change the comment retention mode of the lexer - /// to the specified mode. This is really only useful when lexing in raw - /// mode, because otherwise the lexer needs to manage this. - void SetCommentRetentionState(bool Mode) { - assert(!isKeepWhitespaceMode() && - "Can't play with comment retention state when retaining whitespace"); - ExtendedTokenMode = Mode ? 1 : 0; - } - - /// Sets the extended token mode back to its initial value, according to the - /// language options and preprocessor. This controls whether the lexer - /// produces comment and whitespace tokens. - /// - /// This requires the lexer to have an associated preprocessor. A standalone - /// lexer has nothing to reset to. - void resetExtendedTokenMode(); - - /// Gets source code buffer. - StringRef getBuffer() const { - return StringRef(BufferStart, BufferEnd - BufferStart); - } - - /// ReadToEndOfLine - Read the rest of the current preprocessor line as an - /// uninterpreted string. This switches the lexer out of directive mode. - void ReadToEndOfLine(SmallVectorImpl<char> *Result = nullptr); - - - /// Diag - Forwarding function for diagnostics. This translate a source - /// position in the current buffer into a SourceLocation object for rendering. - DiagnosticBuilder Diag(const char *Loc, unsigned DiagID) const; - - /// getSourceLocation - Return a source location identifier for the specified - /// offset in the current file. - SourceLocation getSourceLocation(const char *Loc, unsigned TokLen = 1) const; - - /// getSourceLocation - Return a source location for the next character in - /// the current file. - SourceLocation getSourceLocation() override { - return getSourceLocation(BufferPtr); - } - - /// \brief Return the current location in the buffer. - const char *getBufferLocation() const { return BufferPtr; } - - /// Stringify - Convert the specified string into a C string by escaping '\' - /// and " characters. This does not add surrounding ""'s to the string. - /// If Charify is true, this escapes the ' character instead of ". - static std::string Stringify(StringRef Str, bool Charify = false); - - /// Stringify - Convert the specified string into a C string by escaping '\' - /// and " characters. This does not add surrounding ""'s to the string. - static void Stringify(SmallVectorImpl<char> &Str); - - - /// getSpelling - This method is used to get the spelling of a token into a - /// preallocated buffer, instead of as an std::string. The caller is required - /// to allocate enough space for the token, which is guaranteed to be at least - /// Tok.getLength() bytes long. The length of the actual result is returned. - /// - /// Note that this method may do two possible things: it may either fill in - /// the buffer specified with characters, or it may *change the input pointer* - /// to point to a constant buffer with the data already in it (avoiding a - /// copy). The caller is not allowed to modify the returned buffer pointer - /// if an internal buffer is returned. - static unsigned getSpelling(const Token &Tok, const char *&Buffer, - const SourceManager &SourceMgr, - const LangOptions &LangOpts, - bool *Invalid = nullptr); - - /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a - /// token is the characters used to represent the token in the source file - /// after trigraph expansion and escaped-newline folding. In particular, this - /// wants to get the true, uncanonicalized, spelling of things like digraphs - /// UCNs, etc. - static std::string getSpelling(const Token &Tok, - const SourceManager &SourceMgr, - const LangOptions &LangOpts, - bool *Invalid = nullptr); - - /// getSpelling - This method is used to get the spelling of the - /// token at the given source location. If, as is usually true, it - /// is not necessary to copy any data, then the returned string may - /// not point into the provided buffer. - /// - /// This method lexes at the expansion depth of the given - /// location and does not jump to the expansion or spelling - /// location. - static StringRef getSpelling(SourceLocation loc, - SmallVectorImpl<char> &buffer, - const SourceManager &SourceMgr, - const LangOptions &LangOpts, - bool *invalid = nullptr); - - /// MeasureTokenLength - Relex the token at the specified location and return - /// its length in bytes in the input file. If the token needs cleaning (e.g. - /// includes a trigraph or an escaped newline) then this count includes bytes - /// that are part of that. - static unsigned MeasureTokenLength(SourceLocation Loc, - const SourceManager &SM, - const LangOptions &LangOpts); - - /// \brief Relex the token at the specified location. - /// \returns true if there was a failure, false on success. - static bool getRawToken(SourceLocation Loc, Token &Result, - const SourceManager &SM, - const LangOptions &LangOpts, - bool IgnoreWhiteSpace = false); - - /// \brief Given a location any where in a source buffer, find the location - /// that corresponds to the beginning of the token in which the original - /// source location lands. - static SourceLocation GetBeginningOfToken(SourceLocation Loc, - const SourceManager &SM, - const LangOptions &LangOpts); - - /// AdvanceToTokenCharacter - If the current SourceLocation specifies a - /// location at the start of a token, return a new location that specifies a - /// character within the token. This handles trigraphs and escaped newlines. - static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, - unsigned Character, - const SourceManager &SM, - const LangOptions &LangOpts); - - /// \brief Computes the source location just past the end of the - /// token at this source location. - /// - /// This routine can be used to produce a source location that - /// points just past the end of the token referenced by \p Loc, and - /// is generally used when a diagnostic needs to point just after a - /// token where it expected something different that it received. If - /// the returned source location would not be meaningful (e.g., if - /// it points into a macro), this routine returns an invalid - /// source location. - /// - /// \param Offset an offset from the end of the token, where the source - /// location should refer to. The default offset (0) produces a source - /// location pointing just past the end of the token; an offset of 1 produces - /// a source location pointing to the last character in the token, etc. - static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, - 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. - /// - /// \param MacroBegin If non-null and function returns true, it is set to - /// begin location of the macro. - static bool isAtStartOfMacroExpansion(SourceLocation loc, - const SourceManager &SM, - const LangOptions &LangOpts, - SourceLocation *MacroBegin = nullptr); - - /// \brief Returns true if the given MacroID location points at the last - /// token of the macro expansion. - /// - /// \param MacroEnd If non-null and function returns true, it is set to - /// end location of the macro. - static bool isAtEndOfMacroExpansion(SourceLocation loc, - const SourceManager &SM, - const LangOptions &LangOpts, - SourceLocation *MacroEnd = nullptr); - - /// \brief Accepts a range and returns a character range with file locations. - /// - /// Returns a null range if a part of the range resides inside a macro - /// expansion or the range does not reside on the same FileID. - /// - /// This function is trying to deal with macros and return a range based on - /// file locations. The cases where it can successfully handle macros are: - /// - /// -begin or end range lies at the start or end of a macro expansion, in - /// which case the location will be set to the expansion point, e.g: - /// \#define M 1 2 - /// a M - /// If you have a range [a, 2] (where 2 came from the macro), the function - /// will return a range for "a M" - /// if you have range [a, 1], the function will fail because the range - /// overlaps with only a part of the macro - /// - /// -The macro is a function macro and the range can be mapped to the macro - /// arguments, e.g: - /// \#define M 1 2 - /// \#define FM(x) x - /// FM(a b M) - /// if you have range [b, 2], the function will return the file range "b M" - /// inside the macro arguments. - /// if you have range [a, 2], the function will return the file range - /// "FM(a b M)" since the range includes all of the macro expansion. - static CharSourceRange makeFileCharRange(CharSourceRange Range, - const SourceManager &SM, - const LangOptions &LangOpts); - - /// \brief Returns a string for the source that the range encompasses. - static StringRef getSourceText(CharSourceRange Range, - const SourceManager &SM, - const LangOptions &LangOpts, - bool *Invalid = nullptr); - - /// \brief Retrieve the name of the immediate macro expansion. - /// - /// This routine starts from a source location, and finds the name of the macro - /// responsible for its immediate expansion. It looks through any intervening - /// macro argument expansions to compute this. It returns a StringRef which - /// refers to the SourceManager-owned buffer of the source where that macro - /// name is spelled. Thus, the result shouldn't out-live that SourceManager. - static StringRef getImmediateMacroName(SourceLocation Loc, - const SourceManager &SM, - const LangOptions &LangOpts); - - /// \brief Compute the preamble of the given file. - /// - /// The preamble of a file contains the initial comments, include directives, - /// and other preprocessor directives that occur before the code in this - /// particular file actually begins. The preamble of the main source file is - /// a potential prefix header. - /// - /// \param Buffer The memory buffer containing the file's contents. - /// - /// \param MaxLines If non-zero, restrict the length of the preamble - /// to fewer than this number of lines. - /// - /// \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(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 - /// location immediately after the specified token. If the token is not found - /// or the location is inside a macro, the returned source location will be - /// invalid. - static SourceLocation findLocationAfterToken(SourceLocation loc, - tok::TokenKind TKind, - const SourceManager &SM, - const LangOptions &LangOpts, - bool SkipTrailingWhitespaceAndNewLine); - - /// \brief Returns true if the given character could appear in an identifier. - static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts); - - /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever - /// emit a warning. - static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size, - const LangOptions &LangOpts) { - // If this is not a trigraph and not a UCN or escaped newline, return - // quickly. - if (isObviouslySimpleCharacter(Ptr[0])) { - Size = 1; - return *Ptr; - } - - Size = 0; - return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts); - } - - //===--------------------------------------------------------------------===// - // Internal implementation interfaces. -private: - - /// LexTokenInternal - Internal interface to lex a preprocessing token. Called - /// by Lex. - /// - bool LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine); - - bool CheckUnicodeWhitespace(Token &Result, uint32_t C, const char *CurPtr); - - /// Given that a token begins with the Unicode character \p C, figure out - /// what kind of token it is and dispatch to the appropriate lexing helper - /// function. - bool LexUnicode(Token &Result, uint32_t C, const char *CurPtr); - - /// FormTokenWithChars - When we lex a token, we have identified a span - /// starting at BufferPtr, going to TokEnd that forms the token. This method - /// takes that range and assigns it to the token as its location and size. In - /// addition, since tokens cannot overlap, this also updates BufferPtr to be - /// TokEnd. - void FormTokenWithChars(Token &Result, const char *TokEnd, - tok::TokenKind Kind) { - unsigned TokLen = TokEnd-BufferPtr; - Result.setLength(TokLen); - Result.setLocation(getSourceLocation(BufferPtr, TokLen)); - Result.setKind(Kind); - BufferPtr = TokEnd; - } - - /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a - /// tok::l_paren token, 0 if it is something else and 2 if there are no more - /// tokens in the buffer controlled by this lexer. - unsigned isNextPPTokenLParen(); - - //===--------------------------------------------------------------------===// - // Lexer character reading interfaces. - - // This lexer is built on two interfaces for reading characters, both of which - // automatically provide phase 1/2 translation. getAndAdvanceChar is used - // when we know that we will be reading a character from the input buffer and - // that this character will be part of the result token. This occurs in (f.e.) - // string processing, because we know we need to read until we find the - // closing '"' character. - // - // The second interface is the combination of getCharAndSize with - // ConsumeChar. getCharAndSize reads a phase 1/2 translated character, - // returning it and its size. If the lexer decides that this character is - // part of the current token, it calls ConsumeChar on it. This two stage - // approach allows us to emit diagnostics for characters (e.g. warnings about - // trigraphs), knowing that they only are emitted if the character is - // consumed. - - /// isObviouslySimpleCharacter - Return true if the specified character is - /// obviously the same in translation phase 1 and translation phase 3. This - /// can return false for characters that end up being the same, but it will - /// never return true for something that needs to be mapped. - static bool isObviouslySimpleCharacter(char C) { - return C != '?' && C != '\\'; - } - - /// getAndAdvanceChar - Read a single 'character' from the specified buffer, - /// advance over it, and return it. This is tricky in several cases. Here we - /// just handle the trivial case and fall-back to the non-inlined - /// getCharAndSizeSlow method to handle the hard case. - inline char getAndAdvanceChar(const char *&Ptr, Token &Tok) { - // If this is not a trigraph and not a UCN or escaped newline, return - // quickly. - if (isObviouslySimpleCharacter(Ptr[0])) return *Ptr++; - - unsigned Size = 0; - char C = getCharAndSizeSlow(Ptr, Size, &Tok); - Ptr += Size; - return C; - } - - /// ConsumeChar - When a character (identified by getCharAndSize) is consumed - /// and added to a given token, check to see if there are diagnostics that - /// need to be emitted or flags that need to be set on the token. If so, do - /// it. - const char *ConsumeChar(const char *Ptr, unsigned Size, Token &Tok) { - // Normal case, we consumed exactly one token. Just return it. - if (Size == 1) - return Ptr+Size; - - // Otherwise, re-lex the character with a current token, allowing - // diagnostics to be emitted and flags to be set. - Size = 0; - getCharAndSizeSlow(Ptr, Size, &Tok); - return Ptr+Size; - } - - /// getCharAndSize - Peek a single 'character' from the specified buffer, - /// get its size, and return it. This is tricky in several cases. Here we - /// just handle the trivial case and fall-back to the non-inlined - /// getCharAndSizeSlow method to handle the hard case. - inline char getCharAndSize(const char *Ptr, unsigned &Size) { - // If this is not a trigraph and not a UCN or escaped newline, return - // quickly. - if (isObviouslySimpleCharacter(Ptr[0])) { - Size = 1; - return *Ptr; - } - - Size = 0; - return getCharAndSizeSlow(Ptr, Size); - } - - /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize - /// method. - char getCharAndSizeSlow(const char *Ptr, unsigned &Size, - Token *Tok = nullptr); - - /// getEscapedNewLineSize - Return the size of the specified escaped newline, - /// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry - /// to this function. - static unsigned getEscapedNewLineSize(const char *P); - - /// SkipEscapedNewLines - If P points to an escaped newline (or a series of - /// them), skip over them and return the first non-escaped-newline found, - /// otherwise return P. - static const char *SkipEscapedNewLines(const char *P); - - /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a - /// diagnostic. - static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size, - const LangOptions &LangOpts); - - //===--------------------------------------------------------------------===// - // Other lexer functions. - - void SkipBytes(unsigned Bytes, bool StartOfLine); - - void PropagateLineStartLeadingSpaceInfo(Token &Result); - - const char *LexUDSuffix(Token &Result, const char *CurPtr, - bool IsStringLiteral); - - // Helper functions to lex the remainder of a token of the specific type. - bool LexIdentifier (Token &Result, const char *CurPtr); - bool LexNumericConstant (Token &Result, const char *CurPtr); - bool LexStringLiteral (Token &Result, const char *CurPtr, - tok::TokenKind Kind); - bool LexRawStringLiteral (Token &Result, const char *CurPtr, - tok::TokenKind Kind); - bool LexAngledStringLiteral(Token &Result, const char *CurPtr); - bool LexCharConstant (Token &Result, const char *CurPtr, - tok::TokenKind Kind); - bool LexEndOfFile (Token &Result, const char *CurPtr); - bool SkipWhitespace (Token &Result, const char *CurPtr, - bool &TokAtPhysicalStartOfLine); - bool SkipLineComment (Token &Result, const char *CurPtr, - bool &TokAtPhysicalStartOfLine); - bool SkipBlockComment (Token &Result, const char *CurPtr, - bool &TokAtPhysicalStartOfLine); - bool SaveLineComment (Token &Result, const char *CurPtr); - - bool IsStartOfConflictMarker(const char *CurPtr); - bool HandleEndOfConflictMarker(const char *CurPtr); - - bool isCodeCompletionPoint(const char *CurPtr) const; - void cutOffLexing() { BufferPtr = BufferEnd; } - - bool isHexaLiteral(const char *Start, const LangOptions &LangOpts); - - - /// Read a universal character name. - /// - /// \param CurPtr The position in the source buffer after the initial '\'. - /// If the UCN is syntactically well-formed (but not necessarily - /// valid), this parameter will be updated to point to the - /// character after the UCN. - /// \param SlashLoc The position in the source buffer of the '\'. - /// \param Tok The token being formed. Pass \c NULL to suppress diagnostics - /// and handle token formation in the caller. - /// - /// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is - /// invalid. - uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok); - - /// \brief Try to consume a UCN as part of an identifier at the current - /// location. - /// \param CurPtr Initially points to the range of characters in the source - /// buffer containing the '\'. Updated to point past the end of - /// the UCN on success. - /// \param Size The number of characters occupied by the '\' (including - /// trigraphs and escaped newlines). - /// \param Result The token being produced. Marked as containing a UCN on - /// success. - /// \return \c true if a UCN was lexed and it produced an acceptable - /// identifier character, \c false otherwise. - bool tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size, - Token &Result); - - /// \brief Try to consume an identifier character encoded in UTF-8. - /// \param CurPtr Points to the start of the (potential) UTF-8 code unit - /// sequence. On success, updated to point past the end of it. - /// \return \c true if a UTF-8 sequence mapping to an acceptable identifier - /// character was lexed, \c false otherwise. - bool tryConsumeIdentifierUTF8Char(const char *&CurPtr); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h deleted file mode 100644 index 5210e3f..0000000 --- a/include/clang/Lex/LiteralSupport.h +++ /dev/null @@ -1,260 +0,0 @@ -//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the NumericLiteralParser, CharLiteralParser, and -// StringLiteralParser interfaces. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_LITERALSUPPORT_H -#define LLVM_CLANG_LEX_LITERALSUPPORT_H - -#include "clang/Basic/CharInfo.h" -#include "clang/Basic/LLVM.h" -#include "clang/Basic/TokenKinds.h" -#include "llvm/ADT/APFloat.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DataTypes.h" - -namespace clang { - -class DiagnosticsEngine; -class Preprocessor; -class Token; -class SourceLocation; -class TargetInfo; -class SourceManager; -class LangOptions; - -/// Copy characters from Input to Buf, expanding any UCNs. -void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input); - -/// NumericLiteralParser - This performs strict semantic analysis of the content -/// of a ppnumber, classifying it as either integer, floating, or erroneous, -/// determines the radix of the value and can convert it to a useful value. -class NumericLiteralParser { - Preprocessor &PP; // needed for diagnostics - - const char *const ThisTokBegin; - const char *const ThisTokEnd; - const char *DigitsBegin, *SuffixBegin; // markers - const char *s; // cursor - - unsigned radix; - - bool saw_exponent, saw_period, saw_ud_suffix; - - SmallString<32> UDSuffixBuf; - -public: - NumericLiteralParser(StringRef TokSpelling, - SourceLocation TokLoc, - Preprocessor &PP); - 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; - } - bool isFloatingLiteral() const { - return saw_period || saw_exponent; - } - - bool hasUDSuffix() const { - return saw_ud_suffix; - } - StringRef getUDSuffix() const { - assert(saw_ud_suffix); - return UDSuffixBuf; - } - unsigned getUDSuffixOffset() const { - assert(saw_ud_suffix); - return SuffixBegin - ThisTokBegin; - } - - static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix); - - unsigned getRadix() const { return radix; } - - /// GetIntegerValue - Convert this numeric literal value to an APInt that - /// matches Val's input width. If there is an overflow (i.e., if the unsigned - /// value read is larger than the APInt's bits will hold), set Val to the low - /// bits of the result and return true. Otherwise, return false. - bool GetIntegerValue(llvm::APInt &Val); - - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); - -private: - - void ParseNumberStartingWithZero(SourceLocation TokLoc); - - static bool isDigitSeparator(char C) { return C == '\''; } - - enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits }; - - /// \brief Ensure that we don't have a digit separator here. - void checkSeparator(SourceLocation TokLoc, const char *Pos, - CheckSeparatorKind IsAfterDigits); - - /// SkipHexDigits - Read and skip over any hex digits, up to End. - /// Return a pointer to the first non-hex digit or End. - const char *SkipHexDigits(const char *ptr) { - while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr))) - ptr++; - return ptr; - } - - /// SkipOctalDigits - Read and skip over any octal digits, up to End. - /// Return a pointer to the first non-hex digit or End. - const char *SkipOctalDigits(const char *ptr) { - while (ptr != ThisTokEnd && - ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr))) - ptr++; - return ptr; - } - - /// SkipDigits - Read and skip over any digits, up to End. - /// Return a pointer to the first non-hex digit or End. - const char *SkipDigits(const char *ptr) { - while (ptr != ThisTokEnd && (isDigit(*ptr) || isDigitSeparator(*ptr))) - ptr++; - return ptr; - } - - /// SkipBinaryDigits - Read and skip over any binary digits, up to End. - /// Return a pointer to the first non-binary digit or End. - const char *SkipBinaryDigits(const char *ptr) { - while (ptr != ThisTokEnd && - (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr))) - ptr++; - return ptr; - } - -}; - -/// CharLiteralParser - Perform interpretation and semantic analysis of a -/// character literal. -class CharLiteralParser { - uint64_t Value; - tok::TokenKind Kind; - bool IsMultiChar; - bool HadError; - SmallString<32> UDSuffixBuf; - unsigned UDSuffixOffset; -public: - CharLiteralParser(const char *begin, const char *end, - SourceLocation Loc, Preprocessor &PP, - tok::TokenKind kind); - - bool hadError() const { return HadError; } - bool isAscii() const { return Kind == tok::char_constant; } - bool isWide() const { return Kind == tok::wide_char_constant; } - bool isUTF16() const { return Kind == tok::utf16_char_constant; } - bool isUTF32() const { return Kind == tok::utf32_char_constant; } - bool isMultiChar() const { return IsMultiChar; } - uint64_t getValue() const { return Value; } - StringRef getUDSuffix() const { return UDSuffixBuf; } - unsigned getUDSuffixOffset() const { - assert(!UDSuffixBuf.empty() && "no ud-suffix"); - return UDSuffixOffset; - } -}; - -/// StringLiteralParser - This decodes string escape characters and performs -/// wide string analysis and Translation Phase #6 (concatenation of string -/// literals) (C99 5.1.1.2p1). -class StringLiteralParser { - const SourceManager &SM; - const LangOptions &Features; - const TargetInfo &Target; - DiagnosticsEngine *Diags; - - unsigned MaxTokenLength; - unsigned SizeBound; - unsigned CharByteWidth; - tok::TokenKind Kind; - SmallString<512> ResultBuf; - char *ResultPtr; // cursor - SmallString<32> UDSuffixBuf; - unsigned UDSuffixToken; - unsigned UDSuffixOffset; -public: - StringLiteralParser(ArrayRef<Token> StringToks, - Preprocessor &PP, bool Complain = true); - StringLiteralParser(ArrayRef<Token> StringToks, - const SourceManager &sm, const LangOptions &features, - const TargetInfo &target, - DiagnosticsEngine *diags = nullptr) - : SM(sm), Features(features), Target(target), Diags(diags), - MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown), - ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) { - init(StringToks); - } - - - bool hadError; - bool Pascal; - - StringRef GetString() const { - return StringRef(ResultBuf.data(), GetStringLength()); - } - unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); } - - unsigned GetNumStringChars() const { - return GetStringLength() / CharByteWidth; - } - /// getOffsetOfStringByte - This function returns the offset of the - /// specified byte of the string data represented by Token. This handles - /// advancing over escape sequences in the string. - /// - /// If the Diagnostics pointer is non-null, then this will do semantic - /// checking of the string literal and emit errors and warnings. - unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const; - - bool isAscii() const { return Kind == tok::string_literal; } - bool isWide() const { return Kind == tok::wide_string_literal; } - bool isUTF8() const { return Kind == tok::utf8_string_literal; } - bool isUTF16() const { return Kind == tok::utf16_string_literal; } - bool isUTF32() const { return Kind == tok::utf32_string_literal; } - bool isPascal() const { return Pascal; } - - StringRef getUDSuffix() const { return UDSuffixBuf; } - - /// Get the index of a token containing a ud-suffix. - unsigned getUDSuffixToken() const { - assert(!UDSuffixBuf.empty() && "no ud-suffix"); - return UDSuffixToken; - } - /// Get the spelling offset of the first byte of the ud-suffix. - unsigned getUDSuffixOffset() const { - assert(!UDSuffixBuf.empty() && "no ud-suffix"); - return UDSuffixOffset; - } - -private: - void init(ArrayRef<Token> StringToks); - bool CopyStringFragment(const Token &Tok, const char *TokBegin, - StringRef Fragment); - void DiagnoseLexingError(SourceLocation Loc); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h deleted file mode 100644 index 243b143..0000000 --- a/include/clang/Lex/MacroArgs.h +++ /dev/null @@ -1,127 +0,0 @@ -//===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the MacroArgs interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_MACROARGS_H -#define LLVM_CLANG_LEX_MACROARGS_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/ArrayRef.h" -#include <vector> - -namespace clang { - class MacroInfo; - class Preprocessor; - class Token; - class SourceLocation; - -/// MacroArgs - An instance of this class captures information about -/// the formal arguments specified to a function-like macro invocation. -class MacroArgs { - /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the - /// arguments. All of the actual argument tokens are allocated immediately - /// after the MacroArgs object in memory. This is all of the arguments - /// concatenated together, with 'EOF' markers at the end of each argument. - unsigned NumUnexpArgTokens; - - /// VarargsElided - True if this is a C99 style varargs macro invocation and - /// there was no argument specified for the "..." argument. If the argument - /// was specified (even empty) or this isn't a C99 style varargs function, or - /// if in strict mode and the C99 varargs macro had only a ... argument, this - /// is false. - bool VarargsElided; - - /// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty - /// if not yet computed. This includes the EOF marker at the end of the - /// stream. - std::vector<std::vector<Token> > PreExpArgTokens; - - /// StringifiedArgs - This contains arguments in 'stringified' form. If the - /// stringified form of an argument has not yet been computed, this is empty. - std::vector<Token> StringifiedArgs; - - /// ArgCache - This is a linked list of MacroArgs objects that the - /// Preprocessor owns which we use to avoid thrashing malloc/free. - MacroArgs *ArgCache; - - MacroArgs(unsigned NumToks, bool varargsElided) - : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), - ArgCache(nullptr) {} - ~MacroArgs() = default; - -public: - /// MacroArgs ctor function - Create a new MacroArgs object with the specified - /// macro and argument info. - static MacroArgs *create(const MacroInfo *MI, - ArrayRef<Token> UnexpArgTokens, - bool VarargsElided, Preprocessor &PP); - - /// destroy - Destroy and deallocate the memory for this object. - /// - void destroy(Preprocessor &PP); - - /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected - /// by pre-expansion, return false. Otherwise, conservatively return true. - bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const; - - /// getUnexpArgument - Return a pointer to the first token of the unexpanded - /// token list for the specified formal. - /// - const Token *getUnexpArgument(unsigned Arg) const; - - /// getArgLength - Given a pointer to an expanded or unexpanded argument, - /// return the number of tokens, not counting the EOF, that make up the - /// argument. - static unsigned getArgLength(const Token *ArgPtr); - - /// getPreExpArgument - Return the pre-expanded form of the specified - /// argument. - const std::vector<Token> & - getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP); - - /// getStringifiedArgument - Compute, cache, and return the specified argument - /// that has been 'stringified' as required by the # operator. - const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP, - SourceLocation ExpansionLocStart, - SourceLocation ExpansionLocEnd); - - /// getNumArguments - Return the number of arguments passed into this macro - /// invocation. - unsigned getNumArguments() const { return NumUnexpArgTokens; } - - - /// isVarargsElidedUse - Return true if this is a C99 style varargs macro - /// invocation and there was no argument specified for the "..." argument. If - /// the argument was specified (even empty) or this isn't a C99 style varargs - /// function, or if in strict mode and the C99 varargs macro had only a ... - /// argument, this returns false. - bool isVarargsElidedUse() const { return VarargsElided; } - - /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of - /// tokens into the literal string token that should be produced by the C # - /// preprocessor operator. If Charify is true, then it should be turned into - /// a character literal for the Microsoft charize (#@) extension. - /// - static Token StringifyArgument(const Token *ArgToks, - Preprocessor &PP, bool Charify, - SourceLocation ExpansionLocStart, - SourceLocation ExpansionLocEnd); - - - /// deallocate - This should only be called by the Preprocessor when managing - /// its freelist. - MacroArgs *deallocate(); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h deleted file mode 100644 index 320645e..0000000 --- a/include/clang/Lex/MacroInfo.h +++ /dev/null @@ -1,609 +0,0 @@ -//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes. -/// -//===----------------------------------------------------------------------===// - -#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/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). -/// -/// There's an instance of this class for every #define. -class MacroInfo { - //===--------------------------------------------------------------------===// - // State set when the macro is defined. - - /// \brief The location the macro is defined. - SourceLocation Location; - /// \brief The location of the last token in the macro. - SourceLocation EndLocation; - - /// \brief The list of arguments for a function-like macro. - /// - /// ArgumentList points to the first of NumArguments pointers. - /// - /// This can be empty, for, e.g. "#define X()". In a C99-style variadic - /// macro, this includes the \c __VA_ARGS__ identifier on the list. - IdentifierInfo **ArgumentList; - - /// \see ArgumentList - unsigned NumArguments; - - /// \brief This is the list of tokens that the macro is defined to. - SmallVector<Token, 8> ReplacementTokens; - - /// \brief Length in characters of the macro definition. - mutable unsigned DefinitionLength; - mutable bool IsDefinitionLengthCached : 1; - - /// \brief True if this macro is function-like, false if it is object-like. - bool IsFunctionLike : 1; - - /// \brief True if this macro is of the form "#define X(...)" or - /// "#define X(Y,Z,...)". - /// - /// The __VA_ARGS__ token should be replaced with the contents of "..." in an - /// invocation. - bool IsC99Varargs : 1; - - /// \brief True if this macro is of the form "#define X(a...)". - /// - /// The "a" identifier in the replacement list will be replaced with all - /// arguments of the macro starting with the specified one. - bool IsGNUVarargs : 1; - - /// \brief True if this macro requires processing before expansion. - /// - /// This is the case for builtin macros such as __LINE__, so long as they have - /// not been redefined, but not for regular predefined macros from the - /// "<built-in>" memory buffer (see Preprocessing::getPredefinesFileID). - bool IsBuiltinMacro : 1; - - /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__" - bool HasCommaPasting : 1; - - //===--------------------------------------------------------------------===// - // State that changes as the macro is used. - - /// \brief True if we have started an expansion of this macro already. - /// - /// This disables recursive expansion, which would be quite bad for things - /// like \#define A A. - bool IsDisabled : 1; - - /// \brief True if this macro is either defined in the main file and has - /// been used, or if it is not defined in the main file. - /// - /// This is used to emit -Wunused-macros diagnostics. - bool IsUsed : 1; - - /// \brief True if this macro can be redefined without emitting a warning. - bool IsAllowRedefinitionsWithoutWarning : 1; - - /// \brief Must warn if the macro is unused at the end of translation unit. - bool IsWarnIfUnused : 1; - - /// \brief Whether this macro info was loaded from an AST file. - unsigned FromASTFile : 1; - - /// \brief Whether this macro was used as header guard. - bool UsedForHeaderGuard : 1; - - // Only the Preprocessor gets to create and destroy these. - MacroInfo(SourceLocation DefLoc); - ~MacroInfo() = default; - -public: - /// \brief Return the location that the macro was defined at. - SourceLocation getDefinitionLoc() const { return Location; } - - /// \brief Set the location of the last token in the macro. - void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; } - - /// \brief Return the location of the last token in the macro. - SourceLocation getDefinitionEndLoc() const { return EndLocation; } - - /// \brief Get length in characters of the macro definition. - unsigned getDefinitionLength(SourceManager &SM) const { - if (IsDefinitionLengthCached) - return DefinitionLength; - return getDefinitionLengthSlow(SM); - } - - /// \brief Return true if the specified macro definition is equal to - /// this macro in spelling, arguments, and whitespace. - /// - /// \param Syntactically if true, the macro definitions can be identical even - /// if they use different identifiers for the function macro parameters. - /// Otherwise the comparison is lexical and this implements the rules in - /// C99 6.10.3. - bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, - bool Syntactically) const; - - /// \brief Set or clear the isBuiltinMacro flag. - void setIsBuiltinMacro(bool Val = true) { IsBuiltinMacro = Val; } - - /// \brief Set the value of the IsUsed flag. - void setIsUsed(bool Val) { IsUsed = Val; } - - /// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag. - void setIsAllowRedefinitionsWithoutWarning(bool Val) { - IsAllowRedefinitionsWithoutWarning = Val; - } - - /// \brief Set the value of the IsWarnIfUnused flag. - void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; } - - /// \brief Set the specified list of identifiers as the argument list for - /// this macro. - void setArgumentList(ArrayRef<IdentifierInfo *> List, - llvm::BumpPtrAllocator &PPAllocator) { - assert(ArgumentList == nullptr && NumArguments == 0 && - "Argument list already set!"); - if (List.empty()) - return; - - NumArguments = List.size(); - ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(List.size()); - std::copy(List.begin(), List.end(), ArgumentList); - } - - /// Arguments - The list of arguments for a function-like macro. This can be - /// empty, for, e.g. "#define X()". - typedef IdentifierInfo *const *arg_iterator; - bool arg_empty() const { return NumArguments == 0; } - arg_iterator arg_begin() const { return ArgumentList; } - arg_iterator arg_end() const { return ArgumentList + NumArguments; } - unsigned getNumArgs() const { return NumArguments; } - ArrayRef<const IdentifierInfo *> args() const { - return ArrayRef<const IdentifierInfo *>(ArgumentList, NumArguments); - } - - /// \brief Return the argument number of the specified identifier, - /// or -1 if the identifier is not a formal argument identifier. - int getArgumentNum(const IdentifierInfo *Arg) const { - for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I) - if (*I == Arg) - return I - arg_begin(); - return -1; - } - - /// Function/Object-likeness. Keep track of whether this macro has formal - /// parameters. - void setIsFunctionLike() { IsFunctionLike = true; } - bool isFunctionLike() const { return IsFunctionLike; } - bool isObjectLike() const { return !IsFunctionLike; } - - /// Varargs querying methods. This can only be set for function-like macros. - void setIsC99Varargs() { IsC99Varargs = true; } - void setIsGNUVarargs() { IsGNUVarargs = true; } - bool isC99Varargs() const { return IsC99Varargs; } - bool isGNUVarargs() const { return IsGNUVarargs; } - bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; } - - /// \brief Return true if this macro requires processing before expansion. - /// - /// This is true only for builtin macro, such as \__LINE__, whose values - /// are not given by fixed textual expansions. Regular predefined macros - /// from the "<built-in>" buffer are not reported as builtins by this - /// function. - bool isBuiltinMacro() const { return IsBuiltinMacro; } - - bool hasCommaPasting() const { return HasCommaPasting; } - void setHasCommaPasting() { HasCommaPasting = true; } - - /// \brief Return false if this macro is defined in the main file and has - /// not yet been used. - bool isUsed() const { return IsUsed; } - - /// \brief Return true if this macro can be redefined without warning. - bool isAllowRedefinitionsWithoutWarning() const { - return IsAllowRedefinitionsWithoutWarning; - } - - /// \brief Return true if we should emit a warning if the macro is unused. - bool isWarnIfUnused() const { return IsWarnIfUnused; } - - /// \brief Return the number of tokens that this macro expands to. - /// - unsigned getNumTokens() const { return ReplacementTokens.size(); } - - const Token &getReplacementToken(unsigned Tok) const { - assert(Tok < ReplacementTokens.size() && "Invalid token #"); - return ReplacementTokens[Tok]; - } - - typedef SmallVectorImpl<Token>::const_iterator tokens_iterator; - 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) { - assert( - !IsDefinitionLengthCached && - "Changing replacement tokens after definition length got calculated"); - ReplacementTokens.push_back(Tok); - } - - /// \brief Return true if this macro is enabled. - /// - /// In other words, that we are not currently in an expansion of this macro. - bool isEnabled() const { return !IsDisabled; } - - void EnableMacro() { - assert(IsDisabled && "Cannot enable an already-enabled macro!"); - IsDisabled = false; - } - - void DisableMacro() { - assert(!IsDisabled && "Cannot disable an already-disabled macro!"); - IsDisabled = true; - } - - /// \brief Determine whether this macro info came from an AST file (such as - /// a precompiled header or module) rather than having been parsed. - bool isFromASTFile() const { return FromASTFile; } - - /// \brief Determine whether this macro was used for a header guard. - bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; } - - void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; } - - /// \brief Retrieve the global ID of the module that owns this particular - /// macro info. - unsigned getOwningModuleID() const { - if (isFromASTFile()) - return *(const unsigned *)(this + 1); - - return 0; - } - - void dump() const; - -private: - unsigned getDefinitionLengthSlow(SourceManager &SM) const; - - void setOwningModuleID(unsigned ID) { - assert(isFromASTFile()); - *(unsigned *)(this + 1) = ID; - } - - friend class Preprocessor; -}; - -class DefMacroDirective; - -/// \brief Encapsulates changes to the "macros namespace" (the location where -/// the macro name became active, the location where it was undefined, etc.). -/// -/// 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 #pragma push_macro / pop_macro can -/// create additional DefMacroDirectives for the same MacroInfo. -class MacroDirective { -public: - enum Kind { MD_Define, MD_Undefine, MD_Visibility }; - -protected: - /// \brief Previous macro directive for the same identifier, or NULL. - MacroDirective *Previous; - - SourceLocation Loc; - - /// \brief MacroDirective kind. - unsigned MDKind : 2; - - /// \brief True if the macro directive was loaded from a PCH file. - bool IsFromPCH : 1; - - // Used by VisibilityMacroDirective ----------------------------------------// - - /// \brief Whether the macro has public visibility (when described in a - /// module). - bool IsPublic : 1; - - MacroDirective(Kind K, SourceLocation Loc) - : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false), - IsPublic(true) {} - -public: - Kind getKind() const { return Kind(MDKind); } - - SourceLocation getLocation() const { return Loc; } - - /// \brief Set previous definition of the macro with the same name. - void setPrevious(MacroDirective *Prev) { Previous = Prev; } - - /// \brief Get previous definition of the macro with the same name. - const MacroDirective *getPrevious() const { return Previous; } - - /// \brief Get previous definition of the macro with the same name. - MacroDirective *getPrevious() { return Previous; } - - /// \brief Return true if the macro directive was loaded from a PCH file. - bool isFromPCH() const { return IsFromPCH; } - - void setIsFromPCH() { IsFromPCH = true; } - - class DefInfo { - DefMacroDirective *DefDirective; - SourceLocation UndefLoc; - bool IsPublic; - - public: - DefInfo() : DefDirective(nullptr), IsPublic(true) {} - - DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc, - bool isPublic) - : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {} - - const DefMacroDirective *getDirective() const { return DefDirective; } - DefMacroDirective *getDirective() { return DefDirective; } - - inline SourceLocation getLocation() const; - inline MacroInfo *getMacroInfo(); - const MacroInfo *getMacroInfo() const { - return const_cast<DefInfo *>(this)->getMacroInfo(); - } - - SourceLocation getUndefLocation() const { return UndefLoc; } - bool isUndefined() const { return UndefLoc.isValid(); } - - bool isPublic() const { return IsPublic; } - - bool isValid() const { return DefDirective != nullptr; } - bool isInvalid() const { return !isValid(); } - - explicit operator bool() const { return isValid(); } - - inline DefInfo getPreviousDefinition(); - const DefInfo getPreviousDefinition() const { - return const_cast<DefInfo *>(this)->getPreviousDefinition(); - } - }; - - /// \brief Traverses the macro directives history and returns the next - /// macro definition directive along with info about its undefined location - /// (if there is one) and if it is public or private. - DefInfo getDefinition(); - const DefInfo getDefinition() const { - return const_cast<MacroDirective *>(this)->getDefinition(); - } - - bool isDefined() const { - if (const DefInfo Def = getDefinition()) - return !Def.isUndefined(); - return false; - } - - const MacroInfo *getMacroInfo() const { - return getDefinition().getMacroInfo(); - } - MacroInfo *getMacroInfo() { return getDefinition().getMacroInfo(); } - - /// \brief Find macro definition active in the specified source location. If - /// this macro was not defined there, return NULL. - const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const; - - void dump() const; - - static bool classof(const MacroDirective *) { return true; } -}; - -/// \brief A directive for a defined macro or a macro imported from a module. -class DefMacroDirective : public MacroDirective { - MacroInfo *Info; - -public: - 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; } - - static bool classof(const MacroDirective *MD) { - return MD->getKind() == MD_Define; - } - static bool classof(const DefMacroDirective *) { return true; } -}; - -/// \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!"); - } - - static bool classof(const MacroDirective *MD) { - return MD->getKind() == MD_Undefine; - } - static bool classof(const UndefMacroDirective *) { return true; } -}; - -/// \brief A directive for setting the module visibility of a macro. -class VisibilityMacroDirective : public MacroDirective { -public: - explicit VisibilityMacroDirective(SourceLocation Loc, bool Public) - : MacroDirective(MD_Visibility, Loc) { - IsPublic = Public; - } - - /// \brief Determine whether this macro is part of the public API of its - /// module. - bool isPublic() const { return IsPublic; } - - static bool classof(const MacroDirective *MD) { - return MD->getKind() == MD_Visibility; - } - static bool classof(const VisibilityMacroDirective *) { return true; } -}; - -inline SourceLocation MacroDirective::DefInfo::getLocation() const { - if (isInvalid()) - return SourceLocation(); - return DefDirective->getLocation(); -} - -inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() { - if (isInvalid()) - return nullptr; - return DefDirective->getInfo(); -} - -inline MacroDirective::DefInfo -MacroDirective::DefInfo::getPreviousDefinition() { - if (isInvalid() || DefDirective->getPrevious() == nullptr) - return DefInfo(); - return DefDirective->getPrevious()->getDefinition(); -} - -/// \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 deleted file mode 100644 index ae79650..0000000 --- a/include/clang/Lex/ModuleLoader.h +++ /dev/null @@ -1,129 +0,0 @@ -//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ModuleLoader interface, which is responsible for -// loading named modules. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_MODULELOADER_H -#define LLVM_CLANG_LEX_MODULELOADER_H - -#include "clang/Basic/Module.h" -#include "clang/Basic/SourceLocation.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/PointerIntPair.h" - -namespace clang { - -class GlobalModuleIndex; -class IdentifierInfo; -class Module; - -/// \brief A sequence of identifier/location pairs used to describe a particular -/// module or submodule, e.g., std.vector. -typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath; - -/// \brief Describes the result of attempting to load a module. -class ModuleLoadResult { - llvm::PointerIntPair<Module *, 1, bool> Storage; - -public: - ModuleLoadResult() : Storage() { } - - ModuleLoadResult(Module *module, bool missingExpected) - : Storage(module, missingExpected) { } - - operator Module *() const { return Storage.getPointer(); } - - /// \brief Determines whether the module, which failed to load, was - /// actually a submodule that we expected to see (based on implying the - /// submodule from header structure), but didn't materialize in the actual - /// module. - bool isMissingExpected() const { return Storage.getInt(); } -}; - -/// \brief Abstract interface for a module loader. -/// -/// This abstract interface describes a module loader, which is responsible -/// for resolving a module name (e.g., "std") to an actual module file, and -/// then loading that module. -class ModuleLoader { - // Building a module if true. - bool BuildingModule; -public: - explicit ModuleLoader(bool BuildingModule = false) : - BuildingModule(BuildingModule), - HadFatalFailure(false) {} - - virtual ~ModuleLoader(); - - /// \brief Returns true if this instance is building a module. - bool buildingModule() const { - return BuildingModule; - } - /// \brief Flag indicating whether this instance is building a module. - void setBuildingModule(bool BuildingModuleFlag) { - BuildingModule = BuildingModuleFlag; - } - - /// \brief Attempt to load the given module. - /// - /// This routine attempts to load the module described by the given - /// parameters. - /// - /// \param ImportLoc The location of the 'import' keyword. - /// - /// \param Path The identifiers (and their locations) of the module - /// "path", e.g., "std.vector" would be split into "std" and "vector". - /// - /// \param Visibility The visibility provided for the names in the loaded - /// module. - /// - /// \param IsInclusionDirective Indicates that this module is being loaded - /// implicitly, due to the presence of an inclusion directive. Otherwise, - /// it is being loaded due to an import declaration. - /// - /// \returns If successful, returns the loaded module. Otherwise, returns - /// NULL to indicate that the module could not be loaded. - virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, - ModuleIdPath Path, - Module::NameVisibilityKind Visibility, - bool IsInclusionDirective) = 0; - - /// \brief Make the given module visible. - virtual void makeModuleVisible(Module *Mod, - Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc) = 0; - - /// \brief Load, create, or return global module. - /// This function returns an existing global module index, if one - /// had already been loaded or created, or loads one if it - /// exists, or creates one if it doesn't exist. - /// Also, importantly, if the index doesn't cover all the modules - /// in the module map, it will be update to do so here, because - /// of its use in searching for needed module imports and - /// associated fixit messages. - /// \param TriggerLoc The location for what triggered the load. - /// \returns Returns null if load failed. - virtual GlobalModuleIndex *loadGlobalModuleIndex( - SourceLocation TriggerLoc) = 0; - - /// Check global module index for missing imports. - /// \param Name The symbol name to look for. - /// \param TriggerLoc The location for what triggered the load. - /// \returns Returns true if any modules with that symbol found. - virtual bool lookupMissingImports(StringRef Name, - SourceLocation TriggerLoc) = 0; - - bool HadFatalFailure; -}; - -} - -#endif diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h deleted file mode 100644 index 155943e..0000000 --- a/include/clang/Lex/ModuleMap.h +++ /dev/null @@ -1,514 +0,0 @@ -//===--- ModuleMap.h - Describe the layout of modules -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ModuleMap interface, which describes the layout of a -// module as it relates to headers. -// -//===----------------------------------------------------------------------===// - - -#ifndef LLVM_CLANG_LEX_MODULEMAP_H -#define LLVM_CLANG_LEX_MODULEMAP_H - -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/Module.h" -#include "clang/Basic/SourceManager.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include <string> - -namespace clang { - -class DirectoryEntry; -class FileEntry; -class FileManager; -class DiagnosticConsumer; -class DiagnosticsEngine; -class HeaderSearch; -class ModuleMapParser; - -/// \brief A mechanism to observe the actions of the module map parser as it -/// reads module map files. -class ModuleMapCallbacks { -public: - virtual ~ModuleMapCallbacks() {} - - /// \brief Called when a module map file has been read. - /// - /// \param FileStart A SourceLocation referring to the start of the file's - /// contents. - /// \param File The file itself. - /// \param IsSystem Whether this is a module map from a system include path. - virtual void moduleMapFileRead(SourceLocation FileStart, - const FileEntry &File, bool IsSystem) {} -}; - -class ModuleMap { - SourceManager &SourceMgr; - DiagnosticsEngine &Diags; - const LangOptions &LangOpts; - const TargetInfo *Target; - HeaderSearch &HeaderInfo; - - llvm::SmallVector<std::unique_ptr<ModuleMapCallbacks>, 1> Callbacks; - - /// \brief The directory used for Clang-supplied, builtin include headers, - /// such as "stdint.h". - const DirectoryEntry *BuiltinIncludeDir; - - /// \brief Language options used to parse the module map itself. - /// - /// These are always simple C language options. - LangOptions MMapLangOpts; - - // The module that we are building; related to \c LangOptions::CurrentModule. - Module *CompilingModule; - -public: - // The module that the .cc source file is associated with. - Module *SourceModule; - std::string SourceModuleName; - -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 { - /// \brief This header is normally included in the module. - NormalHeader = 0x0, - /// \brief This header is included but private. - 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, - /// whether it was included or excluded. - class KnownHeader { - llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage; - - public: - KnownHeader() : Storage(nullptr, NormalHeader) { } - KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { } - - friend bool operator==(const KnownHeader &A, const KnownHeader &B) { - return A.Storage == B.Storage; - } - friend bool operator!=(const KnownHeader &A, const KnownHeader &B) { - return A.Storage != B.Storage; - } - - /// \brief Retrieve the module the header is stored in. - Module *getModule() const { return Storage.getPointer(); } - - /// \brief The role of this header within the module. - ModuleHeaderRole getRole() const { return Storage.getInt(); } - - /// \brief Whether this header is available in the module. - bool isAvailable() const { - return getModule()->isAvailable(); - } - - // \brief Whether this known header is valid (i.e., it has an - // associated module). - explicit operator bool() const { - return Storage.getPointer() != nullptr; - } - }; - - typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet; - -private: - typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> > - HeadersMap; - - /// \brief Mapping from each header to the module that owns the contents of - /// that header. - HeadersMap Headers; - - /// \brief Mapping from directories with umbrella headers to the module - /// that is generated from the umbrella header. - /// - /// This mapping is used to map headers that haven't explicitly been named - /// in the module map over to the module that includes them via its umbrella - /// 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() {} - - /// \brief Whether to infer modules from this directory. - unsigned InferModules : 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. - const FileEntry *ModuleMapFile; - - /// \brief The names of modules that cannot be inferred within this - /// directory. - SmallVector<std::string, 2> ExcludedModules; - }; - - /// \brief A mapping from directories to information about inferring - /// 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; - - friend class ModuleMapParser; - - /// \brief Resolve the given export declaration into an actual export - /// declaration. - /// - /// \param Mod The module in which we're resolving the export declaration. - /// - /// \param Unresolved The export declaration to resolve. - /// - /// \param Complain Whether this routine should complain about unresolvable - /// exports. - /// - /// \returns The resolved export declaration, which will have a NULL pointer - /// if the export could not be resolved. - Module::ExportDecl - resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved, - bool Complain) const; - - /// \brief Resolve the given module id to an actual module. - /// - /// \param Id The module-id to resolve. - /// - /// \param Mod The module in which we're resolving the module-id. - /// - /// \param Complain Whether this routine should complain about unresolvable - /// module-ids. - /// - /// \returns The resolved module, or null if the module-id could not be - /// resolved. - Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const; - - /// \brief Looks up the modules that \p File corresponds to. - /// - /// If \p File represents a builtin header within Clang's builtin include - /// directory, this also loads all of the module maps to see if it will get - /// associated with a specific module (e.g. in /usr/include). - HeadersMap::iterator findKnownHeader(const FileEntry *File); - - /// \brief Searches for a module whose umbrella directory contains \p File. - /// - /// \param File The header to search for. - /// - /// \param IntermediateDirs On success, contains the set of directories - /// searched before finding \p File. - KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File, - SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs); - - /// \brief Given that \p File is not in the Headers map, look it up within - /// umbrella directories and find or create a module for it. - KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File); - - /// \brief A convenience method to determine if \p File is (possibly nested) - /// in an umbrella directory. - bool isHeaderInUmbrellaDirs(const FileEntry *File) { - SmallVector<const DirectoryEntry *, 2> IntermediateDirs; - return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs)); - } - - Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir, - Attributes Attrs, Module *Parent); - -public: - /// \brief Construct a new module map. - /// - /// \param SourceMgr The source manager used to find module files and headers. - /// This source manager should be shared with the header-search mechanism, - /// since they will refer to the same headers. - /// - /// \param Diags A diagnostic engine used for diagnostics. - /// - /// \param LangOpts Language options for this translation unit. - /// - /// \param Target The target for this translation unit. - ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, - const LangOptions &LangOpts, const TargetInfo *Target, - HeaderSearch &HeaderInfo); - - /// \brief Destroy the module map. - /// - ~ModuleMap(); - - /// \brief Set the target information. - void setTarget(const TargetInfo &Target); - - /// \brief Set the directory that contains Clang-supplied include - /// files, such as our stdarg.h or tgmath.h. - void setBuiltinIncludeDir(const DirectoryEntry *Dir) { - BuiltinIncludeDir = Dir; - } - - /// \brief Add a module map callback. - void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) { - Callbacks.push_back(std::move(Callback)); - } - - /// \brief Retrieve the module that owns the given header file, if any. - /// - /// \param File The header file that is likely to be included. - /// - /// \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); - - /// \brief Retrieve all the modules that contain the given header file. This - /// may not include umbrella modules, nor information from external sources, - /// if they have not yet been inferred / loaded. - /// - /// Typically, \ref findModuleForHeader should be used instead, as it picks - /// the preferred module for the header. - ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File) const; - - /// \brief Reports errors if a module must not include a specific file. - /// - /// \param RequestingModule The module including a file. - /// - /// \param FilenameLoc The location of the inclusion's filename. - /// - /// \param Filename The included filename as written. - /// - /// \param File The included file. - void diagnoseHeaderInclusion(Module *RequestingModule, - SourceLocation FilenameLoc, StringRef Filename, - const FileEntry *File); - - /// \brief Determine whether the given header is part of a module - /// marked 'unavailable'. - bool isHeaderInUnavailableModule(const FileEntry *Header) const; - - /// \brief Determine whether the given header is unavailable as part - /// of the specified module. - bool isHeaderUnavailableInModule(const FileEntry *Header, - const Module *RequestingModule) const; - - /// \brief Retrieve a module with the given name. - /// - /// \param Name The name of the module to look up. - /// - /// \returns The named module, if known; otherwise, returns null. - Module *findModule(StringRef Name) const; - - /// \brief Retrieve a module with the given name using lexical name lookup, - /// starting at the given context. - /// - /// \param Name The name of the module to look up. - /// - /// \param Context The module context, from which we will perform lexical - /// name lookup. - /// - /// \returns The named module, if known; otherwise, returns null. - Module *lookupModuleUnqualified(StringRef Name, Module *Context) const; - - /// \brief Retrieve a module with the given name within the given context, - /// using direct (qualified) name lookup. - /// - /// \param Name The name of the module to look up. - /// - /// \param Context The module for which we will look for a submodule. If - /// null, we will look for a top-level module. - /// - /// \returns The named submodule, if known; otherwose, returns null. - Module *lookupModuleQualified(StringRef Name, Module *Context) const; - - /// \brief Find a new module or submodule, or create it if it does not already - /// exist. - /// - /// \param Name The name of the module to find or create. - /// - /// \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 IsFramework Whether this is a framework module. - /// - /// \param IsExplicit Whether this is an explicit submodule. - /// - /// \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, - bool IsFramework, - bool IsExplicit); - - /// \brief Infer the contents of a framework module map from the given - /// framework directory. - Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir, - bool IsSystem, Module *Parent); - - /// \brief Retrieve the module map file containing the definition of the given - /// module. - /// - /// \param Module The module whose module map file will be returned, if known. - /// - /// \returns The file entry for the module map file containing the given - /// module, or NULL if the module definition was inferred. - 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. - /// - /// \param Mod The module whose exports should be resolved. - /// - /// \param Complain Whether to emit diagnostics for failures. - /// - /// \returns true if any errors were encountered while resolving exports, - /// false otherwise. - bool resolveExports(Module *Mod, bool Complain); - - /// \brief Resolve all of the unresolved uses in the given module. - /// - /// \param Mod The module whose uses should be resolved. - /// - /// \param Complain Whether to emit diagnostics for failures. - /// - /// \returns true if any errors were encountered while resolving uses, - /// false otherwise. - bool resolveUses(Module *Mod, bool Complain); - - /// \brief Resolve all of the unresolved conflicts in the given module. - /// - /// \param Mod The module whose conflicts should be resolved. - /// - /// \param Complain Whether to emit diagnostics for failures. - /// - /// \returns true if any errors were encountered while resolving conflicts, - /// false otherwise. - bool resolveConflicts(Module *Mod, bool Complain); - - /// \brief Infers the (sub)module based on the given source location and - /// source manager. - /// - /// \param Loc The location within the source that we are querying, along - /// with its source manager. - /// - /// \returns The module that owns this source location, or null if no - /// module owns this source location. - Module *inferModuleFromLocation(FullSourceLoc Loc); - - /// \brief Sets the umbrella header of the given module to the given - /// header. - 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, - Twine NameAsWritten); - - /// \brief Adds this header to the given module. - /// \param Role The role of the header wrt the module. - void addHeader(Module *Mod, Module::Header Header, - ModuleHeaderRole Role, bool Imported = false); - - /// \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. - /// - /// \param File The file to be parsed. - /// - /// \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. - /// - /// \param ExternModuleLoc The location of the "extern module" declaration - /// that caused us to load this module map file, if any. - /// - /// \returns true if an error occurred, false otherwise. - bool parseModuleMapFile(const FileEntry *File, bool IsSystem, - const DirectoryEntry *HomeDir, - SourceLocation ExternModuleLoc = SourceLocation()); - - /// \brief Dump the contents of the module map, for debugging purposes. - void dump(); - - typedef llvm::StringMap<Module *>::const_iterator module_iterator; - module_iterator module_begin() const { return Modules.begin(); } - module_iterator module_end() const { return Modules.end(); } -}; - -} -#endif diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h deleted file mode 100644 index 83e6f99..0000000 --- a/include/clang/Lex/MultipleIncludeOpt.h +++ /dev/null @@ -1,181 +0,0 @@ -//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the MultipleIncludeOpt interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H -#define LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H - -#include "clang/Basic/SourceLocation.h" - -namespace clang { -class IdentifierInfo; - -/// \brief Implements the simple state machine that the Lexer class uses to -/// detect files subject to the 'multiple-include' optimization. -/// -/// The public methods in this class are triggered by various -/// events that occur when a file is lexed, and after the entire file is lexed, -/// information about which macro (if any) controls the header is returned. -class MultipleIncludeOpt { - /// ReadAnyTokens - This is set to false when a file is first opened and true - /// any time a token is returned to the client or a (non-multiple-include) - /// directive is parsed. When the final \#endif is parsed this is reset back - /// to false, that way any tokens before the first \#ifdef or after the last - /// \#endif can be easily detected. - bool ReadAnyTokens; - - /// ImmediatelyAfterTopLevelIfndef - This is true when the only tokens - /// processed in the file so far is an #ifndef and an identifier. Used in - /// the detection of header guards in a file. - bool ImmediatelyAfterTopLevelIfndef; - - /// ReadAnyTokens - This is set to false when a file is first opened and true - /// any time a token is returned to the client or a (non-multiple-include) - /// directive is parsed. When the final #endif is parsed this is reset back - /// to false, that way any tokens before the first #ifdef or after the last - /// #endif can be easily detected. - bool DidMacroExpansion; - - /// TheMacro - The controlling macro for a file, if valid. - /// - const IdentifierInfo *TheMacro; - - /// DefinedMacro - The macro defined right after TheMacro, if any. - const IdentifierInfo *DefinedMacro; - - SourceLocation MacroLoc; - SourceLocation DefinedLoc; -public: - MultipleIncludeOpt() { - ReadAnyTokens = false; - ImmediatelyAfterTopLevelIfndef = false; - DidMacroExpansion = false; - TheMacro = nullptr; - DefinedMacro = nullptr; - } - - SourceLocation GetMacroLocation() const { - return MacroLoc; - } - - SourceLocation GetDefinedLocation() const { - return DefinedLoc; - } - - void resetImmediatelyAfterTopLevelIfndef() { - ImmediatelyAfterTopLevelIfndef = false; - } - - void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc) { - DefinedMacro = M; - DefinedLoc = Loc; - } - - /// Invalidate - Permanently mark this file as not being suitable for the - /// include-file optimization. - void Invalidate() { - // If we have read tokens but have no controlling macro, the state-machine - // below can never "accept". - ReadAnyTokens = true; - ImmediatelyAfterTopLevelIfndef = false; - DefinedMacro = nullptr; - TheMacro = nullptr; - } - - /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the - /// top of the file when reading preprocessor directives. Otherwise, reading - /// the "ifndef x" would count as reading tokens. - bool getHasReadAnyTokensVal() const { return ReadAnyTokens; } - - /// getImmediatelyAfterTopLevelIfndef - returns true if the last directive - /// was an #ifndef at the beginning of the file. - bool getImmediatelyAfterTopLevelIfndef() const { - return ImmediatelyAfterTopLevelIfndef; - } - - // If a token is read, remember that we have seen a side-effect in this file. - void ReadToken() { - ReadAnyTokens = true; - ImmediatelyAfterTopLevelIfndef = false; - } - - /// ExpandedMacro - When a macro is expanded with this lexer as the current - /// buffer, this method is called to disable the MIOpt if needed. - void ExpandedMacro() { DidMacroExpansion = true; } - - /// \brief Called when entering a top-level \#ifndef directive (or the - /// "\#if !defined" equivalent) without any preceding tokens. - /// - /// Note, we don't care about the input value of 'ReadAnyTokens'. The caller - /// ensures that this is only called if there are no tokens read before the - /// \#ifndef. The caller is required to do this, because reading the \#if - /// line obviously reads in in tokens. - void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) { - // If the macro is already set, this is after the top-level #endif. - if (TheMacro) - return Invalidate(); - - // If we have already expanded a macro by the end of the #ifndef line, then - // there is a macro expansion *in* the #ifndef line. This means that the - // condition could evaluate differently when subsequently #included. Reject - // this. - if (DidMacroExpansion) - return Invalidate(); - - // Remember that we're in the #if and that we have the macro. - ReadAnyTokens = true; - ImmediatelyAfterTopLevelIfndef = true; - TheMacro = M; - MacroLoc = Loc; - } - - /// \brief Invoked when a top level conditional (except \#ifndef) is found. - void EnterTopLevelConditional() { - // If a conditional directive (except #ifndef) is found at the top level, - // there is a chunk of the file not guarded by the controlling macro. - Invalidate(); - } - - /// \brief Called when the lexer exits the top-level conditional. - void ExitTopLevelConditional() { - // If we have a macro, that means the top of the file was ok. Set our state - // back to "not having read any tokens" so we can detect anything after the - // #endif. - if (!TheMacro) return Invalidate(); - - // At this point, we haven't "read any tokens" but we do have a controlling - // macro. - ReadAnyTokens = false; - ImmediatelyAfterTopLevelIfndef = false; - } - - /// \brief Once the entire file has been lexed, if there is a controlling - /// macro, return it. - const IdentifierInfo *GetControllingMacroAtEndOfFile() const { - // If we haven't read any tokens after the #endif, return the controlling - // macro if it's valid (if it isn't, it will be null). - if (!ReadAnyTokens) - return TheMacro; - return nullptr; - } - - /// \brief If the ControllingMacro is followed by a macro definition, return - /// the macro that was defined. - const IdentifierInfo *GetDefinedMacro() const { - return DefinedMacro; - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h deleted file mode 100644 index 68b8f1c..0000000 --- a/include/clang/Lex/PPCallbacks.h +++ /dev/null @@ -1,509 +0,0 @@ -//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the PPCallbacks interface. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H -#define LLVM_CLANG_LEX_PPCALLBACKS_H - -#include "clang/Basic/DiagnosticIDs.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Lex/DirectoryLookup.h" -#include "clang/Lex/ModuleLoader.h" -#include "clang/Lex/Pragma.h" -#include "llvm/ADT/StringRef.h" -#include <string> - -namespace clang { - class SourceLocation; - class Token; - class IdentifierInfo; - class MacroDefinition; - class MacroDirective; - class MacroArgs; - -/// \brief This interface provides a way to observe the actions of the -/// preprocessor as it does its thing. -/// -/// Clients can define their hooks here to implement preprocessor level tools. -class PPCallbacks { -public: - virtual ~PPCallbacks(); - - enum FileChangeReason { - EnterFile, ExitFile, SystemHeaderPragma, RenameFile - }; - - /// \brief Callback invoked whenever a source file is entered or exited. - /// - /// \param Loc Indicates the new location. - /// \param PrevFID the file that was exited if \p Reason is ExitFile. - virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType, - FileID PrevFID = FileID()) { - } - - /// \brief Callback invoked whenever a source file is skipped as the result - /// of header guard optimization. - /// - /// \param SkippedFile The file that is skipped instead of entering \#include - /// - /// \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) { - } - - /// \brief Callback invoked whenever an inclusion directive results in a - /// file-not-found error. - /// - /// \param FileName The name of the file being included, as written in the - /// source code. - /// - /// \param RecoveryPath If this client indicates that it can recover from - /// this missing file, the client should set this as an additional header - /// search patch. - /// - /// \returns true to indicate that the preprocessor should attempt to recover - /// by adding \p RecoveryPath as a header search path. - virtual bool FileNotFound(StringRef FileName, - SmallVectorImpl<char> &RecoveryPath) { - return false; - } - - /// \brief Callback invoked whenever an inclusion directive of - /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless - /// of whether the inclusion will actually result in an inclusion. - /// - /// \param HashLoc The location of the '#' that starts the inclusion - /// directive. - /// - /// \param IncludeTok The token that indicates the kind of inclusion - /// directive, e.g., 'include' or 'import'. - /// - /// \param FileName The name of the file being included, as written in the - /// source code. - /// - /// \param IsAngled Whether the file name was enclosed in angle brackets; - /// otherwise, it was enclosed in quotes. - /// - /// \param FilenameRange The character range of the quotes or angle brackets - /// for the written file name. - /// - /// \param File The actual file that may be included by this inclusion - /// directive. - /// - /// \param SearchPath Contains the search path which was used to find the file - /// in the file system. If the file was found via an absolute include path, - /// SearchPath will be empty. For framework includes, the SearchPath and - /// RelativePath will be split up. For example, if an include of "Some/Some.h" - /// is found via the framework path - /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be - /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be - /// "Some.h". - /// - /// \param RelativePath The path relative to SearchPath, at which the include - /// file was found. This is equal to FileName except for framework includes. - /// - /// \param Imported The module, whenever an inclusion directive was - /// automatically turned into a module import or null otherwise. - /// - virtual void InclusionDirective(SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - const FileEntry *File, - StringRef SearchPath, - StringRef RelativePath, - const Module *Imported) { - } - - /// \brief Callback invoked whenever there was an explicit module-import - /// syntax. - /// - /// \param ImportLoc The location of import directive token. - /// - /// \param Path The identifiers (and their locations) of the module - /// "path", e.g., "std.vector" would be split into "std" and "vector". - /// - /// \param Imported The imported module; can be null if importing failed. - /// - virtual void moduleImport(SourceLocation ImportLoc, - ModuleIdPath Path, - const Module *Imported) { - } - - /// \brief Callback invoked when the end of the main file is reached. - /// - /// No subsequent callbacks will be made. - virtual void EndOfMainFile() { - } - - /// \brief Callback invoked when a \#ident or \#sccs directive is read. - /// \param Loc The location of the directive. - /// \param str The text of the directive. - /// - virtual void Ident(SourceLocation Loc, StringRef str) { - } - - /// \brief Callback invoked when start reading any pragma directive. - virtual void PragmaDirective(SourceLocation Loc, - PragmaIntroducerKind Introducer) { - } - - /// \brief Callback invoked when a \#pragma comment directive is read. - virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - StringRef Str) { - } - - /// \brief Callback invoked when a \#pragma detect_mismatch directive is - /// read. - virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, - StringRef Value) { - } - - /// \brief Callback invoked when a \#pragma clang __debug directive is read. - /// \param Loc The location of the debug directive. - /// \param DebugType The identifier following __debug. - virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) { - } - - /// \brief Determines the kind of \#pragma invoking a call to PragmaMessage. - enum PragmaMessageKind { - /// \brief \#pragma message has been invoked. - PMK_Message, - - /// \brief \#pragma GCC warning has been invoked. - PMK_Warning, - - /// \brief \#pragma GCC error has been invoked. - PMK_Error - }; - - /// \brief Callback invoked when a \#pragma message directive is read. - /// \param Loc The location of the message directive. - /// \param Namespace The namespace of the message directive. - /// \param Kind The type of the message directive. - /// \param Str The text of the message directive. - virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, - PragmaMessageKind Kind, StringRef Str) { - } - - /// \brief Callback invoked when a \#pragma gcc diagnostic push directive - /// is read. - virtual void PragmaDiagnosticPush(SourceLocation Loc, - StringRef Namespace) { - } - - /// \brief Callback invoked when a \#pragma gcc diagnostic pop directive - /// is read. - virtual void PragmaDiagnosticPop(SourceLocation Loc, - StringRef Namespace) { - } - - /// \brief Callback invoked when a \#pragma gcc diagnostic directive is read. - virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, - diag::Severity mapping, StringRef Str) {} - - /// \brief Called when an OpenCL extension is either disabled or - /// enabled with a pragma. - virtual void PragmaOpenCLExtension(SourceLocation NameLoc, - const IdentifierInfo *Name, - SourceLocation StateLoc, unsigned State) { - } - - /// \brief Callback invoked when a \#pragma warning directive is read. - virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, - ArrayRef<int> Ids) { - } - - /// \brief Callback invoked when a \#pragma warning(push) directive is read. - virtual void PragmaWarningPush(SourceLocation Loc, int Level) { - } - - /// \brief Callback invoked when a \#pragma warning(pop) directive is read. - virtual void PragmaWarningPop(SourceLocation Loc) { - } - - /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a - /// macro invocation is found. - 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, - const MacroDirective *MD) { - } - - /// \brief Hook called whenever a macro \#undef is seen. - /// - /// MD is released immediately following this callback. - virtual void MacroUndefined(const Token &MacroNameTok, - 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 MacroDefinition &MD, - SourceRange Range) { - } - - /// \brief Hook called when a source range is skipped. - /// \param Range The SourceRange that was skipped. The range begins at the - /// \#if/\#else directive and ends after the \#endif/\#else directive. - virtual void SourceRangeSkipped(SourceRange Range) { - } - - enum ConditionValueKind { - CVK_NotEvaluated, CVK_False, CVK_True - }; - - /// \brief Hook called whenever an \#if is seen. - /// \param Loc the source location of the directive. - /// \param ConditionRange The SourceRange of the expression being tested. - /// \param ConditionValue The evaluated value of the condition. - /// - // FIXME: better to pass in a list (or tree!) of Tokens. - virtual void If(SourceLocation Loc, SourceRange ConditionRange, - ConditionValueKind ConditionValue) { - } - - /// \brief Hook called whenever an \#elif is seen. - /// \param Loc the source location of the directive. - /// \param ConditionRange The SourceRange of the expression being tested. - /// \param ConditionValue The evaluated value of the condition. - /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. - // FIXME: better to pass in a list (or tree!) of Tokens. - virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - ConditionValueKind ConditionValue, SourceLocation IfLoc) { - } - - /// \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 MacroDefinition if the name was a macro, null otherwise. - virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - 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 MacroDefiniton if the name was a macro, null otherwise. - virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDefinition &MD) { - } - - /// \brief Hook called whenever an \#else is seen. - /// \param Loc the source location of the directive. - /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. - virtual void Else(SourceLocation Loc, SourceLocation IfLoc) { - } - - /// \brief Hook called whenever an \#endif is seen. - /// \param Loc the source location of the directive. - /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. - virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) { - } -}; - -/// \brief Simple wrapper class for chaining callbacks. -class PPChainedCallbacks : public PPCallbacks { - virtual void anchor(); - std::unique_ptr<PPCallbacks> First, Second; - -public: - 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, - FileID PrevFID) override { - First->FileChanged(Loc, Reason, FileType, PrevFID); - Second->FileChanged(Loc, Reason, FileType, PrevFID); - } - - void FileSkipped(const FileEntry &SkippedFile, - const Token &FilenameTok, - SrcMgr::CharacteristicKind FileType) override { - First->FileSkipped(SkippedFile, FilenameTok, FileType); - Second->FileSkipped(SkippedFile, FilenameTok, FileType); - } - - bool FileNotFound(StringRef FileName, - SmallVectorImpl<char> &RecoveryPath) override { - return First->FileNotFound(FileName, RecoveryPath) || - Second->FileNotFound(FileName, RecoveryPath); - } - - void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, - StringRef FileName, bool IsAngled, - CharSourceRange FilenameRange, const FileEntry *File, - StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override { - First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, - FilenameRange, File, SearchPath, RelativePath, - Imported); - Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, - FilenameRange, File, SearchPath, RelativePath, - Imported); - } - - void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, - const Module *Imported) override { - First->moduleImport(ImportLoc, Path, Imported); - Second->moduleImport(ImportLoc, Path, Imported); - } - - void EndOfMainFile() override { - First->EndOfMainFile(); - Second->EndOfMainFile(); - } - - void Ident(SourceLocation Loc, StringRef str) override { - First->Ident(Loc, str); - Second->Ident(Loc, str); - } - - void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - StringRef Str) override { - First->PragmaComment(Loc, Kind, Str); - Second->PragmaComment(Loc, Kind, Str); - } - - void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, - StringRef Value) override { - First->PragmaDetectMismatch(Loc, Name, Value); - Second->PragmaDetectMismatch(Loc, Name, Value); - } - - void PragmaMessage(SourceLocation Loc, StringRef Namespace, - PragmaMessageKind Kind, StringRef Str) override { - First->PragmaMessage(Loc, Namespace, Kind, Str); - Second->PragmaMessage(Loc, Namespace, Kind, Str); - } - - void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override { - First->PragmaDiagnosticPush(Loc, Namespace); - Second->PragmaDiagnosticPush(Loc, Namespace); - } - - void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override { - First->PragmaDiagnosticPop(Loc, Namespace); - Second->PragmaDiagnosticPop(Loc, Namespace); - } - - void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, - diag::Severity mapping, StringRef Str) override { - First->PragmaDiagnostic(Loc, Namespace, mapping, Str); - Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); - } - - void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, - SourceLocation StateLoc, unsigned State) override { - First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); - Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); - } - - void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, - ArrayRef<int> Ids) override { - First->PragmaWarning(Loc, WarningSpec, Ids); - Second->PragmaWarning(Loc, WarningSpec, Ids); - } - - void PragmaWarningPush(SourceLocation Loc, int Level) override { - First->PragmaWarningPush(Loc, Level); - Second->PragmaWarningPush(Loc, Level); - } - - void PragmaWarningPop(SourceLocation Loc) override { - First->PragmaWarningPop(Loc); - Second->PragmaWarningPop(Loc); - } - - 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); - } - - void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override { - First->MacroDefined(MacroNameTok, MD); - Second->MacroDefined(MacroNameTok, MD); - } - - void MacroUndefined(const Token &MacroNameTok, - const MacroDefinition &MD) override { - First->MacroUndefined(MacroNameTok, MD); - Second->MacroUndefined(MacroNameTok, MD); - } - - void Defined(const Token &MacroNameTok, const MacroDefinition &MD, - SourceRange Range) override { - First->Defined(MacroNameTok, MD, Range); - Second->Defined(MacroNameTok, MD, Range); - } - - void SourceRangeSkipped(SourceRange Range) override { - First->SourceRangeSkipped(Range); - Second->SourceRangeSkipped(Range); - } - - /// \brief Hook called whenever an \#if is seen. - void If(SourceLocation Loc, SourceRange ConditionRange, - ConditionValueKind ConditionValue) override { - First->If(Loc, ConditionRange, ConditionValue); - Second->If(Loc, ConditionRange, ConditionValue); - } - - /// \brief Hook called whenever an \#elif is seen. - void Elif(SourceLocation Loc, SourceRange ConditionRange, - ConditionValueKind ConditionValue, SourceLocation IfLoc) override { - First->Elif(Loc, ConditionRange, ConditionValue, IfLoc); - Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc); - } - - /// \brief Hook called whenever an \#ifdef is seen. - void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - 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 MacroDefinition &MD) override { - First->Ifndef(Loc, MacroNameTok, MD); - Second->Ifndef(Loc, MacroNameTok, MD); - } - - /// \brief Hook called whenever an \#else is seen. - void Else(SourceLocation Loc, SourceLocation IfLoc) override { - First->Else(Loc, IfLoc); - Second->Else(Loc, IfLoc); - } - - /// \brief Hook called whenever an \#endif is seen. - void Endif(SourceLocation Loc, SourceLocation IfLoc) override { - First->Endif(Loc, IfLoc); - Second->Endif(Loc, IfLoc); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h deleted file mode 100644 index 8c52275..0000000 --- a/include/clang/Lex/PPConditionalDirectiveRecord.h +++ /dev/null @@ -1,103 +0,0 @@ -//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PPConditionalDirectiveRecord class, which maintains -// a record of conditional directive regions. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H -#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H - -#include "clang/Basic/SourceLocation.h" -#include "clang/Lex/PPCallbacks.h" -#include "llvm/ADT/SmallVector.h" -#include <vector> - -namespace clang { - -/// \brief Records preprocessor conditional directive regions and allows -/// querying in which region source locations belong to. -class PPConditionalDirectiveRecord : public PPCallbacks { - SourceManager &SourceMgr; - - SmallVector<SourceLocation, 6> CondDirectiveStack; - - class CondDirectiveLoc { - SourceLocation Loc; - SourceLocation RegionLoc; - - public: - CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc) - : Loc(Loc), RegionLoc(RegionLoc) {} - - SourceLocation getLoc() const { return Loc; } - SourceLocation getRegionLoc() const { return RegionLoc; } - - class Comp { - SourceManager &SM; - public: - explicit Comp(SourceManager &SM) : SM(SM) {} - bool operator()(const CondDirectiveLoc &LHS, - const CondDirectiveLoc &RHS) { - return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc()); - } - bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) { - return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS); - } - bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) { - return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc()); - } - }; - }; - - typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy; - /// \brief The locations of conditional directives in source order. - CondDirectiveLocsTy CondDirectiveLocs; - - void addCondDirectiveLoc(CondDirectiveLoc DirLoc); - -public: - /// \brief Construct a new preprocessing record. - explicit PPConditionalDirectiveRecord(SourceManager &SM); - - size_t getTotalMemory() const; - - SourceManager &getSourceManager() const { return SourceMgr; } - - /// \brief Returns true if the given range intersects with a conditional - /// directive. if a \#if/\#endif block is fully contained within the range, - /// this function will return false. - bool rangeIntersectsConditionalDirective(SourceRange Range) const; - - /// \brief Returns true if the given locations are in different regions, - /// separated by conditional directive blocks. - bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS, - SourceLocation RHS) const { - return findConditionalDirectiveRegionLoc(LHS) != - findConditionalDirectiveRegionLoc(RHS); - } - - SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const; - -private: - void If(SourceLocation Loc, SourceRange ConditionRange, - ConditionValueKind ConditionValue) override; - void Elif(SourceLocation Loc, SourceRange ConditionRange, - ConditionValueKind ConditionValue, SourceLocation IfLoc) override; - void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDefinition &MD) override; - void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDefinition &MD) override; - void Else(SourceLocation Loc, SourceLocation IfLoc) override; - void Endif(SourceLocation Loc, SourceLocation IfLoc) override; -}; - -} // end namespace clang - -#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h deleted file mode 100644 index 904be79..0000000 --- a/include/clang/Lex/PTHLexer.h +++ /dev/null @@ -1,104 +0,0 @@ -//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PTHLexer interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PTHLEXER_H -#define LLVM_CLANG_LEX_PTHLEXER_H - -#include "clang/Lex/PreprocessorLexer.h" - -namespace clang { - -class PTHManager; -class PTHSpellingSearch; - -class PTHLexer : public PreprocessorLexer { - SourceLocation FileStartLoc; - - /// TokBuf - Buffer from PTH file containing raw token data. - const unsigned char* TokBuf; - - /// CurPtr - Pointer into current offset of the token buffer where - /// the next token will be read. - const unsigned char* CurPtr; - - /// LastHashTokPtr - Pointer into TokBuf of the last processed '#' - /// token that appears at the start of a line. - const unsigned char* LastHashTokPtr; - - /// PPCond - Pointer to a side table in the PTH file that provides a - /// a consise summary of the preproccessor conditional block structure. - /// This is used to perform quick skipping of conditional blocks. - const unsigned char* PPCond; - - /// CurPPCondPtr - Pointer inside PPCond that refers to the next entry - /// to process when doing quick skipping of preprocessor blocks. - const unsigned char* CurPPCondPtr; - - PTHLexer(const PTHLexer &) = delete; - void operator=(const PTHLexer &) = delete; - - /// ReadToken - Used by PTHLexer to read tokens TokBuf. - void ReadToken(Token& T); - - bool LexEndOfFile(Token &Result); - - /// PTHMgr - The PTHManager object that created this PTHLexer. - PTHManager& PTHMgr; - - Token EofToken; - -protected: - friend class PTHManager; - - /// Create a PTHLexer for the specified token stream. - PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D, - const unsigned char* ppcond, PTHManager &PM); -public: - ~PTHLexer() override {} - - /// Lex - Return the next token. - bool Lex(Token &Tok); - - void getEOF(Token &Tok); - - /// DiscardToEndOfLine - Read the rest of the current preprocessor line as an - /// uninterpreted string. This switches the lexer out of directive mode. - void DiscardToEndOfLine(); - - /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a - /// tok::l_paren token, 0 if it is something else and 2 if there are no more - /// tokens controlled by this lexer. - unsigned isNextPPTokenLParen() { - // isNextPPTokenLParen is not on the hot path, and all we care about is - // whether or not we are at a token with kind tok::eof or tok::l_paren. - // Just read the first byte from the current token pointer to determine - // its kind. - tok::TokenKind x = (tok::TokenKind)*CurPtr; - return x == tok::eof ? 2 : x == tok::l_paren; - } - - /// IndirectLex - An indirect call to 'Lex' that can be invoked via - /// the PreprocessorLexer interface. - void IndirectLex(Token &Result) override { Lex(Result); } - - /// getSourceLocation - Return a source location for the token in - /// the current file. - SourceLocation getSourceLocation() override; - - /// SkipBlock - Used by Preprocessor to skip the current conditional block. - bool SkipBlock(); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h deleted file mode 100644 index 26178ed..0000000 --- a/include/clang/Lex/PTHManager.h +++ /dev/null @@ -1,150 +0,0 @@ -//===--- PTHManager.h - Manager object for PTH processing -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PTHManager interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PTHMANAGER_H -#define LLVM_CLANG_LEX_PTHMANAGER_H - -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/IdentifierTable.h" -#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> - -namespace llvm { - class MemoryBuffer; -} - -namespace clang { - -class FileEntry; -class PTHLexer; -class DiagnosticsEngine; -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. - 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*. - std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> PerIDCache; - - /// FileLookup - Abstract data structure used for mapping between files - /// and token data in the PTH file. - 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 - /// reconsitute an IdentifierInfo. - const unsigned char* const IdDataTable; - - /// SortedIdTable - Abstract data structure mapping from strings to - /// persistent IDs. This is used by get(). - std::unique_ptr<PTHStringIdLookup> StringIdLookup; - - /// NumIds - The number of identifiers in the PTH file. - const unsigned NumIds; - - /// PP - The Preprocessor object that will use this PTHManager to create - /// PTHLexer objects. - Preprocessor* PP; - - /// SpellingBase - The base offset within the PTH memory buffer that - /// contains the cached spellings for literals. - const unsigned char* const SpellingBase; - - /// OriginalSourceFile - A null-terminated C-string that specifies the name - /// if the file (if any) that was to used to generate the PTH cache. - const char* OriginalSourceFile; - - /// This constructor is intended to only be called by the static 'Create' - /// method. - 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 &) = delete; - void operator=(const PTHManager &) = delete; - - /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached - /// spelling for a token. - unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer); - - /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the - /// PTH file. - inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) { - // Check if the IdentifierInfo has already been resolved. - if (IdentifierInfo* II = PerIDCache[PersistentID]) - return II; - return LazilyCreateIdentifierInfo(PersistentID); - } - IdentifierInfo* LazilyCreateIdentifierInfo(unsigned PersistentID); - -public: - // The current PTH version. - enum { Version = 10 }; - - ~PTHManager() override; - - /// getOriginalSourceFile - Return the full path to the original header - /// file name that was used to generate the PTH cache. - const char* getOriginalSourceFile() const { - return OriginalSourceFile; - } - - /// get - Return the identifier token info for the specified named identifier. - /// Unlike the version in IdentifierTable, this returns a pointer instead - /// of a reference. If the pointer is NULL then the IdentifierInfo cannot - /// be found. - IdentifierInfo *get(StringRef Name) override; - - /// Create - This method creates PTHManager objects. The 'file' argument - /// is the name of the PTH file. This method returns NULL upon failure. - static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags); - - void setPreprocessor(Preprocessor *pp) { PP = pp; } - - /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the - /// specified file. This method returns NULL if no cached tokens exist. - /// It is the responsibility of the caller to 'delete' the returned object. - PTHLexer *CreateLexer(FileID FID); - - /// createStatCache - Returns a FileSystemStatCache object for use with - /// 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. - std::unique_ptr<FileSystemStatCache> createStatCache(); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h deleted file mode 100644 index 274f0da..0000000 --- a/include/clang/Lex/Pragma.h +++ /dev/null @@ -1,126 +0,0 @@ -//===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PragmaHandler and PragmaTable interfaces. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PRAGMA_H -#define LLVM_CLANG_LEX_PRAGMA_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include <cassert> - -namespace clang { - class Preprocessor; - class Token; - class IdentifierInfo; - class PragmaNamespace; - - /** - * \brief Describes how the pragma was introduced, e.g., with \#pragma, - * _Pragma, or __pragma. - */ - enum PragmaIntroducerKind { - /** - * \brief The pragma was introduced via \#pragma. - */ - PIK_HashPragma, - - /** - * \brief The pragma was introduced via the C99 _Pragma(string-literal). - */ - PIK__Pragma, - - /** - * \brief The pragma was introduced via the Microsoft - * __pragma(token-string). - */ - PIK___pragma - }; - -/// PragmaHandler - Instances of this interface defined to handle the various -/// pragmas that the language front-end uses. Each handler optionally has a -/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with -/// that identifier is found. If a handler does not match any of the declared -/// pragmas the handler with a null identifier is invoked, if it exists. -/// -/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g. -/// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other -/// pragmas. -class PragmaHandler { - std::string Name; -public: - explicit PragmaHandler(StringRef name) : Name(name) {} - PragmaHandler() {} - virtual ~PragmaHandler(); - - StringRef getName() const { return Name; } - virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &FirstToken) = 0; - - /// getIfNamespace - If this is a namespace, return it. This is equivalent to - /// using a dynamic_cast, but doesn't require RTTI. - virtual PragmaNamespace *getIfNamespace() { return nullptr; } -}; - -/// EmptyPragmaHandler - A pragma handler which takes no action, which can be -/// used to ignore particular pragmas. -class EmptyPragmaHandler : public PragmaHandler { -public: - explicit EmptyPragmaHandler(StringRef Name = StringRef()); - - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &FirstToken) override; -}; - -/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, -/// allowing hierarchical pragmas to be defined. Common examples of namespaces -/// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces -/// may be (potentially recursively) defined. -class PragmaNamespace : public PragmaHandler { - /// Handlers - This is a map of the handlers in this namespace with their name - /// as key. - /// - llvm::StringMap<PragmaHandler*> Handlers; -public: - explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {} - ~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 - /// exists, otherwise return null. If IgnoreNull is true (the default) then - /// the null handler isn't returned on failure to match. - PragmaHandler *FindHandler(StringRef Name, - bool IgnoreNull = true) const; - - /// AddPragma - Add a pragma to this namespace. - /// - void AddPragma(PragmaHandler *Handler); - - /// RemovePragmaHandler - Remove the given handler from the - /// namespace. - void RemovePragmaHandler(PragmaHandler *Handler); - - bool IsEmpty() { - return Handlers.empty(); - } - - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &FirstToken) override; - - PragmaNamespace *getIfNamespace() override { return this; } -}; - - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h deleted file mode 100644 index 87b8ce1..0000000 --- a/include/clang/Lex/PreprocessingRecord.h +++ /dev/null @@ -1,536 +0,0 @@ -//===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PreprocessingRecord class, which maintains a record -// of what occurred during preprocessing. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H -#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H - -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Lex/PPCallbacks.h" -#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> - -namespace clang { - class IdentifierInfo; - class MacroInfo; - class PreprocessingRecord; -} - -/// \brief Allocates memory within a Clang preprocessing record. -void *operator new(size_t bytes, clang::PreprocessingRecord &PR, - unsigned alignment = 8) LLVM_NOEXCEPT; - -/// \brief Frees memory allocated in a Clang preprocessing record. -void operator delete(void *ptr, clang::PreprocessingRecord &PR, - unsigned) LLVM_NOEXCEPT; - -namespace clang { - class MacroDefinitionRecord; - class FileEntry; - - /// \brief Base class that describes a preprocessed entity, which may be a - /// preprocessor directive or macro expansion. - class PreprocessedEntity { - public: - /// \brief The kind of preprocessed entity an object describes. - enum EntityKind { - /// \brief Indicates a problem trying to load the preprocessed entity. - InvalidKind, - - /// \brief A macro expansion. - MacroExpansionKind, - - /// \defgroup Preprocessing directives - /// @{ - - /// \brief A macro definition. - MacroDefinitionKind, - - /// \brief An inclusion directive, such as \c \#include, \c - /// \#import, or \c \#include_next. - InclusionDirectiveKind, - - /// @} - - FirstPreprocessingDirective = MacroDefinitionKind, - LastPreprocessingDirective = InclusionDirectiveKind - }; - - private: - /// \brief The kind of preprocessed entity that this object describes. - EntityKind Kind; - - /// \brief The source range that covers this preprocessed entity. - SourceRange Range; - - protected: - PreprocessedEntity(EntityKind Kind, SourceRange Range) - : Kind(Kind), Range(Range) { } - - friend class PreprocessingRecord; - - public: - /// \brief Retrieve the kind of preprocessed entity stored in this object. - EntityKind getKind() const { return Kind; } - - /// \brief Retrieve the source range that covers this entire preprocessed - /// entity. - SourceRange getSourceRange() const LLVM_READONLY { return Range; } - - /// \brief Returns true if there was a problem loading the preprocessed - /// entity. - bool isInvalid() const { return Kind == InvalidKind; } - - // Only allow allocation of preprocessed entities using the allocator - // in PreprocessingRecord or by doing a placement new. - void *operator new(size_t bytes, PreprocessingRecord &PR, - unsigned alignment = 8) LLVM_NOEXCEPT { - return ::operator new(bytes, PR, alignment); - } - - void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; } - - void operator delete(void *ptr, PreprocessingRecord &PR, - unsigned alignment) LLVM_NOEXCEPT { - return ::operator delete(ptr, PR, alignment); - } - - void operator delete(void *, std::size_t) LLVM_NOEXCEPT {} - void operator delete(void *, void *) LLVM_NOEXCEPT {} - - private: - // Make vanilla 'new' and 'delete' illegal for preprocessed entities. - void *operator new(size_t bytes) LLVM_NOEXCEPT; - void operator delete(void *data) LLVM_NOEXCEPT; - }; - - /// \brief Records the presence of a preprocessor directive. - class PreprocessingDirective : public PreprocessedEntity { - public: - PreprocessingDirective(EntityKind Kind, SourceRange Range) - : PreprocessedEntity(Kind, Range) { } - - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *PD) { - return PD->getKind() >= FirstPreprocessingDirective && - PD->getKind() <= LastPreprocessingDirective; - } - }; - - /// \brief Record the location of a macro definition. - class MacroDefinitionRecord : public PreprocessingDirective { - /// \brief The name of the macro being defined. - const IdentifierInfo *Name; - - public: - 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(); } - - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *PE) { - return PE->getKind() == MacroDefinitionKind; - } - }; - - /// \brief Records the location of a macro expansion. - 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 *, MacroDefinitionRecord *> NameOrDef; - - public: - MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) - : PreprocessedEntity(MacroExpansionKind, Range), - NameOrDef(BuiltinName) {} - - 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 (MacroDefinitionRecord *Def = getDefinition()) - return Def->getName(); - return NameOrDef.get<IdentifierInfo *>(); - } - - /// \brief The definition of the macro being expanded. May return null if - /// this is a builtin macro. - MacroDefinitionRecord *getDefinition() const { - return NameOrDef.dyn_cast<MacroDefinitionRecord *>(); - } - - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *PE) { - return PE->getKind() == MacroExpansionKind; - } - }; - - /// \brief Record the location of an inclusion directive, such as an - /// \c \#include or \c \#import statement. - class InclusionDirective : public PreprocessingDirective { - public: - /// \brief The kind of inclusion directives known to the - /// preprocessor. - enum InclusionKind { - /// \brief An \c \#include directive. - Include, - /// \brief An Objective-C \c \#import directive. - Import, - /// \brief A GNU \c \#include_next directive. - IncludeNext, - /// \brief A Clang \c \#__include_macros directive. - IncludeMacros - }; - - private: - /// \brief The name of the file that was included, as written in - /// the source. - StringRef FileName; - - /// \brief Whether the file name was in quotation marks; otherwise, it was - /// in angle brackets. - unsigned InQuotes : 1; - - /// \brief The kind of inclusion directive we have. - /// - /// This is a value of type InclusionKind. - unsigned Kind : 2; - - /// \brief Whether the inclusion directive was automatically turned into - /// a module import. - unsigned ImportedModule : 1; - - /// \brief The file that was included. - const FileEntry *File; - - public: - InclusionDirective(PreprocessingRecord &PPRec, - InclusionKind Kind, StringRef FileName, - bool InQuotes, bool ImportedModule, - const FileEntry *File, SourceRange Range); - - /// \brief Determine what kind of inclusion directive this is. - InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); } - - /// \brief Retrieve the included file name as it was written in the source. - StringRef getFileName() const { return FileName; } - - /// \brief Determine whether the included file name was written in quotes; - /// otherwise, it was written in angle brackets. - bool wasInQuotes() const { return InQuotes; } - - /// \brief Determine whether the inclusion directive was automatically - /// turned into a module import. - bool importedModule() const { return ImportedModule; } - - /// \brief Retrieve the file entry for the actual file that was included - /// by this directive. - const FileEntry *getFile() const { return File; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *PE) { - return PE->getKind() == InclusionDirectiveKind; - } - }; - - /// \brief An abstract class that should be subclassed by any external source - /// of preprocessing record entries. - class ExternalPreprocessingRecordSource { - public: - virtual ~ExternalPreprocessingRecordSource(); - - /// \brief Read a preallocated preprocessed entity from the external source. - /// - /// \returns null if an error occurred that prevented the preprocessed - /// entity from being loaded. - virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0; - - /// \brief Returns a pair of [Begin, End) indices of preallocated - /// preprocessed entities that \p Range encompasses. - virtual std::pair<unsigned, unsigned> - findPreprocessedEntitiesInRange(SourceRange Range) = 0; - - /// \brief Optionally returns true or false if the preallocated preprocessed - /// entity with index \p Index came from file \p FID. - virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index, - FileID FID) { - return None; - } - }; - - /// \brief A record of the steps taken while preprocessing a source file, - /// including the various preprocessing directives processed, macros - /// expanded, etc. - class PreprocessingRecord : public PPCallbacks { - SourceManager &SourceMgr; - - /// \brief Allocator used to store preprocessing objects. - llvm::BumpPtrAllocator BumpAlloc; - - /// \brief The set of preprocessed entities in this record, in order they - /// were seen. - std::vector<PreprocessedEntity *> PreprocessedEntities; - - /// \brief The set of preprocessed entities in this record that have been - /// loaded from external sources. - /// - /// The entries in this vector are loaded lazily from the external source, - /// and are referenced by the iterator using negative indices. - std::vector<PreprocessedEntity *> LoadedPreprocessedEntities; - - /// \brief The set of ranges that were skipped by the preprocessor, - std::vector<SourceRange> SkippedRanges; - - /// \brief Global (loaded or local) ID for a preprocessed entity. - /// 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. - /// Value -1 corresponds to element 0 in the loaded entities vector, - /// value -2 corresponds to element 1 in the loaded entities vector, etc. - /// Value 0 is an invalid value, the index to local entities is 1-based, - /// value 1 corresponds to element 0 in the local entities vector, - /// value 2 corresponds to element 1 in the local entities vector, etc. - class PPEntityID { - int ID; - explicit PPEntityID(int ID) : ID(ID) {} - friend class PreprocessingRecord; - public: - PPEntityID() : ID(0) {} - }; - - static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) { - return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1); - } - - /// \brief Mapping from MacroInfo structures to their definitions. - llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions; - - /// \brief External source of preprocessed entities. - ExternalPreprocessingRecordSource *ExternalSource; - - /// \brief Retrieve the preprocessed entity at the given ID. - PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID); - - /// \brief Retrieve the loaded preprocessed entity at the given index. - PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index); - - /// \brief Determine the number of preprocessed entities that were - /// loaded (or can be loaded) from an external source. - unsigned getNumLoadedPreprocessedEntities() const { - return LoadedPreprocessedEntities.size(); - } - - /// \brief Returns a pair of [Begin, End) indices of local preprocessed - /// entities that \p Range encompasses. - std::pair<unsigned, unsigned> - findLocalPreprocessedEntitiesInRange(SourceRange Range) const; - unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const; - unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const; - - /// \brief Allocate space for a new set of loaded preprocessed entities. - /// - /// \returns The index into the set of loaded preprocessed entities, which - /// corresponds to the first newly-allocated entity. - unsigned allocateLoadedEntities(unsigned NumEntities); - - /// \brief Register a new macro definition. - 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); - } - - /// \brief Deallocate memory in the preprocessing record. - void Deallocate(void *Ptr) { } - - size_t getTotalMemory() const; - - SourceManager &getSourceManager() const { return SourceMgr; } - - /// 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; - - iterator(PreprocessingRecord *Self, int Position) - : 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() + this->I : this->I; - PPEntityID ID = Self->getPPEntityID(Index, isLoaded); - return Self->getPreprocessedEntity(ID); - } - PreprocessedEntity *operator->() const { return **this; } - }; - - /// \brief Begin iterator for all preprocessed entities. - iterator begin() { - return iterator(this, -(int)LoadedPreprocessedEntities.size()); - } - - /// \brief End iterator for all preprocessed entities. - iterator end() { - return iterator(this, PreprocessedEntities.size()); - } - - /// \brief Begin iterator for local, non-loaded, preprocessed entities. - iterator local_begin() { - return iterator(this, 0); - } - - /// \brief End iterator for local, non-loaded, preprocessed entities. - iterator local_end() { - return iterator(this, PreprocessedEntities.size()); - } - - /// \brief iterator range for the given range of loaded - /// preprocessed entities. - llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start, - unsigned count) { - unsigned end = start + count; - assert(end <= LoadedPreprocessedEntities.size()); - return llvm::make_range( - iterator(this, int(start) - LoadedPreprocessedEntities.size()), - iterator(this, int(end) - LoadedPreprocessedEntities.size())); - } - - /// \brief Returns a range of preprocessed entities that source range \p R - /// encompasses. - /// - /// \param R the range to look for preprocessed entities. - /// - 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. - /// - /// Can be used to avoid implicit deserializations of preallocated - /// preprocessed entities if we only care about entities of a specific file - /// and not from files \#included in the range given at - /// \see getPreprocessedEntitiesInRange. - bool isEntityInFileID(iterator PPEI, FileID FID); - - /// \brief Add a new preprocessed entity to this record. - PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity); - - /// \brief Set the external source for preprocessed entities. - void SetExternalSource(ExternalPreprocessingRecordSource &Source); - - /// \brief Retrieve the external source for preprocessed entities. - ExternalPreprocessingRecordSource *getExternalSource() const { - return ExternalSource; - } - - /// \brief Retrieve the macro definition that corresponds to the given - /// \c MacroInfo. - MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI); - - /// \brief Retrieve all ranges that got skipped while preprocessing. - const std::vector<SourceRange> &getSkippedRanges() const { - return SkippedRanges; - } - - private: - 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 MacroDefinition &MD) override; - void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, - StringRef FileName, bool IsAngled, - CharSourceRange FilenameRange, - const FileEntry *File, StringRef SearchPath, - StringRef RelativePath, - const Module *Imported) override; - void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDefinition &MD) override; - void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDefinition &MD) override; - /// \brief Hook called whenever the 'defined' operator is seen. - void Defined(const Token &MacroNameTok, const MacroDefinition &MD, - SourceRange Range) override; - - void SourceRangeSkipped(SourceRange Range) override; - - void addMacroExpansion(const Token &Id, const MacroInfo *MI, - SourceRange Range); - - /// \brief Cached result of the last \see getPreprocessedEntitiesInRange - /// query. - struct { - SourceRange Range; - std::pair<int, int> Result; - } CachedRangeQuery; - - std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R); - - friend class ASTReader; - friend class ASTWriter; - }; -} // end namespace clang - -inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR, - unsigned alignment) LLVM_NOEXCEPT { - return PR.Allocate(bytes, alignment); -} - -inline void operator delete(void *ptr, clang::PreprocessingRecord &PR, - unsigned) LLVM_NOEXCEPT { - PR.Deallocate(ptr); -} - -#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h deleted file mode 100644 index f6154b6..0000000 --- a/include/clang/Lex/Preprocessor.h +++ /dev/null @@ -1,1911 +0,0 @@ -//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the clang::Preprocessor interface. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H -#define LLVM_CLANG_LEX_PREPROCESSOR_H - -#include "clang/Basic/Builtins.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/MacroInfo.h" -#include "clang/Lex/ModuleMap.h" -#include "clang/Lex/PPCallbacks.h" -#include "clang/Lex/PTHLexer.h" -#include "clang/Lex/TokenLexer.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" -#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> - -namespace llvm { - template<unsigned InternalLen> class SmallString; -} - -namespace clang { - -class SourceManager; -class ExternalPreprocessorSource; -class FileManager; -class FileEntry; -class HeaderSearch; -class PragmaNamespace; -class PragmaHandler; -class CommentHandler; -class ScratchBuffer; -class TargetInfo; -class PPCallbacks; -class CodeCompletionHandler; -class DirectoryLookup; -class PreprocessingRecord; -class ModuleLoader; -class PTHManager; -class PreprocessorOptions; - -/// \brief Stores token information for comparing actual tokens with -/// predefined values. Only handles simple tokens and identifiers. -class TokenValue { - tok::TokenKind Kind; - IdentifierInfo *II; - -public: - TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) { - assert(Kind != tok::raw_identifier && "Raw identifiers are not supported."); - assert(Kind != tok::identifier && - "Identifiers should be created by TokenValue(IdentifierInfo *)"); - assert(!tok::isLiteral(Kind) && "Literals are not supported."); - assert(!tok::isAnnotation(Kind) && "Annotations are not supported."); - } - TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {} - bool operator==(const Token &Tok) const { - return Tok.getKind() == Kind && - (!II || II == Tok.getIdentifierInfo()); - } -}; - -/// \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. -/// -/// Lexers know only about tokens within a single source file, and don't -/// know anything about preprocessor-level issues like the \#include stack, -/// token expansion, etc. -class Preprocessor : public RefCountedBase<Preprocessor> { - IntrusiveRefCntPtr<PreprocessorOptions> PPOpts; - DiagnosticsEngine *Diags; - LangOptions &LangOpts; - const TargetInfo *Target; - const TargetInfo *AuxTarget; - FileManager &FileMgr; - SourceManager &SourceMgr; - std::unique_ptr<ScratchBuffer> ScratchBuf; - HeaderSearch &HeaderInfo; - ModuleLoader &TheModuleLoader; - - /// \brief External source of macros. - ExternalPreprocessorSource *ExternalSource; - - - /// An optional PTHManager object used for getting tokens from - /// a token cache rather than lexing the original source file. - std::unique_ptr<PTHManager> PTH; - - /// A BumpPtrAllocator object used to quickly allocate and release - /// objects internal to the Preprocessor. - llvm::BumpPtrAllocator BP; - - /// Identifiers for builtin macros and other builtins. - IdentifierInfo *Ident__LINE__, *Ident__FILE__; // __LINE__, __FILE__ - IdentifierInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__ - IdentifierInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__ - IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__ - IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__ - IdentifierInfo *Ident__COUNTER__; // __COUNTER__ - IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma - IdentifierInfo *Ident__identifier; // __identifier - IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__ - IdentifierInfo *Ident__has_feature; // __has_feature - IdentifierInfo *Ident__has_extension; // __has_extension - IdentifierInfo *Ident__has_builtin; // __has_builtin - IdentifierInfo *Ident__has_attribute; // __has_attribute - IdentifierInfo *Ident__has_include; // __has_include - IdentifierInfo *Ident__has_include_next; // __has_include_next - IdentifierInfo *Ident__has_warning; // __has_warning - 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. - - enum { - /// \brief Maximum depth of \#includes. - MaxAllowedIncludeStackDepth = 200 - }; - - // State that is set before the preprocessor begins. - bool KeepComments : 1; - bool KeepMacroComments : 1; - bool SuppressIncludeNotFoundError : 1; - - // State that changes while the preprocessor runs: - bool InMacroArgs : 1; // True if parsing fn macro invocation args. - - /// Whether the preprocessor owns the header search object. - bool OwnsHeaderSearch : 1; - - /// True if macro expansion is disabled. - bool DisableMacroExpansion : 1; - - /// Temporarily disables DisableMacroExpansion (i.e. enables expansion) - /// when parsing preprocessor directives. - bool MacroExpansionInDirectivesOverride : 1; - - class ResetMacroExpansionHelper; - - /// \brief Whether we have already loaded macros from the external source. - mutable bool ReadMacrosFromExternalSource : 1; - - /// \brief True if pragmas are enabled. - bool PragmasEnabled : 1; - - /// \brief True if the current build action is a preprocessing action. - bool PreprocessedOutput : 1; - - /// \brief True if we are currently preprocessing a #if or #elif directive - bool ParsingIfOrElifDirective; - - /// \brief True if we are pre-expanding macro arguments. - bool InMacroArgPreExpansion; - - /// \brief Mapping/lookup information for all identifiers in - /// the program, including program keywords. - mutable IdentifierTable Identifiers; - - /// \brief This table contains all the selectors in the program. - /// - /// Unlike IdentifierTable above, this table *isn't* populated by the - /// preprocessor. It is declared/expanded here because its role/lifetime is - /// conceptually similar to the IdentifierTable. In addition, the current - /// control flow (in clang::ParseAST()), make it convenient to put here. - /// - /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to - /// the lifetime of the preprocessor. - SelectorTable Selectors; - - /// \brief Information about builtins. - Builtin::Context BuiltinInfo; - - /// \brief Tracks all of the pragmas that the client registered - /// with this preprocessor. - 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. - std::vector<CommentHandler *> CommentHandlers; - - /// \brief True if we want to ignore EOF token and continue later on (thus - /// avoid tearing the Lexer and etc. down). - bool IncrementalProcessing; - - /// The kind of translation unit we are processing. - TranslationUnitKind TUKind; - - /// \brief The code-completion handler. - CodeCompletionHandler *CodeComplete; - - /// \brief The file that we're performing code-completion for, if any. - const FileEntry *CodeCompletionFile; - - /// \brief The offset in file for the code-completion point. - unsigned CodeCompletionOffset; - - /// \brief The location for the code-completion point. This gets instantiated - /// when the CodeCompletionFile gets \#include'ed for preprocessing. - SourceLocation CodeCompletionLoc; - - /// \brief The start location for the file of the code-completion point. - /// - /// This gets instantiated when the CodeCompletionFile gets \#include'ed - /// for preprocessing. - SourceLocation CodeCompletionFileLoc; - - /// \brief The source location of the \c import contextual keyword we just - /// lexed, if any. - SourceLocation ModuleImportLoc; - - /// \brief The module import path that we're currently processing. - SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath; - - /// \brief Whether the last token we lexed was an '@'. - bool LastTokenWasAt; - - /// \brief Whether the module import expects an identifier next. Otherwise, - /// it expects a '.' or ';'. - bool ModuleImportExpectsIdentifier; - - /// \brief The source location of the currently-active - /// \#pragma clang arc_cf_code_audited begin. - SourceLocation PragmaARCCFCodeAuditedLoc; - - /// \brief The source location of the currently-active - /// \#pragma clang assume_nonnull begin. - SourceLocation PragmaAssumeNonNullLoc; - - /// \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<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. - /// - /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null. - std::unique_ptr<Lexer> CurLexer; - - /// \brief The current top of stack that we're lexing from if - /// not expanding from a macro and we are lexing from a PTH cache. - /// - /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null. - std::unique_ptr<PTHLexer> CurPTHLexer; - - /// \brief The current top of the stack what we're lexing from - /// if not expanding a macro. - /// - /// This is an alias for either CurLexer or CurPTHLexer. - PreprocessorLexer *CurPPLexer; - - /// \brief Used to find the current FileEntry, if CurLexer is non-null - /// and if applicable. - /// - /// This allows us to implement \#include_next and find directory-specific - /// properties. - const DirectoryLookup *CurDirLookup; - - /// \brief The current macro we are expanding, if we are expanding a macro. - /// - /// One of CurLexer and CurTokenLexer must be null. - std::unique_ptr<TokenLexer> CurTokenLexer; - - /// \brief The kind of lexer we're currently working with. - enum CurLexerKind { - CLK_Lexer, - CLK_PTHLexer, - CLK_TokenLexer, - CLK_CachingLexer, - CLK_LexAfterModuleImport - } CurLexerKind; - - /// \brief If the current lexer is for a submodule that is being built, this - /// is that submodule. - Module *CurSubmodule; - - /// \brief Keeps track of the stack of files currently - /// \#included, and macros currently being expanded from, not counting - /// CurLexer/CurTokenLexer. - struct IncludeStackInfo { - enum CurLexerKind CurLexerKind; - Module *TheSubmodule; - std::unique_ptr<Lexer> TheLexer; - std::unique_ptr<PTHLexer> ThePTHLexer; - PreprocessorLexer *ThePPLexer; - std::unique_ptr<TokenLexer> TheTokenLexer; - const DirectoryLookup *TheDirLookup; - - // The following constructors are completely useless copies of the default - // versions, only needed to pacify MSVC. - IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule, - std::unique_ptr<Lexer> &&TheLexer, - std::unique_ptr<PTHLexer> &&ThePTHLexer, - PreprocessorLexer *ThePPLexer, - std::unique_ptr<TokenLexer> &&TheTokenLexer, - const DirectoryLookup *TheDirLookup) - : CurLexerKind(std::move(CurLexerKind)), - TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)), - ThePTHLexer(std::move(ThePTHLexer)), - ThePPLexer(std::move(ThePPLexer)), - TheTokenLexer(std::move(TheTokenLexer)), - TheDirLookup(std::move(TheDirLookup)) {} - IncludeStackInfo(IncludeStackInfo &&RHS) - : CurLexerKind(std::move(RHS.CurLexerKind)), - TheSubmodule(std::move(RHS.TheSubmodule)), - TheLexer(std::move(RHS.TheLexer)), - ThePTHLexer(std::move(RHS.ThePTHLexer)), - ThePPLexer(std::move(RHS.ThePPLexer)), - TheTokenLexer(std::move(RHS.TheTokenLexer)), - TheDirLookup(std::move(RHS.TheDirLookup)) {} - }; - std::vector<IncludeStackInfo> IncludeMacroStack; - - /// \brief Actions invoked when some preprocessor activity is - /// encountered (e.g. a file is \#included, etc). - std::unique_ptr<PPCallbacks> Callbacks; - - struct MacroExpandsInfo { - Token Tok; - MacroDefinition 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.getLangOpts().ModulesLocalVisibility) || - !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. - if (auto *Latest = getLatest()) - return Latest->findDirectiveAtLoc(Loc, SourceMgr); - return MacroDirective::DefInfo(); - } - - void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) { - if (auto *Info = getModuleInfo(PP, II)) { - Info->OverriddenMacros.insert(Info->OverriddenMacros.end(), - Info->ActiveModuleMacros.begin(), - Info->ActiveModuleMacros.end()); - 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). - /// - /// 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. - /// - /// We store just their SourceLocations instead of - /// something like MacroInfo*. The benefit of this is that when we are - /// deserializing from PCH, we don't need to deserialize identifier & macros - /// just so that we can report that they are unused, we just warn using - /// the SourceLocations of this set (that will be filled by the ASTReader). - /// We are using SmallPtrSet instead of a vector for faster removal. - typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy; - WarnUnusedMacroLocsTy WarnUnusedMacroLocs; - - /// \brief A "freelist" of MacroArg objects that can be - /// reused for quick allocation. - MacroArgs *MacroArgCache; - friend class MacroArgs; - - /// For each IdentifierInfo used in a \#pragma push_macro directive, - /// we keep a MacroInfo stack used to restore the previous macro value. - llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo; - - // Various statistics we track for performance analysis. - unsigned NumDirectives, NumDefined, NumUndefined, NumPragma; - unsigned NumIf, NumElse, NumEndif; - unsigned NumEnteredSourceFiles, MaxIncludeStackDepth; - unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded; - unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste; - unsigned NumSkipped; - - /// \brief The predefined macros that preprocessor should use from the - /// command line etc. - std::string Predefines; - - /// \brief The file ID for the preprocessor predefines. - FileID PredefinesFileID; - - /// \{ - /// \brief Cache of macro expanders to reduce malloc traffic. - enum { TokenLexerCacheSize = 8 }; - unsigned NumCachedTokenLexers; - std::unique_ptr<TokenLexer> TokenLexerCache[TokenLexerCacheSize]; - /// \} - - /// \brief Keeps macro expanded tokens for TokenLexers. - // - /// Works like a stack; a TokenLexer adds the macro expanded tokens that is - /// going to lex in the cache and when it finishes the tokens are removed - /// from the end of the cache. - SmallVector<Token, 16> MacroExpandedTokens; - std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack; - - /// \brief A record of the macro definitions and expansions that - /// occurred during preprocessing. - /// - /// This is an optional side structure that can be enabled with - /// \c createPreprocessingRecord() prior to preprocessing. - PreprocessingRecord *Record; - - /// Cached tokens state. - typedef SmallVector<Token, 1> CachedTokensTy; - - /// \brief Cached tokens are stored here when we do backtracking or - /// lookahead. They are "lexed" by the CachingLex() method. - CachedTokensTy CachedTokens; - - /// \brief The position of the cached token that CachingLex() should - /// "lex" next. - /// - /// If it points beyond the CachedTokens vector, it means that a normal - /// Lex() should be invoked. - CachedTokensTy::size_type CachedLexPos; - - /// \brief Stack of backtrack positions, allowing nested backtracks. - /// - /// The EnableBacktrackAtThisPos() method pushes a position to - /// indicate where CachedLexPos should be set when the BackTrack() method is - /// invoked (at which point the last position is popped). - std::vector<CachedTokensTy::size_type> BacktrackPositions; - - struct MacroInfoChain { - MacroInfo MI; - MacroInfoChain *Next; - }; - - /// MacroInfos are managed as a chain for easy disposal. This is the head - /// of that list. - MacroInfoChain *MIChainHead; - - struct DeserializedMacroInfoChain { - MacroInfo MI; - unsigned OwningModuleID; // MUST be immediately after the MacroInfo object - // so it can be accessed by MacroInfo::getOwningModuleID(). - DeserializedMacroInfoChain *Next; - }; - DeserializedMacroInfoChain *DeserialMIChainHead; - -public: - Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, - DiagnosticsEngine &diags, LangOptions &opts, - SourceManager &SM, HeaderSearch &Headers, - ModuleLoader &TheModuleLoader, - IdentifierInfoLookup *IILookup = nullptr, - bool OwnsHeaderSearch = false, - TranslationUnitKind TUKind = TU_Complete); - - ~Preprocessor(); - - /// \brief Initialize the preprocessor using information about the target. - /// - /// \param Target is owned by the caller and must remain valid for the - /// lifetime of the preprocessor. - /// \param AuxTarget is owned by the caller and must remain valid for - /// the lifetime of the preprocessor. - void Initialize(const TargetInfo &Target, - const TargetInfo *AuxTarget = nullptr); - - /// \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; } - - DiagnosticsEngine &getDiagnostics() const { return *Diags; } - void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; } - - const LangOptions &getLangOpts() const { return LangOpts; } - const TargetInfo &getTargetInfo() const { return *Target; } - const TargetInfo *getAuxTargetInfo() const { return AuxTarget; } - FileManager &getFileManager() const { return FileMgr; } - SourceManager &getSourceManager() const { return SourceMgr; } - 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; } - - void setPTHManager(PTHManager* pm); - - PTHManager *getPTHManager() { return PTH.get(); } - - void setExternalSource(ExternalPreprocessorSource *Source) { - ExternalSource = Source; - } - - ExternalPreprocessorSource *getExternalSource() const { - return ExternalSource; - } - - /// \brief Retrieve the module loader associated with this preprocessor. - ModuleLoader &getModuleLoader() const { return TheModuleLoader; } - - bool hadModuleLoaderFatalFailure() const { - return TheModuleLoader.HadFatalFailure; - } - - /// \brief True if we are currently preprocessing a #if or #elif directive - bool isParsingIfOrElifDirective() const { - return ParsingIfOrElifDirective; - } - - /// \brief Control whether the preprocessor retains comments in output. - void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) { - this->KeepComments = KeepComments | KeepMacroComments; - this->KeepMacroComments = KeepMacroComments; - } - - bool getCommentRetentionState() const { return KeepComments; } - - void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; } - bool getPragmasEnabled() const { return PragmasEnabled; } - - void SetSuppressIncludeNotFoundError(bool Suppress) { - SuppressIncludeNotFoundError = Suppress; - } - - bool GetSuppressIncludeNotFoundError() { - return SuppressIncludeNotFoundError; - } - - /// Sets whether the preprocessor is responsible for producing output or if - /// it is producing tokens to be consumed by Parse and Sema. - void setPreprocessedOutput(bool IsPreprocessedOutput) { - PreprocessedOutput = IsPreprocessedOutput; - } - - /// Returns true if the preprocessor is responsible for generating output, - /// false if it is producing tokens to be consumed by Parse and Sema. - bool isPreprocessedOutput() const { return PreprocessedOutput; } - - /// \brief Return true if we are lexing directly from the specified lexer. - bool isCurrentLexer(const PreprocessorLexer *L) const { - return CurPPLexer == L; - } - - /// \brief Return the current lexer being lexed from. - /// - /// Note that this ignores any potentially active macro expansions and _Pragma - /// expansions going on at the time. - PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; } - - /// \brief Return the current file lexer being lexed from. - /// - /// Note that this ignores any potentially active macro expansions and _Pragma - /// 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; } - - /// \{ - /// \brief Accessors for preprocessor callbacks. - /// - /// Note that this class takes ownership of any PPCallbacks object given to - /// it. - PPCallbacks *getPPCallbacks() const { return Callbacks.get(); } - void addPPCallbacks(std::unique_ptr<PPCallbacks> C) { - if (Callbacks) - C = llvm::make_unique<PPChainedCallbacks>(std::move(C), - std::move(Callbacks)); - Callbacks = std::move(C); - } - /// \} - - bool isMacroDefined(StringRef Id) { - return isMacroDefined(&Identifiers.get(Id)); - } - bool isMacroDefined(const IdentifierInfo *II) { - return II->hasMacroDefinition() && - (!getLangOpts().Modules || (bool)getMacroDefinition(II)); - } - - /// \brief Determine whether II is defined as a macro within the module M, - /// if that is a module that we've already preprocessed. Does not check for - /// macros imported into M. - bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M) { - if (!II->hasMacroDefinition()) - return false; - auto I = Submodules.find(M); - if (I == Submodules.end()) - return false; - auto J = I->second.Macros.find(II); - if (J == I->second.Macros.end()) - return false; - auto *MD = J->second.getLatest(); - return MD && MD->isDefined(); - } - - 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; - - return MD; - } - - const MacroInfo *getMacroInfo(const IdentifierInfo *II) const { - return const_cast<Preprocessor*>(this)->getMacroInfo(II); - } - - 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 latest non-imported macro - /// directive for that identifier. - /// - /// 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) { - DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc); - appendMacroDirective(II, MD); - return MD; - } - 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 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 - /// spelling \p Tokens. If there are multiple macros with same spelling, - /// return the last one defined. - StringRef getLastMacroWithSpelling(SourceLocation Loc, - ArrayRef<TokenValue> Tokens) const; - - const std::string &getPredefines() const { return Predefines; } - /// \brief Set the predefines for this Preprocessor. - /// - /// These predefines are automatically injected when parsing the main file. - void setPredefines(const char *P) { Predefines = P; } - void setPredefines(StringRef P) { Predefines = P; } - - /// Return information about the specified preprocessor - /// identifier token. - IdentifierInfo *getIdentifierInfo(StringRef Name) const { - return &Identifiers.get(Name); - } - - /// \brief Add the specified pragma handler to this preprocessor. - /// - /// If \p Namespace is non-null, then it is a token required to exist on the - /// pragma line before the pragma string starts, e.g. "STDC" or "GCC". - void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler); - void AddPragmaHandler(PragmaHandler *Handler) { - AddPragmaHandler(StringRef(), Handler); - } - - /// \brief Remove the specific pragma handler from this preprocessor. - /// - /// If \p Namespace is non-null, then it should be the namespace that - /// \p Handler was added to. It is an error to remove a handler that - /// has not been registered. - void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler); - void RemovePragmaHandler(PragmaHandler *Handler) { - RemovePragmaHandler(StringRef(), Handler); - } - - /// Install empty handlers for all pragmas (making them ignored). - void IgnorePragmas(); - - /// \brief Add the specified comment handler to the preprocessor. - void addCommentHandler(CommentHandler *Handler); - - /// \brief Remove the specified comment handler. - /// - /// It is an error to remove a handler that has not been registered. - void removeCommentHandler(CommentHandler *Handler); - - /// \brief Set the code completion handler to the given object. - void setCodeCompletionHandler(CodeCompletionHandler &Handler) { - CodeComplete = &Handler; - } - - /// \brief Retrieve the current code-completion handler. - CodeCompletionHandler *getCodeCompletionHandler() const { - return CodeComplete; - } - - /// \brief Clear out the code completion handler. - void clearCodeCompletionHandler() { - CodeComplete = nullptr; - } - - /// \brief Hook used by the lexer to invoke the "natural language" code - /// completion point. - void CodeCompleteNaturalLanguage(); - - /// \brief Retrieve the preprocessing record, or NULL if there is no - /// preprocessing record. - PreprocessingRecord *getPreprocessingRecord() const { return Record; } - - /// \brief Create a new preprocessing record, which will keep track of - /// all macro expansions, macro definitions, etc. - void createPreprocessingRecord(); - - /// \brief Enter the specified FileID as the main source file, - /// which implicitly adds the builtin defines etc. - void EnterMainSourceFile(); - - /// \brief Inform the preprocessor callbacks that processing is complete. - void EndSourceFile(); - - /// \brief Add a source file to the top of the include stack and - /// start lexing tokens from it instead of the current buffer. - /// - /// Emits a diagnostic, doesn't enter the file, and returns true on error. - bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir, - SourceLocation Loc); - - /// \brief Add a Macro to the top of the include stack and start lexing - /// tokens from it instead of the current buffer. - /// - /// \param Args specifies the tokens input to a function-like macro. - /// \param ILEnd specifies the location of the ')' for a function-like macro - /// or the identifier for an object-like macro. - void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro, - MacroArgs *Args); - - /// \brief Add a "macro" context to the top of the include stack, - /// which will cause the lexer to start returning the specified tokens. - /// - /// If \p DisableMacroExpansion is true, tokens lexed from the token stream - /// will not be subject to further macro expansion. Otherwise, these tokens - /// will be re-macro-expanded when/if expansion is enabled. - /// - /// If \p OwnsTokens is false, this method assumes that the specified stream - /// of tokens has a permanent owner somewhere, so they do not need to be - /// copied. If it is true, it assumes the array of tokens is allocated with - /// \c new[] and must be freed. - void EnterTokenStream(const Token *Toks, unsigned NumToks, - bool DisableMacroExpansion, bool OwnsTokens); - - /// \brief Pop the current lexer/macro exp off the top of the lexer stack. - /// - /// This should only be used in situations where the current state of the - /// top-of-stack lexer is known. - void RemoveTopOfLexerStack(); - - /// From the point that this method is called, and until - /// CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor - /// keeps track of the lexed tokens so that a subsequent Backtrack() call will - /// make the Preprocessor re-lex the same tokens. - /// - /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can - /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will - /// be combined with the EnableBacktrackAtThisPos calls in reverse order. - /// - /// NOTE: *DO NOT* forget to call either CommitBacktrackedTokens or Backtrack - /// at some point after EnableBacktrackAtThisPos. If you don't, caching of - /// tokens will continue indefinitely. - /// - void EnableBacktrackAtThisPos(); - - /// \brief Disable the last EnableBacktrackAtThisPos call. - void CommitBacktrackedTokens(); - - /// \brief Make Preprocessor re-lex the tokens that were lexed since - /// EnableBacktrackAtThisPos() was previously called. - void Backtrack(); - - /// \brief True if EnableBacktrackAtThisPos() was called and - /// caching of tokens is on. - bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); } - - /// \brief Lex the next token for this preprocessor. - void Lex(Token &Result); - - 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. - bool LexStringLiteral(Token &Result, std::string &String, - const char *DiagnosticTag, bool AllowMacroExpansion) { - if (AllowMacroExpansion) - Lex(Result); - else - LexUnexpandedToken(Result); - return FinishLexStringLiteral(Result, String, DiagnosticTag, - AllowMacroExpansion); - } - - /// \brief Complete the lexing of a string literal where the first token has - /// already been lexed (see LexStringLiteral). - bool FinishLexStringLiteral(Token &Result, std::string &String, - const char *DiagnosticTag, - bool AllowMacroExpansion); - - /// \brief Lex a token. If it's a comment, keep lexing until we get - /// something not a comment. - /// - /// This is useful in -E -C mode where comments would foul up preprocessor - /// directive handling. - void LexNonComment(Token &Result) { - do - Lex(Result); - while (Result.getKind() == tok::comment); - } - - /// \brief Just like Lex, but disables macro expansion of identifier tokens. - void LexUnexpandedToken(Token &Result) { - // Disable macro expansion. - bool OldVal = DisableMacroExpansion; - DisableMacroExpansion = true; - // Lex the token. - Lex(Result); - - // Reenable it. - DisableMacroExpansion = OldVal; - } - - /// \brief Like LexNonComment, but this disables macro expansion of - /// identifier tokens. - void LexUnexpandedNonComment(Token &Result) { - do - LexUnexpandedToken(Result); - while (Result.getKind() == tok::comment); - } - - /// \brief Parses a simple integer literal to get its numeric value. Floating - /// point literals and user defined literals are rejected. Used primarily to - /// handle pragmas that accept integer arguments. - bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value); - - /// Disables macro expansion everywhere except for preprocessor directives. - void SetMacroExpansionOnlyInDirectives() { - DisableMacroExpansion = true; - MacroExpansionInDirectivesOverride = true; - } - - /// \brief Peeks ahead N tokens and returns that token without consuming any - /// tokens. - /// - /// LookAhead(0) returns the next token that would be returned by Lex(), - /// LookAhead(1) returns the token after it, etc. This returns normal - /// tokens after phase 5. As such, it is equivalent to using - /// 'Lex', not 'LexUnexpandedToken'. - const Token &LookAhead(unsigned N) { - if (CachedLexPos + N < CachedTokens.size()) - return CachedTokens[CachedLexPos+N]; - else - return PeekAhead(N+1); - } - - /// \brief When backtracking is enabled and tokens are cached, - /// this allows to revert a specific number of tokens. - /// - /// Note that the number of tokens being reverted should be up to the last - /// backtrack position, not more. - void RevertCachedTokens(unsigned N) { - assert(isBacktrackEnabled() && - "Should only be called when tokens are cached for backtracking"); - assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back()) - && "Should revert tokens up to the last backtrack position, not more"); - assert(signed(CachedLexPos) - signed(N) >= 0 && - "Corrupted backtrack positions ?"); - CachedLexPos -= N; - } - - /// \brief Enters a token in the token stream to be lexed next. - /// - /// If BackTrack() is called afterwards, the token will remain at the - /// insertion point. - void EnterToken(const Token &Tok) { - EnterCachingLexMode(); - CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok); - } - - /// We notify the Preprocessor that if it is caching tokens (because - /// backtrack is enabled) it should replace the most recent cached tokens - /// with the given annotation token. This function has no effect if - /// backtracking is not enabled. - /// - /// Note that the use of this function is just for optimization, so that the - /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is - /// invoked. - void AnnotateCachedTokens(const Token &Tok) { - assert(Tok.isAnnotation() && "Expected annotation token"); - if (CachedLexPos != 0 && isBacktrackEnabled()) - AnnotatePreviousCachedTokens(Tok); - } - - /// Get the location of the last cached token, suitable for setting the end - /// location of an annotation token. - SourceLocation getLastCachedTokenLocation() const { - assert(CachedLexPos != 0); - return CachedTokens[CachedLexPos-1].getLastLoc(); - } - - /// \brief Replace the last token with an annotation token. - /// - /// Like AnnotateCachedTokens(), this routine replaces an - /// already-parsed (and resolved) token with an annotation - /// token. However, this routine only replaces the last token with - /// the annotation token; it does not affect any other cached - /// tokens. This function has no effect if backtracking is not - /// enabled. - void ReplaceLastTokenWithAnnotation(const Token &Tok) { - assert(Tok.isAnnotation() && "Expected annotation token"); - if (CachedLexPos != 0 && isBacktrackEnabled()) - CachedTokens[CachedLexPos-1] = Tok; - } - - /// Update the current token to represent the provided - /// identifier, in order to cache an action performed by typo correction. - void TypoCorrectToken(const Token &Tok) { - assert(Tok.getIdentifierInfo() && "Expected identifier token"); - if (CachedLexPos != 0 && isBacktrackEnabled()) - CachedTokens[CachedLexPos-1] = Tok; - } - - /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/ - /// CurTokenLexer pointers. - void recomputeCurLexerKind(); - - /// \brief Returns true if incremental processing is enabled - bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; } - - /// \brief Enables the incremental processing - void enableIncrementalProcessing(bool value = true) { - IncrementalProcessing = value; - } - - /// \brief Specify the point at which code-completion will be performed. - /// - /// \param File the file in which code completion should occur. If - /// this file is included multiple times, code-completion will - /// perform completion the first time it is included. If NULL, this - /// function clears out the code-completion point. - /// - /// \param Line the line at which code completion should occur - /// (1-based). - /// - /// \param Column the column at which code completion should occur - /// (1-based). - /// - /// \returns true if an error occurred, false otherwise. - bool SetCodeCompletionPoint(const FileEntry *File, - unsigned Line, unsigned Column); - - /// \brief Determine if we are performing code completion. - bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; } - - /// \brief Returns the location of the code-completion point. - /// - /// Returns an invalid location if code-completion is not enabled or the file - /// containing the code-completion point has not been lexed yet. - SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; } - - /// \brief Returns the start location of the file of code-completion point. - /// - /// Returns an invalid location if code-completion is not enabled or the file - /// containing the code-completion point has not been lexed yet. - SourceLocation getCodeCompletionFileLoc() const { - return CodeCompletionFileLoc; - } - - /// \brief Returns true if code-completion is enabled and we have hit the - /// code-completion point. - bool isCodeCompletionReached() const { return CodeCompletionReached; } - - /// \brief Note that we hit the code-completion point. - void setCodeCompletionReached() { - assert(isCodeCompletionEnabled() && "Code-completion not enabled!"); - CodeCompletionReached = true; - // Silence any diagnostics that occur after we hit the code-completion. - getDiagnostics().setSuppressAllDiagnostics(true); - } - - /// \brief The location of the currently-active \#pragma clang - /// arc_cf_code_audited begin. - /// - /// Returns an invalid location if there is no such pragma active. - SourceLocation getPragmaARCCFCodeAuditedLoc() const { - return PragmaARCCFCodeAuditedLoc; - } - - /// \brief Set the location of the currently-active \#pragma clang - /// arc_cf_code_audited begin. An invalid location ends the pragma. - void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc) { - PragmaARCCFCodeAuditedLoc = Loc; - } - - /// \brief The location of the currently-active \#pragma clang - /// assume_nonnull begin. - /// - /// Returns an invalid location if there is no such pragma active. - SourceLocation getPragmaAssumeNonNullLoc() const { - return PragmaAssumeNonNullLoc; - } - - /// \brief Set the location of the currently-active \#pragma clang - /// assume_nonnull begin. An invalid location ends the pragma. - void setPragmaAssumeNonNullLoc(SourceLocation Loc) { - PragmaAssumeNonNullLoc = 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. - /// - /// \param StartOfLine Whether skipping these bytes puts the lexer at the - /// start of a line. - void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) { - SkipMainFilePreamble.first = Bytes; - SkipMainFilePreamble.second = StartOfLine; - } - - /// Forwarding function for diagnostics. This emits a diagnostic at - /// the specified Token's location, translating the token's start - /// position in the current buffer into a SourcePosition object for rendering. - DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const { - return Diags->Report(Loc, DiagID); - } - - DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const { - return Diags->Report(Tok.getLocation(), DiagID); - } - - /// Return the 'spelling' of the token at the given - /// location; does not go up to the spelling location or down to the - /// expansion location. - /// - /// \param buffer A buffer which will be used only if the token requires - /// "cleaning", e.g. if it contains trigraphs or escaped newlines - /// \param invalid If non-null, will be set \c true if an error occurs. - StringRef getSpelling(SourceLocation loc, - SmallVectorImpl<char> &buffer, - bool *invalid = nullptr) const { - return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid); - } - - /// \brief Return the 'spelling' of the Tok token. - /// - /// The spelling of a token is the characters used to represent the token in - /// the source file after trigraph expansion and escaped-newline folding. In - /// particular, this wants to get the true, uncanonicalized, spelling of - /// things like digraphs, UCNs, etc. - /// - /// \param Invalid If non-null, will be set \c true if an error occurs. - std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const { - return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid); - } - - /// \brief Get the spelling of a token into a preallocated buffer, instead - /// of as an std::string. - /// - /// The caller is required to allocate enough space for the token, which is - /// guaranteed to be at least Tok.getLength() bytes long. The length of the - /// actual result is returned. - /// - /// Note that this method may do two possible things: it may either fill in - /// the buffer specified with characters, or it may *change the input pointer* - /// to point to a constant buffer with the data already in it (avoiding a - /// copy). The caller is not allowed to modify the returned buffer pointer - /// if an internal buffer is returned. - unsigned getSpelling(const Token &Tok, const char *&Buffer, - bool *Invalid = nullptr) const { - return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid); - } - - /// \brief Get the spelling of a token into a SmallVector. - /// - /// Note that the returned StringRef may not point to the - /// supplied buffer if a copy can be avoided. - StringRef getSpelling(const Token &Tok, - SmallVectorImpl<char> &Buffer, - bool *Invalid = nullptr) const; - - /// \brief Relex the token at the specified location. - /// \returns true if there was a failure, false on success. - bool getRawToken(SourceLocation Loc, Token &Result, - bool IgnoreWhiteSpace = false) { - return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace); - } - - /// \brief Given a Token \p Tok that is a numeric constant with length 1, - /// return the character. - char - getSpellingOfSingleCharacterNumericConstant(const Token &Tok, - bool *Invalid = nullptr) const { - assert(Tok.is(tok::numeric_constant) && - Tok.getLength() == 1 && "Called on unsupported token"); - assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1"); - - // If the token is carrying a literal data pointer, just use it. - if (const char *D = Tok.getLiteralData()) - return *D; - - // Otherwise, fall back on getCharacterData, which is slower, but always - // works. - return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid); - } - - /// \brief Retrieve the name of the immediate macro expansion. - /// - /// This routine starts from a source location, and finds the name of the - /// macro responsible for its immediate expansion. It looks through any - /// intervening macro argument expansions to compute this. It returns a - /// StringRef that refers to the SourceManager-owned buffer of the source - /// where that macro name is spelled. Thus, the result shouldn't out-live - /// the SourceManager. - StringRef getImmediateMacroName(SourceLocation Loc) { - return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts()); - } - - /// \brief Plop the specified string into a scratch buffer and set the - /// specified token's location and length to it. - /// - /// If specified, the source location provides a location of the expansion - /// point of the token. - void CreateString(StringRef Str, Token &Tok, - SourceLocation ExpansionLocStart = SourceLocation(), - SourceLocation ExpansionLocEnd = SourceLocation()); - - /// \brief Computes the source location just past the end of the - /// token at this source location. - /// - /// This routine can be used to produce a source location that - /// points just past the end of the token referenced by \p Loc, and - /// is generally used when a diagnostic needs to point just after a - /// token where it expected something different that it received. If - /// the returned source location would not be meaningful (e.g., if - /// it points into a macro), this routine returns an invalid - /// source location. - /// - /// \param Offset an offset from the end of the token, where the source - /// location should refer to. The default offset (0) produces a source - /// location pointing just past the end of the token; an offset of 1 produces - /// a source location pointing to the last character in the token, etc. - SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) { - return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts); - } - - /// \brief Returns true if the given MacroID location points at the first - /// token of the macro expansion. - /// - /// \param MacroBegin If non-null and function returns true, it is set to - /// begin location of the macro. - bool isAtStartOfMacroExpansion(SourceLocation loc, - SourceLocation *MacroBegin = nullptr) const { - return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts, - MacroBegin); - } - - /// \brief Returns true if the given MacroID location points at the last - /// token of the macro expansion. - /// - /// \param MacroEnd If non-null and function returns true, it is set to - /// end location of the macro. - bool isAtEndOfMacroExpansion(SourceLocation loc, - SourceLocation *MacroEnd = nullptr) const { - return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd); - } - - /// \brief Print the token to stderr, used for debugging. - 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. - SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, - unsigned Char) const { - return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts); - } - - /// \brief Increment the counters for the number of token paste operations - /// performed. - /// - /// If fast was specified, this is a 'fast paste' case we handled. - void IncrementPasteCounter(bool isFast) { - if (isFast) - ++NumFastTokenPaste; - else - ++NumTokenPaste; - } - - void PrintStats(); - - size_t getTotalMemory() const; - - /// When the macro expander pastes together a comment (/##/) in Microsoft - /// mode, this method handles updating the current state, returning the - /// token on the next source line. - void HandleMicrosoftCommentPaste(Token &Tok); - - //===--------------------------------------------------------------------===// - // Preprocessor callback methods. These are invoked by a lexer as various - // directives and events are found. - - /// Given a tok::raw_identifier token, look up the - /// identifier information for the token and install it into the token, - /// updating the token kind accordingly. - IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const; - -private: - llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons; - -public: - - /// \brief Specifies the reason for poisoning an identifier. - /// - /// If that identifier is accessed while poisoned, then this reason will be - /// used instead of the default "poisoned" diagnostic. - void SetPoisonReason(IdentifierInfo *II, unsigned DiagID); - - /// \brief Display reason for poisoned identifier. - void HandlePoisonedIdentifier(Token & Tok); - - void MaybeHandlePoisonedIdentifier(Token & Identifier) { - if(IdentifierInfo * II = Identifier.getIdentifierInfo()) { - if(II->isPoisoned()) { - HandlePoisonedIdentifier(Identifier); - } - } - } - -private: - /// Identifiers used for SEH handling in Borland. These are only - /// allowed in particular circumstances - // __except block - IdentifierInfo *Ident__exception_code, - *Ident___exception_code, - *Ident_GetExceptionCode; - // __except filter expression - IdentifierInfo *Ident__exception_info, - *Ident___exception_info, - *Ident_GetExceptionInfo; - // __finally - IdentifierInfo *Ident__abnormal_termination, - *Ident___abnormal_termination, - *Ident_AbnormalTermination; - - const char *getCurLexerEndPos(); - -public: - void PoisonSEHIdentifiers(bool Poison = true); // Borland - - /// \brief Callback invoked when the lexer reads an identifier and has - /// filled in the tokens IdentifierInfo member. - /// - /// This callback potentially macro expands it or turns it into a named - /// token (like 'for'). - /// - /// \returns true if we actually computed a token, false if we need to - /// lex again. - bool HandleIdentifier(Token &Identifier); - - - /// \brief Callback invoked when the lexer hits the end of the current file. - /// - /// This either returns the EOF token and returns true, or - /// pops a level off the include stack and returns false, at which point the - /// client should call lex again. - bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false); - - /// \brief Callback invoked when the current TokenLexer hits the end of its - /// token stream. - bool HandleEndOfTokenLexer(Token &Result); - - /// \brief Callback invoked when the lexer sees a # token at the start of a - /// line. - /// - /// This consumes the directive, modifies the lexer/preprocessor state, and - /// advances the lexer(s) so that the next token read is the correct one. - void HandleDirective(Token &Result); - - /// \brief Ensure that the next token is a tok::eod token. - /// - /// If not, emit a diagnostic and consume up until the eod. - /// If \p EnableMacros is true, then we consider macros that expand to zero - /// tokens as being ok. - void CheckEndOfDirective(const char *Directive, bool EnableMacros = false); - - /// \brief Read and discard all tokens remaining on the current line until - /// the tok::eod token is found. - void DiscardUntilEndOfDirective(); - - /// \brief Returns true if the preprocessor has seen a use of - /// __DATE__ or __TIME__ in the file so far. - bool SawDateOrTime() const { - return DATELoc != SourceLocation() || TIMELoc != SourceLocation(); - } - unsigned getCounterValue() const { return CounterValue; } - void setCounterValue(unsigned V) { CounterValue = V; } - - /// \brief Retrieves the module that we're currently building, if any. - Module *getCurrentModule(); - - /// \brief Allocate a new MacroInfo object with the provided SourceLocation. - MacroInfo *AllocateMacroInfo(SourceLocation L); - - /// \brief Allocate a new MacroInfo object loaded from an AST file. - MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L, - unsigned SubModuleID); - - /// \brief Turn the specified lexer token into a fully checked and spelled - /// filename, e.g. as an operand of \#include. - /// - /// The caller is expected to provide a buffer that is large enough to hold - /// the spelling of the filename, but is also expected to handle the case - /// when this method decides to use a different buffer. - /// - /// \returns true if the input filename was in <>'s or false if it was - /// in ""'s. - bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename); - - /// \brief Given a "foo" or \<foo> reference, look up the indicated file. - /// - /// Returns null on failure. \p isAngled indicates whether the file - /// 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, - ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache = false); - - /// \brief Get the DirectoryLookup structure used to find the current - /// FileEntry, if CurLexer is non-null and if applicable. - /// - /// This allows us to implement \#include_next and find directory-specific - /// properties. - const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; } - - /// \brief Return true if we're in the top-level file, not in a \#include. - bool isInPrimaryFile() const; - - /// \brief Handle cases where the \#include name is expanded - /// from a macro as multiple tokens, which need to be glued together. - /// - /// This occurs for code like: - /// \code - /// \#define FOO <x/y.h> - /// \#include FOO - /// \endcode - /// because in this case, "<x/y.h>" is returned as 7 tokens, not one. - /// - /// This code concatenates and consumes tokens up to the '>' token. It - /// returns false if the > was found, otherwise it returns true if it finds - /// and consumes the EOD marker. - bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer, - SourceLocation &End); - - /// \brief Lex an on-off-switch (C99 6.10.6p2) and verify that it is - /// followed by EOD. Return true if the token is not a valid on-off-switch. - bool LexOnOffSwitch(tok::OnOffSwitch &OOS); - - bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, - bool *ShadowFlag = nullptr); - -private: - - void PushIncludeMacroStack() { - assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer"); - IncludeMacroStack.emplace_back( - CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer), - CurPPLexer, std::move(CurTokenLexer), CurDirLookup); - CurPPLexer = nullptr; - } - - void PopIncludeMacroStack() { - CurLexer = std::move(IncludeMacroStack.back().TheLexer); - CurPTHLexer = std::move(IncludeMacroStack.back().ThePTHLexer); - CurPPLexer = IncludeMacroStack.back().ThePPLexer; - CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer); - CurDirLookup = IncludeMacroStack.back().TheDirLookup; - CurSubmodule = IncludeMacroStack.back().TheSubmodule; - CurLexerKind = IncludeMacroStack.back().CurLexerKind; - IncludeMacroStack.pop_back(); - } - - 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); - UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc); - VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc, - bool isPublic); - - /// \brief Lex and validate a macro name, which occurs after a - /// \#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, 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 - /// what we learn and saving in \p LastTok the last token read. - /// Return true if an error occurs parsing the arg list. - bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok); - - /// We just read a \#if or related directive and decided that the - /// subsequent tokens are in the \#if'd out portion of the - /// file. Lex the rest of the file, until we see an \#endif. If \p - /// FoundNonSkipPortion is true, then we have already emitted code for part of - /// this \#if directive, so \#else/\#elif blocks should never be entered. If - /// \p FoundElse is false, then \#else directives are ok, if not, then we have - /// already seen one so a \#else directive is a duplicate. When this returns, - /// the caller can lex the first valid token. - void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, - bool FoundNonSkipPortion, bool FoundElse, - SourceLocation ElseLoc = SourceLocation()); - - /// \brief A fast PTH version of SkipExcludedConditionalBlock. - void PTHSkipExcludedConditionalBlock(); - - /// \brief Evaluate an integer constant expression that may occur after a - /// \#if or \#elif directive and return it as a bool. - /// - /// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro. - bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro); - - /// \brief Install the standard preprocessor pragmas: - /// \#pragma GCC poison/system_header/dependency and \#pragma once. - void RegisterBuiltinPragmas(); - - /// \brief Register builtin macros such as __LINE__ with the identifier table. - void RegisterBuiltinMacros(); - - /// 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, const MacroDefinition &MD); - - /// \brief Cache macro expanded tokens for TokenLexers. - // - /// Works like a stack; a TokenLexer adds the macro expanded tokens that is - /// going to lex in the cache and when it finishes the tokens are removed - /// from the end of the cache. - Token *cacheMacroExpandedTokens(TokenLexer *tokLexer, - ArrayRef<Token> tokens); - void removeCachedMacroExpandedTokensOfLastLexer(); - friend void TokenLexer::ExpandFunctionArguments(); - - /// Determine whether the next preprocessor token to be - /// lexed is a '('. If so, consume the token and return true, if not, this - /// method should have no observable side-effect on the lexed tokens. - bool isNextPPTokenLParen(); - - /// After reading "MACRO(", this method is invoked to read all of the formal - /// arguments specified for the macro invocation. Returns null on error. - MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI, - SourceLocation &ExpansionEnd); - - /// \brief If an identifier token is read that is to be expanded - /// as a builtin macro, handle it and return the next token as 'Tok'. - void ExpandBuiltinMacro(Token &Tok); - - /// \brief Read a \c _Pragma directive, slice it up, process it, then - /// return the first token after the directive. - /// This assumes that the \c _Pragma token has just been read into \p Tok. - void Handle_Pragma(Token &Tok); - - /// \brief Like Handle_Pragma except the pragma text is not enclosed within - /// a string literal. - void HandleMicrosoft__pragma(Token &Tok); - - /// \brief Add a lexer to the top of the include stack and - /// start lexing tokens from it instead of the current buffer. - void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir); - - /// \brief Add a lexer to the top of the include stack and - /// start getting tokens from it using the PTH cache. - void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir); - - /// \brief Set the FileID for the preprocessor predefines. - void setPredefinesFileID(FileID FID) { - assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!"); - PredefinesFileID = FID; - } - - /// \brief Returns true if we are lexing from a file and not a - /// pragma or a macro. - static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) { - return L ? !L->isPragmaLexer() : P != nullptr; - } - - static bool IsFileLexer(const IncludeStackInfo& I) { - return IsFileLexer(I.TheLexer.get(), I.ThePPLexer); - } - - bool IsFileLexer() const { - return IsFileLexer(CurLexer.get(), CurPPLexer); - } - - //===--------------------------------------------------------------------===// - // Caching stuff. - void CachingLex(Token &Result); - bool InCachingLexMode() const { - // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means - // that we are past EOF, not that we are in CachingLex mode. - return !CurPPLexer && !CurTokenLexer && !CurPTHLexer && - !IncludeMacroStack.empty(); - } - void EnterCachingLexMode(); - void ExitCachingLexMode() { - if (InCachingLexMode()) - RemoveTopOfLexerStack(); - } - const Token &PeekAhead(unsigned N); - void AnnotatePreviousCachedTokens(const Token &Tok); - - //===--------------------------------------------------------------------===// - /// Handle*Directive - implement the various preprocessor directives. These - /// should side-effect the current preprocessor object so that the next call - /// to Lex() will return the appropriate token next. - void HandleLineDirective(Token &Tok); - void HandleDigitDirective(Token &Tok); - void HandleUserDiagnosticDirective(Token &Tok, bool isWarning); - void HandleIdentSCCSDirective(Token &Tok); - void HandleMacroPublicDirective(Token &Tok); - void HandleMacroPrivateDirective(Token &Tok); - - // File inclusion. - 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); - void HandleImportDirective(SourceLocation HashLoc, Token &Tok); - void HandleMicrosoftImportDirective(Token &Tok); - -public: - // Module inclusion testing. - /// \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); - - // Conditional Inclusion. - void HandleIfdefDirective(Token &Tok, bool isIfndef, - bool ReadAnyTokensBeforeDirective); - void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective); - void HandleEndifDirective(Token &Tok); - void HandleElseDirective(Token &Tok); - void HandleElifDirective(Token &Tok); - - // Pragmas. - void HandlePragmaDirective(SourceLocation IntroducerLoc, - PragmaIntroducerKind Introducer); -public: - void HandlePragmaOnce(Token &OnceTok); - void HandlePragmaMark(); - void HandlePragmaPoison(Token &PoisonTok); - void HandlePragmaSystemHeader(Token &SysHeaderTok); - void HandlePragmaDependency(Token &DependencyTok); - void HandlePragmaPushMacro(Token &Tok); - void HandlePragmaPopMacro(Token &Tok); - void HandlePragmaIncludeAlias(Token &Tok); - IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok); - - // Return true and store the first token only if any CommentHandler - // has inserted some tokens and getCommentRetentionState() is false. - bool HandleComment(Token &Token, SourceRange Comment); - - /// \brief A macro is used, update information about macros that need unused - /// warnings. - void markMacroAsUsed(MacroInfo *MI); -}; - -/// \brief Abstract base class that describes a handler that will receive -/// source ranges for each of the comments encountered in the source file. -class CommentHandler { -public: - virtual ~CommentHandler(); - - // The handler shall return true if it has pushed any tokens - // to be read using e.g. EnterToken or EnterTokenStream. - virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0; -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h deleted file mode 100644 index 6d6cf05..0000000 --- a/include/clang/Lex/PreprocessorLexer.h +++ /dev/null @@ -1,183 +0,0 @@ -//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the PreprocessorLexer interface. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H -#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H - -#include "clang/Lex/MultipleIncludeOpt.h" -#include "clang/Lex/Token.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -class FileEntry; -class Preprocessor; - -class PreprocessorLexer { - virtual void anchor(); -protected: - Preprocessor *PP; // Preprocessor object controlling lexing. - - /// The SourceManager FileID corresponding to the file being lexed. - const FileID FID; - - /// \brief Number of SLocEntries before lexing the file. - unsigned InitialNumSLocEntries; - - //===--------------------------------------------------------------------===// - // Context-specific lexing flags set by the preprocessor. - //===--------------------------------------------------------------------===// - - /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token. - bool ParsingPreprocessorDirective; - - /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal - /// token. - bool ParsingFilename; - - /// \brief True if in raw mode. - /// - /// Raw mode disables interpretation of tokens and is a far faster mode to - /// lex in than non-raw-mode. This flag: - /// 1. If EOF of the current lexer is found, the include stack isn't popped. - /// 2. Identifier information is not looked up for identifier tokens. As an - /// effect of this, implicit macro expansion is naturally disabled. - /// 3. "#" tokens at the start of a line are treated as normal tokens, not - /// implicitly transformed by the lexer. - /// 4. All diagnostic messages are disabled. - /// 5. No callbacks are made into the preprocessor. - /// - /// Note that in raw mode that the PP pointer may be null. - bool LexingRawMode; - - /// \brief A state machine that detects the \#ifndef-wrapping a file - /// idiom for the multiple-include optimization. - MultipleIncludeOpt MIOpt; - - /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks - /// we are currently in. - SmallVector<PPConditionalInfo, 4> ConditionalStack; - - PreprocessorLexer(const PreprocessorLexer &) = delete; - void operator=(const PreprocessorLexer &) = delete; - friend class Preprocessor; - - PreprocessorLexer(Preprocessor *pp, FileID fid); - - PreprocessorLexer() - : PP(nullptr), InitialNumSLocEntries(0), - ParsingPreprocessorDirective(false), - ParsingFilename(false), - LexingRawMode(false) {} - - virtual ~PreprocessorLexer() {} - - virtual void IndirectLex(Token& Result) = 0; - - /// \brief Return the source location for the next observable location. - virtual SourceLocation getSourceLocation() = 0; - - //===--------------------------------------------------------------------===// - // #if directive handling. - - /// pushConditionalLevel - When we enter a \#if directive, this keeps track of - /// what we are currently in for diagnostic emission (e.g. \#if with missing - /// \#endif). - void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, - bool FoundNonSkip, bool FoundElse) { - PPConditionalInfo CI; - CI.IfLoc = DirectiveStart; - CI.WasSkipping = WasSkipping; - CI.FoundNonSkip = FoundNonSkip; - CI.FoundElse = FoundElse; - ConditionalStack.push_back(CI); - } - void pushConditionalLevel(const PPConditionalInfo &CI) { - ConditionalStack.push_back(CI); - } - - /// popConditionalLevel - Remove an entry off the top of the conditional - /// stack, returning information about it. If the conditional stack is empty, - /// this returns true and does not fill in the arguments. - bool popConditionalLevel(PPConditionalInfo &CI) { - if (ConditionalStack.empty()) - return true; - CI = ConditionalStack.pop_back_val(); - return false; - } - - /// \brief Return the top of the conditional stack. - /// \pre This requires that there be a conditional active. - PPConditionalInfo &peekConditionalLevel() { - assert(!ConditionalStack.empty() && "No conditionals active!"); - return ConditionalStack.back(); - } - - unsigned getConditionalStackDepth() const { return ConditionalStack.size(); } - -public: - - //===--------------------------------------------------------------------===// - // Misc. lexing methods. - - /// \brief After the preprocessor has parsed a \#include, lex and - /// (potentially) macro expand the filename. - /// - /// If the sequence parsed is not lexically legal, emit a diagnostic and - /// return a result EOD token. - void LexIncludeFilename(Token &Result); - - /// \brief Inform the lexer whether or not we are currently lexing a - /// preprocessor directive. - void setParsingPreprocessorDirective(bool f) { - ParsingPreprocessorDirective = f; - } - - /// \brief Return true if this lexer is in raw mode or not. - bool isLexingRawMode() const { return LexingRawMode; } - - /// \brief Return the preprocessor object for this lexer. - Preprocessor *getPP() const { return PP; } - - FileID getFileID() const { - assert(PP && - "PreprocessorLexer::getFileID() should only be used with a Preprocessor"); - return FID; - } - - /// \brief Number of SLocEntries before lexing the file. - unsigned getInitialNumSLocEntries() const { - return InitialNumSLocEntries; - } - - /// getFileEntry - Return the FileEntry corresponding to this FileID. Like - /// getFileID(), this only works for lexers with attached preprocessors. - const FileEntry *getFileEntry() const; - - /// \brief Iterator that traverses the current stack of preprocessor - /// conditional directives (\#if/\#ifdef/\#ifndef). - typedef SmallVectorImpl<PPConditionalInfo>::const_iterator - conditional_iterator; - - conditional_iterator conditional_begin() const { - return ConditionalStack.begin(); - } - conditional_iterator conditional_end() const { - return ConditionalStack.end(); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h deleted file mode 100644 index 963d95d..0000000 --- a/include/clang/Lex/PreprocessorOptions.h +++ /dev/null @@ -1,185 +0,0 @@ -//===--- PreprocessorOptions.h ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_ -#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_ - -#include "clang/Basic/SourceLocation.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" -#include <cassert> -#include <set> -#include <string> -#include <utility> -#include <vector> - -namespace llvm { - class MemoryBuffer; -} - -namespace clang { - -class Preprocessor; -class LangOptions; - -/// \brief Enumerate the kinds of standard library that -enum ObjCXXARCStandardLibraryKind { - ARCXX_nolib, - /// \brief libc++ - ARCXX_libcxx, - /// \brief libstdc++ - ARCXX_libstdcxx -}; - -/// PreprocessorOptions - This class is used for passing the various options -/// used in preprocessor initialization to InitializePreprocessor(). -class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> { -public: - std::vector<std::pair<std::string, bool/*isUndef*/> > Macros; - std::vector<std::string> Includes; - std::vector<std::string> MacroIncludes; - - /// \brief Initialize the preprocessor with the compiler and target specific - /// predefines. - unsigned UsePredefines : 1; - - /// \brief Whether we should maintain a detailed record of all macro - /// definitions and expansions. - unsigned DetailedRecord : 1; - - /// The implicit PCH included at the start of the translation unit, or empty. - std::string ImplicitPCHInclude; - - /// \brief Headers that will be converted to chained PCHs in memory. - std::vector<std::string> ChainedIncludes; - - /// \brief When true, disables most of the normal validation performed on - /// precompiled headers. - bool DisablePCHValidation; - - /// \brief When true, a PCH with compiler errors will not be rejected. - bool AllowPCHWithCompilerErrors; - - /// \brief Dump declarations that are deserialized from PCH, for testing. - bool DumpDeserializedPCHDecls; - - /// \brief This is a set of names for decls that we do not want to be - /// deserialized, and we emit an error if they are; for testing purposes. - std::set<std::string> DeserializedPCHDeclsToErrorOn; - - /// \brief If non-zero, the implicit PCH include is actually a precompiled - /// preamble that covers this number of bytes in the main source file. - /// - /// The boolean indicates whether the preamble ends at the start of a new - /// line. - std::pair<unsigned, bool> PrecompiledPreambleBytes; - - /// The implicit PTH input included at the start of the translation unit, or - /// empty. - std::string ImplicitPTHInclude; - - /// If given, a PTH cache file to use for speeding up header parsing. - std::string TokenCache; - - /// \brief True if the SourceManager should report the original file name for - /// contents of files that were remapped to other files. Defaults to true. - bool RemappedFilesKeepOriginalName; - - /// \brief The set of file remappings, which take existing files on - /// the system (the first part of each pair) and gives them the - /// contents of other files on the system (the second part of each - /// pair). - std::vector<std::pair<std::string, std::string>> RemappedFiles; - - /// \brief The set of file-to-buffer remappings, which take existing files - /// on the system (the first part of each pair) and gives them the contents - /// of the specified memory buffer (the second part of each pair). - std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers; - - /// \brief Whether the compiler instance should retain (i.e., not free) - /// the buffers associated with remapped files. - /// - /// This flag defaults to false; it can be set true only through direct - /// manipulation of the compiler invocation object, in cases where the - /// compiler invocation and its buffers will be reused. - bool RetainRemappedFileBuffers; - - /// \brief The Objective-C++ ARC standard library that we should support, - /// by providing appropriate definitions to retrofit the standard library - /// with support for lifetime-qualified pointers. - ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary; - - /// \brief Records the set of modules - class FailedModulesSet : public RefCountedBase<FailedModulesSet> { - llvm::StringSet<> Failed; - - public: - bool hasAlreadyFailed(StringRef module) { - return Failed.count(module) > 0; - } - - void addFailed(StringRef module) { - Failed.insert(module); - } - }; - - /// \brief The set of modules that failed to build. - /// - /// This pointer will be shared among all of the compiler instances created - /// to (re)build modules, so that once a module fails to build anywhere, - /// other instances will see that the module has failed and won't try to - /// build it again. - IntrusiveRefCntPtr<FailedModulesSet> FailedModules; - -public: - PreprocessorOptions() : UsePredefines(true), DetailedRecord(false), - DisablePCHValidation(false), - AllowPCHWithCompilerErrors(false), - DumpDeserializedPCHDecls(false), - PrecompiledPreambleBytes(0, true), - RemappedFilesKeepOriginalName(true), - RetainRemappedFileBuffers(false), - ObjCXXARCStandardLibrary(ARCXX_nolib) { } - - void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); } - void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); } - void addRemappedFile(StringRef From, StringRef To) { - RemappedFiles.emplace_back(From, To); - } - - void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) { - RemappedFileBuffers.emplace_back(From, To); - } - - void clearRemappedFiles() { - RemappedFiles.clear(); - RemappedFileBuffers.clear(); - } - - /// \brief Reset any options that are not considered when building a - /// module. - void resetNonModularOptions() { - Includes.clear(); - MacroIncludes.clear(); - ChainedIncludes.clear(); - DumpDeserializedPCHDecls = false; - ImplicitPCHInclude.clear(); - ImplicitPTHInclude.clear(); - TokenCache.clear(); - RetainRemappedFileBuffers = true; - PrecompiledPreambleBytes.first = 0; - PrecompiledPreambleBytes.second = 0; - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h deleted file mode 100644 index a3d6096..0000000 --- a/include/clang/Lex/ScratchBuffer.h +++ /dev/null @@ -1,45 +0,0 @@ -//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ScratchBuffer interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_SCRATCHBUFFER_H -#define LLVM_CLANG_LEX_SCRATCHBUFFER_H - -#include "clang/Basic/SourceLocation.h" - -namespace clang { - class SourceManager; - -/// ScratchBuffer - This class exposes a simple interface for the dynamic -/// construction of tokens. This is used for builtin macros (e.g. __LINE__) as -/// well as token pasting, etc. -class ScratchBuffer { - SourceManager &SourceMgr; - char *CurBuffer; - SourceLocation BufferStartLoc; - unsigned BytesUsed; -public: - ScratchBuffer(SourceManager &SM); - - /// getToken - Splat the specified text into a temporary MemoryBuffer and - /// return a SourceLocation that refers to the token. This is just like the - /// previous method, but returns a location that indicates the physloc of the - /// token. - SourceLocation getToken(const char *Buf, unsigned Len, const char *&DestPtr); - -private: - void AllocScratchBuffer(unsigned RequestLen); -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h deleted file mode 100644 index 7ba22b2..0000000 --- a/include/clang/Lex/Token.h +++ /dev/null @@ -1,328 +0,0 @@ -//===--- Token.h - Token interface ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the Token interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_TOKEN_H -#define LLVM_CLANG_LEX_TOKEN_H - -#include "clang/Basic/OperatorKinds.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/TemplateKinds.h" -#include "clang/Basic/TokenKinds.h" -#include "llvm/ADT/StringRef.h" -#include <cstdlib> - -namespace clang { - -class IdentifierInfo; - -/// Token - This structure provides full information about a lexed token. -/// It is not intended to be space efficient, it is intended to return as much -/// information as possible about each returned token. This is expected to be -/// compressed into a smaller form if memory footprint is important. -/// -/// The parser can create a special "annotation token" representing a stream of -/// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>" -/// 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. 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 - // routine. Keeping as separate members with casts until a more beautiful fix - // presents itself. - - /// UintData - This holds either the length of the token text, when - /// a normal token, or the end of the SourceRange when an annotation - /// token. - unsigned UintData; - - /// PtrData - This is a union of four different pointer types, which depends - /// on what type of token this is: - /// Identifiers, keywords, etc: - /// This is an IdentifierInfo*, which contains the uniqued identifier - /// spelling. - /// Literals: isLiteral() returns true. - /// This is a pointer to the start of the token in a text buffer, which - /// 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; - - /// Kind - The actual flavor of token this is. - tok::TokenKind Kind; - - /// Flags - Bits we track about this token, members of the TokenFlags enum. - unsigned short Flags; -public: - - // Various flags set per token: - enum TokenFlags { - StartOfLine = 0x01, // At start of line or only after whitespace - // (considering the line after macro expansion). - LeadingSpace = 0x02, // Whitespace exists before this token (considering - // whitespace after macro expansion). - DisableExpand = 0x04, // This identifier may never be macro expanded. - NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. - 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). - StringifiedInMacro = 0x100, // This string or character literal is formed by - // macro stringizing or charizing operator. - }; - - tok::TokenKind getKind() const { return Kind; } - void setKind(tok::TokenKind K) { Kind = K; } - - /// is/isNot - Predicates to check if this token is a specific kind, as in - /// "if (Tok.is(tok::l_brace)) {...}". - bool is(tok::TokenKind K) const { return Kind == K; } - bool isNot(tok::TokenKind K) const { return Kind != K; } - bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { - return is(K1) || is(K2); - } - template <typename... Ts> - bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const { - return is(K1) || isOneOf(K2, Ks...); - } - - /// \brief Return true if this is a raw identifier (when lexing - /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode). - bool isAnyIdentifier() const { - return tok::isAnyIdentifier(getKind()); - } - - /// \brief Return true if this is a "literal", like a numeric - /// constant, string, etc. - bool isLiteral() const { - return tok::isLiteral(getKind()); - } - - /// \brief Return true if this is any of tok::annot_* kind tokens. - bool isAnnotation() const { - return tok::isAnnotation(getKind()); - } - - /// \brief Return a source location identifier for the specified - /// offset in the current file. - 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.getRawEncoding(); } - void setLength(unsigned Len) { - assert(!isAnnotation() && "Annotation tokens have no length field"); - UintData = Len; - } - - SourceLocation getAnnotationEndLoc() const { - assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); - return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); - } - void setAnnotationEndLoc(SourceLocation L) { - assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); - UintData = L.getRawEncoding(); - } - - SourceLocation getLastLoc() const { - 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 { - return SourceRange(getLocation(), getAnnotationEndLoc()); - } - void setAnnotationRange(SourceRange R) { - setLocation(R.getBegin()); - setAnnotationEndLoc(R.getEnd()); - } - - const char *getName() const { return tok::getTokenName(Kind); } - - /// \brief Reset all flags to cleared. - void startToken() { - Kind = tok::unknown; - Flags = 0; - PtrData = nullptr; - UintData = 0; - Loc = SourceLocation().getRawEncoding(); - } - - IdentifierInfo *getIdentifierInfo() const { - assert(isNot(tok::raw_identifier) && - "getIdentifierInfo() on a tok::raw_identifier token!"); - 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. - StringRef getRawIdentifier() const { - assert(is(tok::raw_identifier)); - return StringRef(reinterpret_cast<const char *>(PtrData), getLength()); - } - void setRawIdentifierData(const char *Ptr) { - assert(is(tok::raw_identifier)); - PtrData = const_cast<char*>(Ptr); - } - - /// getLiteralData - For a literal token (numeric constant, string, etc), this - /// returns a pointer to the start of it in the text buffer if known, null - /// otherwise. - const char *getLiteralData() const { - assert(isLiteral() && "Cannot get literal data of non-literal"); - return reinterpret_cast<const char*>(PtrData); - } - void setLiteralData(const char *Ptr) { - assert(isLiteral() && "Cannot set literal data of non-literal"); - PtrData = const_cast<char*>(Ptr); - } - - void *getAnnotationValue() const { - assert(isAnnotation() && "Used AnnotVal on non-annotation token"); - return PtrData; - } - void setAnnotationValue(void *val) { - assert(isAnnotation() && "Used AnnotVal on non-annotation token"); - PtrData = val; - } - - /// \brief Set the specified flag. - void setFlag(TokenFlags Flag) { - Flags |= Flag; - } - - /// \brief Unset the specified flag. - void clearFlag(TokenFlags Flag) { - Flags &= ~Flag; - } - - /// \brief Return the internal represtation of the flags. - /// - /// This is only intended for low-level operations such as writing tokens to - /// disk. - unsigned getFlags() const { - return Flags; - } - - /// \brief Set a flag to either true or false. - void setFlagValue(TokenFlags Flag, bool Val) { - if (Val) - setFlag(Flag); - else - clearFlag(Flag); - } - - /// isAtStartOfLine - Return true if this token is at the start of a line. - /// - bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; } - - /// \brief Return true if this token has whitespace before it. - /// - bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; } - - /// \brief Return true if this identifier token should never - /// be expanded in the future, due to C99 6.10.3.4p2. - bool isExpandDisabled() const { - return (Flags & DisableExpand) ? true : false; - } - - /// \brief Return true if we have an ObjC keyword identifier. - bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const; - - /// \brief Return the ObjC keyword kind. - tok::ObjCKeywordKind getObjCKeywordID() const; - - /// \brief Return true if this token has trigraphs or escaped newlines in it. - bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; } - - /// \brief Return true if this token has an empty macro before it. - /// - bool hasLeadingEmptyMacro() const { - return (Flags & LeadingEmptyMacro) ? true : false; - } - - /// \brief Return true if this token is a string or character literal which - /// has a ud-suffix. - bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; } - - /// 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) -/// currently active. -struct PPConditionalInfo { - /// \brief Location where the conditional started. - SourceLocation IfLoc; - - /// \brief True if this was contained in a skipping directive, e.g., - /// in a "\#if 0" block. - bool WasSkipping; - - /// \brief True if we have emitted tokens already, and now we're in - /// an \#else block or something. Only useful in Skipping blocks. - bool FoundNonSkip; - - /// \brief True if we've seen a \#else in this block. If so, - /// \#elif/\#else directives are not allowed. - bool FoundElse; -}; - -} // end namespace clang - -namespace llvm { - template <> - struct isPodLike<clang::Token> { static const bool value = true; }; -} // end namespace llvm - -#endif diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h deleted file mode 100644 index a2d98b0..0000000 --- a/include/clang/Lex/TokenConcatenation.h +++ /dev/null @@ -1,72 +0,0 @@ -//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TokenConcatenation class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_TOKENCONCATENATION_H -#define LLVM_CLANG_LEX_TOKENCONCATENATION_H - -#include "clang/Basic/TokenKinds.h" - -namespace clang { - class Preprocessor; - class Token; - - /// TokenConcatenation class, which answers the question of - /// "Is it safe to emit two tokens without a whitespace between them, or - /// would that cause implicit concatenation of the tokens?" - /// - /// For example, it emitting two identifiers "foo" and "bar" next to each - /// other would cause the lexer to produce one "foobar" token. Emitting "1" - /// and ")" next to each other is safe. - /// - class TokenConcatenation { - Preprocessor &PP; - - enum AvoidConcatInfo { - /// By default, a token never needs to avoid concatenation. Most tokens - /// (e.g. ',', ')', etc) don't cause a problem when concatenated. - aci_never_avoid_concat = 0, - - /// aci_custom_firstchar - AvoidConcat contains custom code to handle this - /// token's requirements, and it needs to know the first character of the - /// token. - aci_custom_firstchar = 1, - - /// aci_custom - AvoidConcat contains custom code to handle this token's - /// requirements, but it doesn't need to know the first character of the - /// token. - aci_custom = 2, - - /// aci_avoid_equal - Many tokens cannot be safely followed by an '=' - /// character. For example, "<<" turns into "<<=" when followed by an =. - aci_avoid_equal = 4 - }; - - /// TokenInfo - This array contains information for each token on what - /// action to take when avoiding concatenation of tokens in the AvoidConcat - /// method. - char TokenInfo[tok::NUM_TOKENS]; - public: - TokenConcatenation(Preprocessor &PP); - - bool AvoidConcat(const Token &PrevPrevTok, - const Token &PrevTok, - const Token &Tok) const; - - private: - /// IsIdentifierStringPrefix - Return true if the spelling of the token - /// is literally 'L', 'u', 'U', or 'u8'. - bool IsIdentifierStringPrefix(const Token &Tok) const; - }; - } // end clang namespace - -#endif diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h deleted file mode 100644 index fdeed44..0000000 --- a/include/clang/Lex/TokenLexer.h +++ /dev/null @@ -1,205 +0,0 @@ -//===--- TokenLexer.h - Lex from a token buffer -----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TokenLexer interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LEX_TOKENLEXER_H -#define LLVM_CLANG_LEX_TOKENLEXER_H - -#include "clang/Basic/SourceLocation.h" - -namespace clang { - class MacroInfo; - class Preprocessor; - class Token; - class MacroArgs; - -/// TokenLexer - This implements a lexer that returns tokens from a macro body -/// or token stream instead of lexing from a character buffer. This is used for -/// macro expansion and _Pragma handling, for example. -/// -class TokenLexer { - /// Macro - The macro we are expanding from. This is null if expanding a - /// token stream. - /// - MacroInfo *Macro; - - /// ActualArgs - The actual arguments specified for a function-like macro, or - /// null. The TokenLexer owns the pointed-to object. - MacroArgs *ActualArgs; - - /// PP - The current preprocessor object we are expanding for. - /// - Preprocessor &PP; - - /// Tokens - This is the pointer to an array of tokens that the macro is - /// defined to, with arguments expanded for function-like macros. If this is - /// a token stream, these are the tokens we are returning. This points into - /// the macro definition we are lexing from, a cache buffer that is owned by - /// the preprocessor, or some other buffer that we may or may not own - /// (depending on OwnsTokens). - /// Note that if it points into Preprocessor's cache buffer, the Preprocessor - /// may update the pointer as needed. - const Token *Tokens; - friend class Preprocessor; - - /// NumTokens - This is the length of the Tokens array. - /// - unsigned NumTokens; - - /// CurToken - This is the next token that Lex will return. - /// - unsigned CurToken; - - /// ExpandLocStart/End - The source location range where this macro was - /// expanded. - SourceLocation ExpandLocStart, ExpandLocEnd; - - /// \brief Source location pointing at the source location entry chunk that - /// was reserved for the current macro expansion. - SourceLocation MacroExpansionStart; - - /// \brief The offset of the macro expansion in the - /// "source location address space". - unsigned MacroStartSLocOffset; - - /// \brief Location of the macro definition. - SourceLocation MacroDefStart; - /// \brief Length of the macro definition. - unsigned MacroDefLength; - - /// Lexical information about the expansion point of the macro: the identifier - /// that the macro expanded from had these properties. - bool AtStartOfLine : 1; - bool HasLeadingSpace : 1; - - // NextTokGetsSpace - When this is true, the next token appended to the - // output list during function argument expansion will get a leading space, - // regardless of whether it had one to begin with or not. This is used for - // placemarker support. If still true after function argument expansion, the - // leading space will be applied to the first token following the macro - // expansion. - bool NextTokGetsSpace : 1; - - /// OwnsTokens - This is true if this TokenLexer allocated the Tokens - /// array, and thus needs to free it when destroyed. For simple object-like - /// macros (for example) we just point into the token buffer of the macro - /// definition, we don't make a copy of it. - bool OwnsTokens : 1; - - /// DisableMacroExpansion - This is true when tokens lexed from the TokenLexer - /// should not be subject to further macro expansion. - bool DisableMacroExpansion : 1; - - 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. - /// ILEnd specifies the location of the ')' for a function-like macro or the - /// identifier for an object-like macro. - TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI, - MacroArgs *ActualArgs, Preprocessor &pp) - : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) { - Init(Tok, ILEnd, MI, ActualArgs); - } - - /// Init - Initialize this TokenLexer to expand from the specified macro - /// with the specified argument information. Note that this ctor takes - /// ownership of the ActualArgs pointer. ILEnd specifies the location of the - /// ')' for a function-like macro or the identifier for an object-like macro. - void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI, - MacroArgs *ActualArgs); - - /// Create a TokenLexer for the specified token stream. If 'OwnsTokens' is - /// specified, this takes ownership of the tokens and delete[]'s them when - /// the token lexer is empty. - TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion, - bool ownsTokens, Preprocessor &pp) - : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) { - Init(TokArray, NumToks, DisableExpansion, ownsTokens); - } - - /// Init - Initialize this TokenLexer with the specified token stream. - /// This does not take ownership of the specified token vector. - /// - /// DisableExpansion is true when macro expansion of tokens lexed from this - /// stream should be disabled. - void Init(const Token *TokArray, unsigned NumToks, - bool DisableMacroExpansion, bool OwnsTokens); - - ~TokenLexer() { destroy(); } - - /// isNextTokenLParen - If the next token lexed will pop this macro off the - /// expansion stack, return 2. If the next unexpanded token is a '(', return - /// 1, otherwise return 0. - unsigned isNextTokenLParen() const; - - /// Lex - Lex and return a token from this macro stream. - bool Lex(Token &Tok); - - /// isParsingPreprocessorDirective - Return true if we are in the middle of a - /// preprocessor directive. - bool isParsingPreprocessorDirective() const; - -private: - void destroy(); - - /// isAtEnd - Return true if the next lex call will pop this macro off the - /// include stack. - bool isAtEnd() const { - return CurToken == NumTokens; - } - - /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ## - /// operator. Read the ## and RHS, and paste the LHS/RHS together. If there - /// are is another ## after it, chomp it iteratively. Return the result as - /// Tok. If this returns true, the caller should immediately return the - /// token. - bool PasteTokens(Token &Tok); - - /// Expand the arguments of a function-like macro so that we can quickly - /// return preexpanded tokens from Tokens. - void ExpandFunctionArguments(); - - /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes - /// together to form a comment that comments out everything in the current - /// macro, other active macros, and anything left on the current physical - /// source line of the expanded buffer. Handle this by returning the - /// first token on the next line. - void HandleMicrosoftCommentPaste(Token &Tok, SourceLocation OpLoc); - - /// \brief If \p loc is a FileID and points inside the current macro - /// definition, returns the appropriate source location pointing at the - /// macro expansion source location entry. - SourceLocation getExpansionLocForMacroDefLoc(SourceLocation loc) const; - - /// \brief Creates SLocEntries and updates the locations of macro argument - /// tokens to their new expanded locations. - /// - /// \param ArgIdSpellLoc the location of the macro argument id inside the - /// macro definition. - void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc, - Token *begin_tokens, Token *end_tokens); - - /// Remove comma ahead of __VA_ARGS__, if present, according to compiler - /// dialect settings. Returns true if the comma is removed. - bool MaybeRemoveCommaBeforeVaArgs(SmallVectorImpl<Token> &ResultToks, - bool HasPasteOperator, - MacroInfo *Macro, unsigned MacroArgNo, - Preprocessor &PP); - - void PropagateLineStartLeadingSpaceInfo(Token &Result); -}; - -} // end namespace clang - -#endif |