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