1 //===- PreprocessorOptions.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
10 #define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
11 
12 #include "clang/Basic/BitmaskEnum.h"
13 #include "clang/Basic/FileEntry.h"
14 #include "clang/Basic/LLVM.h"
15 #include "clang/Lex/DependencyDirectivesScanner.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/StringSet.h"
18 #include <functional>
19 #include <map>
20 #include <memory>
21 #include <optional>
22 #include <set>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 namespace llvm {
28 
29 class MemoryBuffer;
30 
31 } // namespace llvm
32 
33 namespace clang {
34 
35 /// Enumerate the kinds of standard library that
36 enum ObjCXXARCStandardLibraryKind {
37   ARCXX_nolib,
38 
39   /// libc++
40   ARCXX_libcxx,
41 
42   /// libstdc++
43   ARCXX_libstdcxx
44 };
45 
46 /// Whether to disable the normal validation performed on precompiled
47 /// headers and module files when they are loaded.
48 enum class DisableValidationForModuleKind {
49   /// Perform validation, don't disable it.
50   None = 0,
51 
52   /// Disable validation for a precompiled header and the modules it depends on.
53   PCH = 0x1,
54 
55   /// Disable validation for module files.
56   Module = 0x2,
57 
58   /// Disable validation for all kinds.
59   All = PCH | Module,
60 
61   LLVM_MARK_AS_BITMASK_ENUM(Module)
62 };
63 
64 /// PreprocessorOptions - This class is used for passing the various options
65 /// used in preprocessor initialization to InitializePreprocessor().
66 class PreprocessorOptions {
67 public:
68   std::vector<std::pair<std::string, bool/*isUndef*/>> Macros;
69   std::vector<std::string> Includes;
70   std::vector<std::string> MacroIncludes;
71 
72   /// Perform extra checks when loading PCM files for mutable file systems.
73   bool ModulesCheckRelocated = true;
74 
75   /// Initialize the preprocessor with the compiler and target specific
76   /// predefines.
77   bool UsePredefines = true;
78 
79   /// Indicates whether to predefine target OS macros.
80   bool DefineTargetOSMacros = false;
81 
82   /// Whether we should maintain a detailed record of all macro
83   /// definitions and expansions.
84   bool DetailedRecord = false;
85 
86   /// When true, we are creating or using a PCH where a #pragma hdrstop is
87   /// expected to indicate the beginning or end of the PCH.
88   bool PCHWithHdrStop = false;
89 
90   /// When true, we are creating a PCH or creating the PCH object while
91   /// expecting a #pragma hdrstop to separate the two.  Allow for a
92   /// missing #pragma hdrstop, which generates a PCH for the whole file,
93   /// and creates an empty PCH object.
94   bool PCHWithHdrStopCreate = false;
95 
96   /// If non-empty, the filename used in an #include directive in the primary
97   /// source file (or command-line preinclude) that is used to implement
98   /// MSVC-style precompiled headers. When creating a PCH, after the #include
99   /// of this header, the PCH generation stops. When using a PCH, tokens are
100   /// skipped until after an #include of this header is seen.
101   std::string PCHThroughHeader;
102 
103   /// The implicit PCH included at the start of the translation unit, or empty.
104   std::string ImplicitPCHInclude;
105 
106   /// Headers that will be converted to chained PCHs in memory.
107   std::vector<std::string> ChainedIncludes;
108 
109   /// Whether to disable most of the normal validation performed on
110   /// precompiled headers and module files.
111   DisableValidationForModuleKind DisablePCHOrModuleValidation =
112       DisableValidationForModuleKind::None;
113 
114   /// When true, a PCH with compiler errors will not be rejected.
115   bool AllowPCHWithCompilerErrors = false;
116 
117   /// When true, a PCH with modules cache path different to the current
118   /// compilation will not be rejected.
119   bool AllowPCHWithDifferentModulesCachePath = false;
120 
121   /// Dump declarations that are deserialized from PCH, for testing.
122   bool DumpDeserializedPCHDecls = false;
123 
124   /// This is a set of names for decls that we do not want to be
125   /// deserialized, and we emit an error if they are; for testing purposes.
126   std::set<std::string> DeserializedPCHDeclsToErrorOn;
127 
128   /// If non-zero, the implicit PCH include is actually a precompiled
129   /// preamble that covers this number of bytes in the main source file.
130   ///
131   /// The boolean indicates whether the preamble ends at the start of a new
132   /// line.
133   std::pair<unsigned, bool> PrecompiledPreambleBytes;
134 
135   /// True indicates that a preamble is being generated.
136   ///
137   /// When the lexer is done, one of the things that need to be preserved is the
138   /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
139   /// processing the rest of the file. Similarly, we track an unterminated
140   /// #pragma assume_nonnull.
141   bool GeneratePreamble = false;
142 
143   /// Whether to write comment locations into the PCH when building it.
144   /// Reading the comments from the PCH can be a performance hit even if the
145   /// clients don't use them.
146   bool WriteCommentListToPCH = true;
147 
148   /// When enabled, preprocessor is in a mode for parsing a single file only.
149   ///
150   /// Disables #includes of other files and if there are unresolved identifiers
151   /// in preprocessor directive conditions it causes all blocks to be parsed so
152   /// that the client can get the maximum amount of information from the parser.
153   bool SingleFileParseMode = false;
154 
155   /// When enabled, the preprocessor will construct editor placeholder tokens.
156   bool LexEditorPlaceholders = true;
157 
158   /// True if the SourceManager should report the original file name for
159   /// contents of files that were remapped to other files. Defaults to true.
160   bool RemappedFilesKeepOriginalName = true;
161 
162   /// The set of file remappings, which take existing files on
163   /// the system (the first part of each pair) and gives them the
164   /// contents of other files on the system (the second part of each
165   /// pair).
166   std::vector<std::pair<std::string, std::string>> RemappedFiles;
167 
168   /// The set of file-to-buffer remappings, which take existing files
169   /// on the system (the first part of each pair) and gives them the contents
170   /// of the specified memory buffer (the second part of each pair).
171   std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
172 
173   /// Whether the compiler instance should retain (i.e., not free)
174   /// the buffers associated with remapped files.
175   ///
176   /// This flag defaults to false; it can be set true only through direct
177   /// manipulation of the compiler invocation object, in cases where the
178   /// compiler invocation and its buffers will be reused.
179   bool RetainRemappedFileBuffers = false;
180 
181   /// When enabled, excluded conditional blocks retain in the main file.
182   bool RetainExcludedConditionalBlocks = false;
183 
184   /// The Objective-C++ ARC standard library that we should support,
185   /// by providing appropriate definitions to retrofit the standard library
186   /// with support for lifetime-qualified pointers.
187   ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
188 
189   /// Records the set of modules
190   class FailedModulesSet {
191     llvm::StringSet<> Failed;
192 
193   public:
hasAlreadyFailed(StringRef module)194     bool hasAlreadyFailed(StringRef module) {
195       return Failed.count(module) > 0;
196     }
197 
addFailed(StringRef module)198     void addFailed(StringRef module) {
199       Failed.insert(module);
200     }
201   };
202 
203   /// The set of modules that failed to build.
204   ///
205   /// This pointer will be shared among all of the compiler instances created
206   /// to (re)build modules, so that once a module fails to build anywhere,
207   /// other instances will see that the module has failed and won't try to
208   /// build it again.
209   std::shared_ptr<FailedModulesSet> FailedModules;
210 
211   /// Function for getting the dependency preprocessor directives of a file.
212   ///
213   /// These are directives derived from a special form of lexing where the
214   /// source input is scanned for the preprocessor directives that might have an
215   /// effect on the dependencies for a compilation unit.
216   ///
217   /// Enables a client to cache the directives for a file and provide them
218   /// across multiple compiler invocations.
219   /// FIXME: Allow returning an error.
220   std::function<std::optional<ArrayRef<dependency_directives_scan::Directive>>(
221       FileEntryRef)>
222       DependencyDirectivesForFile;
223 
224   /// Set up preprocessor for RunAnalysis action.
225   bool SetUpStaticAnalyzer = false;
226 
227   /// Prevents intended crashes when using #pragma clang __debug. For testing.
228   bool DisablePragmaDebugCrash = false;
229 
230   /// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
231   std::optional<uint64_t> SourceDateEpoch;
232 
233 public:
PreprocessorOptions()234   PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
235 
addMacroDef(StringRef Name)236   void addMacroDef(StringRef Name) {
237     Macros.emplace_back(std::string(Name), false);
238   }
addMacroUndef(StringRef Name)239   void addMacroUndef(StringRef Name) {
240     Macros.emplace_back(std::string(Name), true);
241   }
242 
addRemappedFile(StringRef From,StringRef To)243   void addRemappedFile(StringRef From, StringRef To) {
244     RemappedFiles.emplace_back(std::string(From), std::string(To));
245   }
246 
addRemappedFile(StringRef From,llvm::MemoryBuffer * To)247   void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
248     RemappedFileBuffers.emplace_back(std::string(From), To);
249   }
250 
clearRemappedFiles()251   void clearRemappedFiles() {
252     RemappedFiles.clear();
253     RemappedFileBuffers.clear();
254   }
255 
256   /// Reset any options that are not considered when building a
257   /// module.
resetNonModularOptions()258   void resetNonModularOptions() {
259     Includes.clear();
260     MacroIncludes.clear();
261     ChainedIncludes.clear();
262     DumpDeserializedPCHDecls = false;
263     ImplicitPCHInclude.clear();
264     SingleFileParseMode = false;
265     LexEditorPlaceholders = true;
266     RetainRemappedFileBuffers = true;
267     PrecompiledPreambleBytes.first = 0;
268     PrecompiledPreambleBytes.second = false;
269     RetainExcludedConditionalBlocks = false;
270   }
271 };
272 
273 } // namespace clang
274 
275 #endif // LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
276