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/LLVM.h"
13 #include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSet.h"
16 #include <functional>
17 #include <map>
18 #include <memory>
19 #include <set>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 namespace llvm {
25 
26 class MemoryBuffer;
27 
28 } // namespace llvm
29 
30 namespace clang {
31 
32 /// Enumerate the kinds of standard library that
33 enum ObjCXXARCStandardLibraryKind {
34   ARCXX_nolib,
35 
36   /// libc++
37   ARCXX_libcxx,
38 
39   /// libstdc++
40   ARCXX_libstdcxx
41 };
42 
43 /// PreprocessorOptions - This class is used for passing the various options
44 /// used in preprocessor initialization to InitializePreprocessor().
45 class PreprocessorOptions {
46 public:
47   std::vector<std::pair<std::string, bool/*isUndef*/>> Macros;
48   std::vector<std::string> Includes;
49   std::vector<std::string> MacroIncludes;
50 
51   /// Initialize the preprocessor with the compiler and target specific
52   /// predefines.
53   bool UsePredefines = true;
54 
55   /// Whether we should maintain a detailed record of all macro
56   /// definitions and expansions.
57   bool DetailedRecord = false;
58 
59   /// When true, we are creating or using a PCH where a #pragma hdrstop is
60   /// expected to indicate the beginning or end of the PCH.
61   bool PCHWithHdrStop = false;
62 
63   /// When true, we are creating a PCH or creating the PCH object while
64   /// expecting a #pragma hdrstop to separate the two.  Allow for a
65   /// missing #pragma hdrstop, which generates a PCH for the whole file,
66   /// and creates an empty PCH object.
67   bool PCHWithHdrStopCreate = false;
68 
69   /// If non-empty, the filename used in an #include directive in the primary
70   /// source file (or command-line preinclude) that is used to implement
71   /// MSVC-style precompiled headers. When creating a PCH, after the #include
72   /// of this header, the PCH generation stops. When using a PCH, tokens are
73   /// skipped until after an #include of this header is seen.
74   std::string PCHThroughHeader;
75 
76   /// The implicit PCH included at the start of the translation unit, or empty.
77   std::string ImplicitPCHInclude;
78 
79   /// Headers that will be converted to chained PCHs in memory.
80   std::vector<std::string> ChainedIncludes;
81 
82   /// When true, disables most of the normal validation performed on
83   /// precompiled headers.
84   bool DisablePCHValidation = false;
85 
86   /// When true, a PCH with compiler errors will not be rejected.
87   bool AllowPCHWithCompilerErrors = false;
88 
89   /// Dump declarations that are deserialized from PCH, for testing.
90   bool DumpDeserializedPCHDecls = false;
91 
92   /// This is a set of names for decls that we do not want to be
93   /// deserialized, and we emit an error if they are; for testing purposes.
94   std::set<std::string> DeserializedPCHDeclsToErrorOn;
95 
96   /// If non-zero, the implicit PCH include is actually a precompiled
97   /// preamble that covers this number of bytes in the main source file.
98   ///
99   /// The boolean indicates whether the preamble ends at the start of a new
100   /// line.
101   std::pair<unsigned, bool> PrecompiledPreambleBytes;
102 
103   /// True indicates that a preamble is being generated.
104   ///
105   /// When the lexer is done, one of the things that need to be preserved is the
106   /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
107   /// processing the rest of the file.
108   bool GeneratePreamble = false;
109 
110   /// Whether to write comment locations into the PCH when building it.
111   /// Reading the comments from the PCH can be a performance hit even if the
112   /// clients don't use them.
113   bool WriteCommentListToPCH = true;
114 
115   /// When enabled, preprocessor is in a mode for parsing a single file only.
116   ///
117   /// Disables #includes of other files and if there are unresolved identifiers
118   /// in preprocessor directive conditions it causes all blocks to be parsed so
119   /// that the client can get the maximum amount of information from the parser.
120   bool SingleFileParseMode = false;
121 
122   /// When enabled, the preprocessor will construct editor placeholder tokens.
123   bool LexEditorPlaceholders = true;
124 
125   /// True if the SourceManager should report the original file name for
126   /// contents of files that were remapped to other files. Defaults to true.
127   bool RemappedFilesKeepOriginalName = true;
128 
129   /// The set of file remappings, which take existing files on
130   /// the system (the first part of each pair) and gives them the
131   /// contents of other files on the system (the second part of each
132   /// pair).
133   std::vector<std::pair<std::string, std::string>> RemappedFiles;
134 
135   /// The set of file-to-buffer remappings, which take existing files
136   /// on the system (the first part of each pair) and gives them the contents
137   /// of the specified memory buffer (the second part of each pair).
138   std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
139 
140   /// Whether the compiler instance should retain (i.e., not free)
141   /// the buffers associated with remapped files.
142   ///
143   /// This flag defaults to false; it can be set true only through direct
144   /// manipulation of the compiler invocation object, in cases where the
145   /// compiler invocation and its buffers will be reused.
146   bool RetainRemappedFileBuffers = false;
147 
148   /// When enabled, excluded conditional blocks retain in the main file.
149   bool RetainExcludedConditionalBlocks = false;
150 
151   /// The Objective-C++ ARC standard library that we should support,
152   /// by providing appropriate definitions to retrofit the standard library
153   /// with support for lifetime-qualified pointers.
154   ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
155 
156   /// Records the set of modules
157   class FailedModulesSet {
158     llvm::StringSet<> Failed;
159 
160   public:
161     bool hasAlreadyFailed(StringRef module) {
162       return Failed.count(module) > 0;
163     }
164 
165     void addFailed(StringRef module) {
166       Failed.insert(module);
167     }
168   };
169 
170   /// The set of modules that failed to build.
171   ///
172   /// This pointer will be shared among all of the compiler instances created
173   /// to (re)build modules, so that once a module fails to build anywhere,
174   /// other instances will see that the module has failed and won't try to
175   /// build it again.
176   std::shared_ptr<FailedModulesSet> FailedModules;
177 
178   /// A prefix map for __FILE__ and __BASE_FILE__.
179   std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
180 
181   /// Contains the currently active skipped range mappings for skipping excluded
182   /// conditional directives.
183   ///
184   /// The pointer is passed to the Preprocessor when it's constructed. The
185   /// pointer is unowned, the client is responsible for its lifetime.
186   ExcludedPreprocessorDirectiveSkipMapping
187       *ExcludedConditionalDirectiveSkipMappings = nullptr;
188 
189   /// Set up preprocessor for RunAnalysis action.
190   bool SetUpStaticAnalyzer = false;
191 
192   /// Prevents intended crashes when using #pragma clang __debug. For testing.
193   bool DisablePragmaDebugCrash = false;
194 
195 public:
196   PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
197 
198   void addMacroDef(StringRef Name) {
199     Macros.emplace_back(std::string(Name), false);
200   }
201   void addMacroUndef(StringRef Name) {
202     Macros.emplace_back(std::string(Name), true);
203   }
204 
205   void addRemappedFile(StringRef From, StringRef To) {
206     RemappedFiles.emplace_back(std::string(From), std::string(To));
207   }
208 
209   void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
210     RemappedFileBuffers.emplace_back(std::string(From), To);
211   }
212 
213   void clearRemappedFiles() {
214     RemappedFiles.clear();
215     RemappedFileBuffers.clear();
216   }
217 
218   /// Reset any options that are not considered when building a
219   /// module.
220   void resetNonModularOptions() {
221     Includes.clear();
222     MacroIncludes.clear();
223     ChainedIncludes.clear();
224     DumpDeserializedPCHDecls = false;
225     ImplicitPCHInclude.clear();
226     SingleFileParseMode = false;
227     LexEditorPlaceholders = true;
228     RetainRemappedFileBuffers = true;
229     PrecompiledPreambleBytes.first = 0;
230     PrecompiledPreambleBytes.second = false;
231     RetainExcludedConditionalBlocks = false;
232   }
233 };
234 
235 } // namespace clang
236 
237 #endif // LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
238