aboutsummaryrefslogtreecommitdiffstats
path: root/include/clang/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/DependencyDirectivesSourceMinimizer.h22
-rw-r--r--include/clang/Lex/DirectoryLookup.h68
-rw-r--r--include/clang/Lex/HeaderMap.h5
-rw-r--r--include/clang/Lex/HeaderSearch.h14
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h27
-rw-r--r--include/clang/Lex/Lexer.h15
-rw-r--r--include/clang/Lex/MacroArgs.h10
-rw-r--r--include/clang/Lex/PPCallbacks.h12
-rw-r--r--include/clang/Lex/Preprocessor.h55
-rw-r--r--include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h31
-rw-r--r--include/clang/Lex/PreprocessorOptions.h16
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;
}
};