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   /// Whether we should maintain a detailed record of all macro
80   /// definitions and expansions.
81   bool DetailedRecord = false;
82 
83   /// When true, we are creating or using a PCH where a #pragma hdrstop is
84   /// expected to indicate the beginning or end of the PCH.
85   bool PCHWithHdrStop = false;
86 
87   /// When true, we are creating a PCH or creating the PCH object while
88   /// expecting a #pragma hdrstop to separate the two.  Allow for a
89   /// missing #pragma hdrstop, which generates a PCH for the whole file,
90   /// and creates an empty PCH object.
91   bool PCHWithHdrStopCreate = false;
92 
93   /// If non-empty, the filename used in an #include directive in the primary
94   /// source file (or command-line preinclude) that is used to implement
95   /// MSVC-style precompiled headers. When creating a PCH, after the #include
96   /// of this header, the PCH generation stops. When using a PCH, tokens are
97   /// skipped until after an #include of this header is seen.
98   std::string PCHThroughHeader;
99 
100   /// The implicit PCH included at the start of the translation unit, or empty.
101   std::string ImplicitPCHInclude;
102 
103   /// Headers that will be converted to chained PCHs in memory.
104   std::vector<std::string> ChainedIncludes;
105 
106   /// Whether to disable most of the normal validation performed on
107   /// precompiled headers and module files.
108   DisableValidationForModuleKind DisablePCHOrModuleValidation =
109       DisableValidationForModuleKind::None;
110 
111   /// When true, a PCH with compiler errors will not be rejected.
112   bool AllowPCHWithCompilerErrors = false;
113 
114   /// When true, a PCH with modules cache path different to the current
115   /// compilation will not be rejected.
116   bool AllowPCHWithDifferentModulesCachePath = false;
117 
118   /// Dump declarations that are deserialized from PCH, for testing.
119   bool DumpDeserializedPCHDecls = false;
120 
121   /// This is a set of names for decls that we do not want to be
122   /// deserialized, and we emit an error if they are; for testing purposes.
123   std::set<std::string> DeserializedPCHDeclsToErrorOn;
124 
125   /// If non-zero, the implicit PCH include is actually a precompiled
126   /// preamble that covers this number of bytes in the main source file.
127   ///
128   /// The boolean indicates whether the preamble ends at the start of a new
129   /// line.
130   std::pair<unsigned, bool> PrecompiledPreambleBytes;
131 
132   /// True indicates that a preamble is being generated.
133   ///
134   /// When the lexer is done, one of the things that need to be preserved is the
135   /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
136   /// processing the rest of the file. Similarly, we track an unterminated
137   /// #pragma assume_nonnull.
138   bool GeneratePreamble = false;
139 
140   /// Whether to write comment locations into the PCH when building it.
141   /// Reading the comments from the PCH can be a performance hit even if the
142   /// clients don't use them.
143   bool WriteCommentListToPCH = true;
144 
145   /// When enabled, preprocessor is in a mode for parsing a single file only.
146   ///
147   /// Disables #includes of other files and if there are unresolved identifiers
148   /// in preprocessor directive conditions it causes all blocks to be parsed so
149   /// that the client can get the maximum amount of information from the parser.
150   bool SingleFileParseMode = false;
151 
152   /// When enabled, the preprocessor will construct editor placeholder tokens.
153   bool LexEditorPlaceholders = true;
154 
155   /// True if the SourceManager should report the original file name for
156   /// contents of files that were remapped to other files. Defaults to true.
157   bool RemappedFilesKeepOriginalName = true;
158 
159   /// The set of file remappings, which take existing files on
160   /// the system (the first part of each pair) and gives them the
161   /// contents of other files on the system (the second part of each
162   /// pair).
163   std::vector<std::pair<std::string, std::string>> RemappedFiles;
164 
165   /// The set of file-to-buffer remappings, which take existing files
166   /// on the system (the first part of each pair) and gives them the contents
167   /// of the specified memory buffer (the second part of each pair).
168   std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
169 
170   /// Whether the compiler instance should retain (i.e., not free)
171   /// the buffers associated with remapped files.
172   ///
173   /// This flag defaults to false; it can be set true only through direct
174   /// manipulation of the compiler invocation object, in cases where the
175   /// compiler invocation and its buffers will be reused.
176   bool RetainRemappedFileBuffers = false;
177 
178   /// When enabled, excluded conditional blocks retain in the main file.
179   bool RetainExcludedConditionalBlocks = false;
180 
181   /// The Objective-C++ ARC standard library that we should support,
182   /// by providing appropriate definitions to retrofit the standard library
183   /// with support for lifetime-qualified pointers.
184   ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
185 
186   /// Records the set of modules
187   class FailedModulesSet {
188     llvm::StringSet<> Failed;
189 
190   public:
191     bool hasAlreadyFailed(StringRef module) {
192       return Failed.count(module) > 0;
193     }
194 
195     void addFailed(StringRef module) {
196       Failed.insert(module);
197     }
198   };
199 
200   /// The set of modules that failed to build.
201   ///
202   /// This pointer will be shared among all of the compiler instances created
203   /// to (re)build modules, so that once a module fails to build anywhere,
204   /// other instances will see that the module has failed and won't try to
205   /// build it again.
206   std::shared_ptr<FailedModulesSet> FailedModules;
207 
208   /// Function for getting the dependency preprocessor directives of a file.
209   ///
210   /// These are directives derived from a special form of lexing where the
211   /// source input is scanned for the preprocessor directives that might have an
212   /// effect on the dependencies for a compilation unit.
213   ///
214   /// Enables a client to cache the directives for a file and provide them
215   /// across multiple compiler invocations.
216   /// FIXME: Allow returning an error.
217   std::function<std::optional<ArrayRef<dependency_directives_scan::Directive>>(
218       FileEntryRef)>
219       DependencyDirectivesForFile;
220 
221   /// Set up preprocessor for RunAnalysis action.
222   bool SetUpStaticAnalyzer = false;
223 
224   /// Prevents intended crashes when using #pragma clang __debug. For testing.
225   bool DisablePragmaDebugCrash = false;
226 
227   /// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
228   std::optional<uint64_t> SourceDateEpoch;
229 
230 public:
231   PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
232 
233   void addMacroDef(StringRef Name) {
234     Macros.emplace_back(std::string(Name), false);
235   }
236   void addMacroUndef(StringRef Name) {
237     Macros.emplace_back(std::string(Name), true);
238   }
239 
240   void addRemappedFile(StringRef From, StringRef To) {
241     RemappedFiles.emplace_back(std::string(From), std::string(To));
242   }
243 
244   void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
245     RemappedFileBuffers.emplace_back(std::string(From), To);
246   }
247 
248   void clearRemappedFiles() {
249     RemappedFiles.clear();
250     RemappedFileBuffers.clear();
251   }
252 
253   /// Reset any options that are not considered when building a
254   /// module.
255   void resetNonModularOptions() {
256     Includes.clear();
257     MacroIncludes.clear();
258     ChainedIncludes.clear();
259     DumpDeserializedPCHDecls = false;
260     ImplicitPCHInclude.clear();
261     SingleFileParseMode = false;
262     LexEditorPlaceholders = true;
263     RetainRemappedFileBuffers = true;
264     PrecompiledPreambleBytes.first = 0;
265     PrecompiledPreambleBytes.second = false;
266     RetainExcludedConditionalBlocks = false;
267   }
268 };
269 
270 } // namespace clang
271 
272 #endif // LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
273