diff options
Diffstat (limited to 'include/clang/Lex')
-rw-r--r-- | include/clang/Lex/DependencyDirectivesSourceMinimizer.h | 22 | ||||
-rw-r--r-- | include/clang/Lex/DirectoryLookup.h | 68 | ||||
-rw-r--r-- | include/clang/Lex/HeaderMap.h | 5 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 14 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearchOptions.h | 27 | ||||
-rw-r--r-- | include/clang/Lex/Lexer.h | 15 | ||||
-rw-r--r-- | include/clang/Lex/MacroArgs.h | 10 | ||||
-rw-r--r-- | include/clang/Lex/PPCallbacks.h | 12 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 55 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h | 31 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessorOptions.h | 16 |
11 files changed, 187 insertions, 88 deletions
diff --git a/include/clang/Lex/DependencyDirectivesSourceMinimizer.h b/include/clang/Lex/DependencyDirectivesSourceMinimizer.h index 41641078afe4..d832df6b6146 100644 --- a/include/clang/Lex/DependencyDirectivesSourceMinimizer.h +++ b/include/clang/Lex/DependencyDirectivesSourceMinimizer.h @@ -38,6 +38,7 @@ enum TokenKind { pp_undef, pp_import, pp_pragma_import, + pp_pragma_once, pp_include_next, pp_if, pp_ifdef, @@ -46,6 +47,9 @@ enum TokenKind { pp_else, pp_endif, decl_at_import, + cxx_export_decl, + cxx_module_decl, + cxx_import_decl, pp_eof, }; @@ -62,6 +66,24 @@ struct Token { Token(TokenKind K, int Offset) : K(K), Offset(Offset) {} }; +/// Simplified token range to track the range of a potentially skippable PP +/// directive. +struct SkippedRange { + /// Offset into the output byte stream of where the skipped directive begins. + int Offset; + + /// The number of bytes that can be skipped before the preprocessing must + /// resume. + int Length; +}; + +/// Computes the potential source ranges that can be skipped by the preprocessor +/// when skipping a directive like #if, #ifdef or #elsif. +/// +/// \returns false on success, true on error. +bool computeSkippedRanges(ArrayRef<Token> Input, + llvm::SmallVectorImpl<SkippedRange> &Range); + } // end namespace minimize_source_to_dependency_directives /// Minimize the input down to the preprocessor directives that might have diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index 7c556ac35175..d526319a68c6 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -36,14 +36,17 @@ public: LT_HeaderMap }; private: - union { // This union is discriminated by isHeaderMap. + union DLU { // 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; + DirectoryEntryRef Dir; /// Map - This is the HeaderMap if this is a headermap lookup. /// const HeaderMap *Map; + + DLU(DirectoryEntryRef Dir) : Dir(Dir) {} + DLU(const HeaderMap *Map) : Map(Map) {} } u; /// DirCharacteristic - The type of directory this is: this is an instance of @@ -62,24 +65,18 @@ private: unsigned SearchedAllModuleMaps : 1; public: - /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of - /// 'dir'. - DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT, + /// This ctor *does not take ownership* of 'Dir'. + DirectoryLookup(DirectoryEntryRef Dir, SrcMgr::CharacteristicKind DT, bool isFramework) - : DirCharacteristic(DT), - LookupType(isFramework ? LT_Framework : LT_NormalDir), - IsIndexHeaderMap(false), SearchedAllModuleMaps(false) { - u.Dir = dir; - } + : u(Dir), DirCharacteristic(DT), + LookupType(isFramework ? LT_Framework : LT_NormalDir), + IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {} - /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of - /// 'map'. - DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT, + /// 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; - } + : u(Map), DirCharacteristic(DT), LookupType(LT_HeaderMap), + IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {} /// getLookupType - Return the kind of directory lookup that this is: either a /// normal directory, a framework path, or a HeaderMap. @@ -92,13 +89,17 @@ public: /// getDir - Return the directory that this entry refers to. /// const DirectoryEntry *getDir() const { - return isNormalDir() ? u.Dir : nullptr; + return isNormalDir() ? &u.Dir.getDirEntry() : nullptr; } /// getFrameworkDir - Return the directory that this framework refers to. /// const DirectoryEntry *getFrameworkDir() const { - return isFramework() ? u.Dir : nullptr; + return isFramework() ? &u.Dir.getDirEntry() : nullptr; + } + + Optional<DirectoryEntryRef> getFrameworkDirRef() const { + return isFramework() ? Optional<DirectoryEntryRef>(u.Dir) : None; } /// getHeaderMap - Return the directory that this entry refers to. @@ -176,27 +177,20 @@ public: /// \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, - SourceLocation IncludeLoc, - SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, - Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule, - bool &InUserSpecifiedSystemFramework, - bool &IsFrameworkFound, - bool &HasBeenMapped, - SmallVectorImpl<char> &MappedName) const; + Optional<FileEntryRef> + LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, + SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath, Module *RequestingModule, + ModuleMap::KnownHeader *SuggestedModule, + bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, + bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName) const; private: - const FileEntry *DoFrameworkLookup( - StringRef Filename, HeaderSearch &HS, - SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, - Module *RequestingModule, + Optional<FileEntryRef> DoFrameworkLookup( + StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool &InUserSpecifiedSystemFramework, - bool &IsFrameworkFound) const; - + bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const; }; } // end namespace clang diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index eca8755d4525..accb061e51ba 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_LEX_HEADERMAP_H #define LLVM_CLANG_LEX_HEADERMAP_H +#include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" @@ -21,8 +22,6 @@ namespace clang { -class FileEntry; -class FileManager; struct HMapBucket; struct HMapHeader; @@ -78,7 +77,7 @@ public: /// 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; + Optional<FileEntryRef> LookupFile(StringRef Filename, FileManager &FM) const; using HeaderMapImpl::lookupFilename; using HeaderMapImpl::getFileName; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index c5e66242444a..0d20dafe2cb1 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -250,12 +250,6 @@ class HeaderSearch { /// Entity used to look up stored header file information. ExternalHeaderFileInfoSource *ExternalSource = nullptr; - // Various statistics we track for performance analysis. - unsigned NumIncluded = 0; - unsigned NumMultiIncludeFileOptzn = 0; - unsigned NumFrameworkLookups = 0; - unsigned NumSubFrameworkLookups = 0; - public: HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts, SourceManager &SourceMgr, DiagnosticsEngine &Diags, @@ -395,7 +389,7 @@ public: /// found in any of searched SearchDirs. Will be set to false if a framework /// is found only through header maps. Doesn't guarantee the requested file is /// found. - const FileEntry *LookupFile( + Optional<FileEntryRef> LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, @@ -410,7 +404,7 @@ public: /// 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( + Optional<FileEntryRef> LookupSubframeworkHeader( StringRef Filename, const FileEntry *ContextFileEnt, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule); @@ -544,8 +538,6 @@ public: const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework); - void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } - /// 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. @@ -649,7 +641,7 @@ private: /// Look up the file with the specified name and determine its owning /// module. - const FileEntry * + Optional<FileEntryRef> getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir, bool IsSystemHeaderDir, Module *RequestingModule, diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h index ed128bce485f..5c19a41986b5 100644 --- a/include/clang/Lex/HeaderSearchOptions.h +++ b/include/clang/Lex/HeaderSearchOptions.h @@ -11,6 +11,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/CachedHashString.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include <cstdint> @@ -195,6 +196,10 @@ public: /// Whether to validate system input files when a module is loaded. unsigned ModulesValidateSystemHeaders : 1; + // Whether the content of input files should be hashed and used to + // validate consistency. + unsigned ValidateASTInputFilesContent : 1; + /// Whether the module includes debug information (-gmodules). unsigned UseDebugInfo : 1; @@ -202,14 +207,23 @@ public: unsigned ModulesHashContent : 1; + /// Whether we should include all things that could impact the module in the + /// hash. + /// + /// This includes things like the full header search path, and enabled + /// diagnostics. + unsigned ModulesStrictContextHash : 1; + HeaderSearchOptions(StringRef _Sysroot = "/") : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), UseBuiltinIncludes(true), UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), - ModulesValidateSystemHeaders(false), UseDebugInfo(false), - ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {} + ModulesValidateSystemHeaders(false), + ValidateASTInputFilesContent(false), UseDebugInfo(false), + ModulesValidateDiagnosticOptions(true), ModulesHashContent(false), + ModulesStrictContextHash(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, @@ -233,6 +247,15 @@ public: } }; +inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) { + return llvm::hash_combine(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot); +} + +inline llvm::hash_code +hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) { + return llvm::hash_combine(SHP.Prefix, SHP.IsSystemHeader); +} + } // namespace clang #endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 69cfe62e4bdb..97a222f4a703 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -265,6 +265,21 @@ public: /// Return the current location in the buffer. const char *getBufferLocation() const { return BufferPtr; } + /// Returns the current lexing offset. + unsigned getCurrentBufferOffset() { + assert(BufferPtr >= BufferStart && "Invalid buffer state"); + return BufferPtr - BufferStart; + } + + /// Skip over \p NumBytes bytes. + /// + /// If the skip is successful, the next token will be lexed from the new + /// offset. The lexer also assumes that we skipped to the start of the line. + /// + /// \returns true if the skip failed (new offset would have been past the + /// end of the buffer), false otherwise. + bool skipOver(unsigned NumBytes); + /// Stringify - Convert the specified string into a C string by i) escaping /// '\\' and " characters and ii) replacing newline character(s) with "\\n". /// If Charify is true, this escapes the ' character instead of ". diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h index 8806f2d8c656..59676c30e0a5 100644 --- a/include/clang/Lex/MacroArgs.h +++ b/include/clang/Lex/MacroArgs.h @@ -48,10 +48,6 @@ class MacroArgs final /// 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; @@ -94,12 +90,6 @@ public: const std::vector<Token> & getPreExpArgument(unsigned Arg, 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); - /// getNumMacroArguments - Return the number of arguments the invoked macro /// expects. unsigned getNumMacroArguments() const { return NumMacroArgs; } diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index f3f3796b1a30..1edcb567de66 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -57,10 +57,9 @@ public: /// \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, + virtual void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, - SrcMgr::CharacteristicKind FileType) { - } + SrcMgr::CharacteristicKind FileType) {} /// Callback invoked whenever an inclusion directive results in a /// file-not-found error. @@ -308,7 +307,7 @@ public: /// Hook called when a '__has_include' or '__has_include_next' directive is /// read. virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, - const FileEntry *File, + Optional<FileEntryRef> File, SrcMgr::CharacteristicKind FileType) {} /// Hook called when a source range is skipped. @@ -390,8 +389,7 @@ public: Second->FileChanged(Loc, Reason, FileType, PrevFID); } - void FileSkipped(const FileEntry &SkippedFile, - const Token &FilenameTok, + void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) override { First->FileSkipped(SkippedFile, FilenameTok, FileType); Second->FileSkipped(SkippedFile, FilenameTok, FileType); @@ -491,7 +489,7 @@ public: } void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, - const FileEntry *File, + Optional<FileEntryRef> File, SrcMgr::CharacteristicKind FileType) override { First->HasInclude(Loc, FileName, IsAngled, File, FileType); Second->HasInclude(Loc, FileName, IsAngled, File, FileType); diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index f65b0cda462f..1bdd2be04c0e 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -28,6 +28,7 @@ #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/ModuleMap.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h" #include "clang/Lex/Token.h" #include "clang/Lex/TokenLexer.h" #include "llvm/ADT/ArrayRef.h" @@ -370,9 +371,9 @@ class Preprocessor { /// it expects a '.' or ';'. bool ModuleImportExpectsIdentifier = false; - /// The source location of the currently-active + /// The identifier and source location of the currently-active /// \#pragma clang arc_cf_code_audited begin. - SourceLocation PragmaARCCFCodeAuditedLoc; + std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo; /// The source location of the currently-active /// \#pragma clang assume_nonnull begin. @@ -994,7 +995,7 @@ public: PPCallbacks *getPPCallbacks() const { return Callbacks.get(); } void addPPCallbacks(std::unique_ptr<PPCallbacks> C) { if (Callbacks) - C = llvm::make_unique<PPChainedCallbacks>(std::move(C), + C = std::make_unique<PPChainedCallbacks>(std::move(C), std::move(Callbacks)); Callbacks = std::move(C); } @@ -1471,7 +1472,7 @@ public: if (LexLevel) { // It's not correct in general to enter caching lex mode while in the // middle of a nested lexing action. - auto TokCopy = llvm::make_unique<Token[]>(1); + auto TokCopy = std::make_unique<Token[]>(1); TokCopy[0] = Tok; EnterTokenStream(std::move(TokCopy), 1, true, IsReinject); } else { @@ -1601,14 +1602,16 @@ public: /// arc_cf_code_audited begin. /// /// Returns an invalid location if there is no such pragma active. - SourceLocation getPragmaARCCFCodeAuditedLoc() const { - return PragmaARCCFCodeAuditedLoc; + std::pair<IdentifierInfo *, SourceLocation> + getPragmaARCCFCodeAuditedInfo() const { + return PragmaARCCFCodeAuditedInfo; } /// 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; + void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident, + SourceLocation Loc) { + PragmaARCCFCodeAuditedInfo = {Ident, Loc}; } /// The location of the currently-active \#pragma clang @@ -1949,17 +1952,15 @@ public: /// Given a "foo" or \<foo> reference, look up the indicated file. /// - /// Returns null on failure. \p isAngled indicates whether the file + /// Returns None 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 *IsMapped, bool *IsFrameworkFound, - bool SkipCache = false); + Optional<FileEntryRef> + 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 *IsMapped, + bool *IsFrameworkFound, bool SkipCache = false); /// Get the DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. @@ -2202,6 +2203,15 @@ private: } }; + Optional<FileEntryRef> LookupHeaderIncludeOrImport( + const DirectoryLookup *&CurDir, StringRef Filename, + SourceLocation FilenameLoc, CharSourceRange FilenameRange, + const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl, + bool &IsMapped, const DirectoryLookup *LookupFrom, + const FileEntry *LookupFromFile, StringRef LookupFilename, + SmallVectorImpl<char> &RelativePath, SmallVectorImpl<char> &SearchPath, + ModuleMap::KnownHeader &SuggestedModule, bool isAngled); + // File inclusion. void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok, const DirectoryLookup *LookupFrom = nullptr, @@ -2313,6 +2323,15 @@ public: /// A macro is used, update information about macros that need unused /// warnings. void markMacroAsUsed(MacroInfo *MI); + +private: + Optional<unsigned> + getSkippedRangeForExcludedConditionalBlock(SourceLocation HashLoc); + + /// Contains the currently active skipped range mappings for skipping excluded + /// conditional directives. + ExcludedPreprocessorDirectiveSkipMapping + *ExcludedConditionalDirectiveSkipMappings; }; /// Abstract base class that describes a handler that will receive diff --git a/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h b/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h new file mode 100644 index 000000000000..893b7ba7a9f5 --- /dev/null +++ b/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h @@ -0,0 +1,31 @@ +//===- PreprocessorExcludedConditionalDirectiveSkipMapping.h - --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H +#define LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/MemoryBuffer.h" + +namespace clang { + +/// A mapping from an offset into a buffer to the number of bytes that can be +/// skipped by the preprocessor when skipping over excluded conditional +/// directive ranges. +using PreprocessorSkippedRangeMapping = llvm::DenseMap<unsigned, unsigned>; + +/// The datastructure that holds the mapping between the active memory buffers +/// and the individual skip mappings. +using ExcludedPreprocessorDirectiveSkipMapping = + llvm::DenseMap<const llvm::MemoryBuffer *, + const PreprocessorSkippedRangeMapping *>; + +} // end namespace clang + +#endif // LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h index 1480548c7fbe..344afa894172 100644 --- a/include/clang/Lex/PreprocessorOptions.h +++ b/include/clang/Lex/PreprocessorOptions.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_ #include "clang/Basic/LLVM.h" +#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include <memory> @@ -142,6 +143,9 @@ public: /// compiler invocation and its buffers will be reused. bool RetainRemappedFileBuffers = false; + /// When enabled, excluded conditional blocks retain in the main file. + bool RetainExcludedConditionalBlocks = false; + /// 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. @@ -169,6 +173,17 @@ public: /// build it again. std::shared_ptr<FailedModulesSet> FailedModules; + /// Contains the currently active skipped range mappings for skipping excluded + /// conditional directives. + /// + /// The pointer is passed to the Preprocessor when it's constructed. The + /// pointer is unowned, the client is responsible for its lifetime. + ExcludedPreprocessorDirectiveSkipMapping + *ExcludedConditionalDirectiveSkipMappings = nullptr; + + /// Set up preprocessor for RunAnalysis action. + bool SetUpStaticAnalyzer = false; + public: PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {} @@ -201,6 +216,7 @@ public: RetainRemappedFileBuffers = true; PrecompiledPreambleBytes.first = 0; PrecompiledPreambleBytes.second = false; + RetainExcludedConditionalBlocks = false; } }; |