1 //===-- FrontendActions.h - Useful Frontend Actions -------------*- 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_FRONTEND_FRONTENDACTIONS_H
10 #define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
11 
12 #include "clang/Frontend/FrontendAction.h"
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 namespace clang {
18 
19 //===----------------------------------------------------------------------===//
20 // Custom Consumer Actions
21 //===----------------------------------------------------------------------===//
22 
23 class InitOnlyAction : public FrontendAction {
24   void ExecuteAction() override;
25 
26   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
27                                                  StringRef InFile) override;
28 
29 public:
30   // Don't claim to only use the preprocessor, we want to follow the AST path,
31   // but do nothing.
usesPreprocessorOnly()32   bool usesPreprocessorOnly() const override { return false; }
33 };
34 
35 /// Preprocessor-based frontend action that also loads PCH files.
36 class ReadPCHAndPreprocessAction : public FrontendAction {
37   void ExecuteAction() override;
38 
39   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
40                                                  StringRef InFile) override;
41 
42 public:
usesPreprocessorOnly()43   bool usesPreprocessorOnly() const override { return false; }
44 };
45 
46 class DumpCompilerOptionsAction : public FrontendAction {
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)47   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
48                                                  StringRef InFile) override {
49     return nullptr;
50   }
51 
52   void ExecuteAction() override;
53 
54 public:
usesPreprocessorOnly()55   bool usesPreprocessorOnly() const override { return true; }
56 };
57 
58 //===----------------------------------------------------------------------===//
59 // AST Consumer Actions
60 //===----------------------------------------------------------------------===//
61 
62 class ASTPrintAction : public ASTFrontendAction {
63 protected:
64   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
65                                                  StringRef InFile) override;
66 };
67 
68 class ASTDumpAction : public ASTFrontendAction {
69 protected:
70   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
71                                                  StringRef InFile) override;
72 };
73 
74 class ASTDeclListAction : public ASTFrontendAction {
75 protected:
76   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
77                                                  StringRef InFile) override;
78 };
79 
80 class ASTViewAction : public ASTFrontendAction {
81 protected:
82   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
83                                                  StringRef InFile) override;
84 };
85 
86 class GeneratePCHAction : public ASTFrontendAction {
87 protected:
88   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
89                                                  StringRef InFile) override;
90 
getTranslationUnitKind()91   TranslationUnitKind getTranslationUnitKind() override {
92     return TU_Prefix;
93   }
94 
hasASTFileSupport()95   bool hasASTFileSupport() const override { return false; }
96 
97   bool shouldEraseOutputFiles() override;
98 
99 public:
100   /// Compute the AST consumer arguments that will be used to
101   /// create the PCHGenerator instance returned by CreateASTConsumer.
102   ///
103   /// \returns false if an error occurred, true otherwise.
104   static bool ComputeASTConsumerArguments(CompilerInstance &CI,
105                                           std::string &Sysroot);
106 
107   /// Creates file to write the PCH into and returns a stream to write it
108   /// into. On error, returns null.
109   static std::unique_ptr<llvm::raw_pwrite_stream>
110   CreateOutputFile(CompilerInstance &CI, StringRef InFile,
111                    std::string &OutputFile);
112 
113   bool BeginSourceFileAction(CompilerInstance &CI) override;
114 };
115 
116 class GenerateModuleAction : public ASTFrontendAction {
117   virtual std::unique_ptr<raw_pwrite_stream>
118   CreateOutputFile(CompilerInstance &CI, StringRef InFile) = 0;
119 
120 protected:
121   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
122                                                  StringRef InFile) override;
123 
getTranslationUnitKind()124   TranslationUnitKind getTranslationUnitKind() override {
125     return TU_Module;
126   }
127 
hasASTFileSupport()128   bool hasASTFileSupport() const override { return false; }
129 
130   bool shouldEraseOutputFiles() override;
131 };
132 
133 class GenerateInterfaceStubsAction : public ASTFrontendAction {
134 protected:
135   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
136                                                  StringRef InFile) override;
137 
getTranslationUnitKind()138   TranslationUnitKind getTranslationUnitKind() override { return TU_Module; }
hasASTFileSupport()139   bool hasASTFileSupport() const override { return false; }
140 };
141 
142 class GenerateModuleFromModuleMapAction : public GenerateModuleAction {
143 private:
144   bool BeginSourceFileAction(CompilerInstance &CI) override;
145 
146   std::unique_ptr<raw_pwrite_stream>
147   CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
148 };
149 
150 class GenerateModuleInterfaceAction : public GenerateModuleAction {
151 private:
152   bool BeginSourceFileAction(CompilerInstance &CI) override;
153 
154   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
155                                                  StringRef InFile) override;
156 
157   std::unique_ptr<raw_pwrite_stream>
158   CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
159 };
160 
161 class GenerateHeaderUnitAction : public GenerateModuleAction {
162 
163 private:
164   bool BeginSourceFileAction(CompilerInstance &CI) override;
165 
166   std::unique_ptr<raw_pwrite_stream>
167   CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
168 };
169 
170 class SyntaxOnlyAction : public ASTFrontendAction {
171 protected:
172   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
173                                                  StringRef InFile) override;
174 
175 public:
176   ~SyntaxOnlyAction() override;
hasCodeCompletionSupport()177   bool hasCodeCompletionSupport() const override { return true; }
178 };
179 
180 /// Dump information about the given module file, to be used for
181 /// basic debugging and discovery.
182 class DumpModuleInfoAction : public ASTFrontendAction {
183   // Allow other tools (ex lldb) to direct output for their use.
184   std::shared_ptr<llvm::raw_ostream> OutputStream;
185 
186 protected:
187   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
188                                                  StringRef InFile) override;
189   bool BeginInvocation(CompilerInstance &CI) override;
190   void ExecuteAction() override;
191 
192 public:
193   DumpModuleInfoAction() = default;
DumpModuleInfoAction(std::shared_ptr<llvm::raw_ostream> Out)194   explicit DumpModuleInfoAction(std::shared_ptr<llvm::raw_ostream> Out)
195       : OutputStream(Out) {}
hasPCHSupport()196   bool hasPCHSupport() const override { return false; }
hasASTFileSupport()197   bool hasASTFileSupport() const override { return true; }
hasIRSupport()198   bool hasIRSupport() const override { return false; }
hasCodeCompletionSupport()199   bool hasCodeCompletionSupport() const override { return false; }
200 };
201 
202 class VerifyPCHAction : public ASTFrontendAction {
203 protected:
204   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
205                                                  StringRef InFile) override;
206 
207   void ExecuteAction() override;
208 
209 public:
hasCodeCompletionSupport()210   bool hasCodeCompletionSupport() const override { return false; }
211 };
212 
213 class TemplightDumpAction : public ASTFrontendAction {
214 protected:
215   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
216                                                  StringRef InFile) override;
217 
218   void ExecuteAction() override;
219 };
220 
221 /**
222  * Frontend action adaptor that merges ASTs together.
223  *
224  * This action takes an existing AST file and "merges" it into the AST
225  * context, producing a merged context. This action is an action
226  * adaptor, which forwards most of its calls to another action that
227  * will consume the merged context.
228  */
229 class ASTMergeAction : public FrontendAction {
230   /// The action that the merge action adapts.
231   std::unique_ptr<FrontendAction> AdaptedAction;
232 
233   /// The set of AST files to merge.
234   std::vector<std::string> ASTFiles;
235 
236 protected:
237   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
238                                                  StringRef InFile) override;
239 
240   bool BeginSourceFileAction(CompilerInstance &CI) override;
241 
242   void ExecuteAction() override;
243   void EndSourceFileAction() override;
244 
245 public:
246   ASTMergeAction(std::unique_ptr<FrontendAction> AdaptedAction,
247                  ArrayRef<std::string> ASTFiles);
248   ~ASTMergeAction() override;
249 
250   bool usesPreprocessorOnly() const override;
251   TranslationUnitKind getTranslationUnitKind() override;
252   bool hasPCHSupport() const override;
253   bool hasASTFileSupport() const override;
254   bool hasCodeCompletionSupport() const override;
255 };
256 
257 class PrintPreambleAction : public FrontendAction {
258 protected:
259   void ExecuteAction() override;
CreateASTConsumer(CompilerInstance &,StringRef)260   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
261                                                  StringRef) override {
262     return nullptr;
263   }
264 
usesPreprocessorOnly()265   bool usesPreprocessorOnly() const override { return true; }
266 };
267 
268 class PrintDependencyDirectivesSourceMinimizerAction : public FrontendAction {
269 protected:
270   void ExecuteAction() override;
CreateASTConsumer(CompilerInstance &,StringRef)271   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
272                                                  StringRef) override {
273     return nullptr;
274   }
275 
usesPreprocessorOnly()276   bool usesPreprocessorOnly() const override { return true; }
277 };
278 
279 //===----------------------------------------------------------------------===//
280 // Preprocessor Actions
281 //===----------------------------------------------------------------------===//
282 
283 class DumpRawTokensAction : public PreprocessorFrontendAction {
284 protected:
285   void ExecuteAction() override;
286 };
287 
288 class DumpTokensAction : public PreprocessorFrontendAction {
289 protected:
290   void ExecuteAction() override;
291 };
292 
293 class PreprocessOnlyAction : public PreprocessorFrontendAction {
294 protected:
295   void ExecuteAction() override;
296 };
297 
298 class PrintPreprocessedAction : public PreprocessorFrontendAction {
299 protected:
300   void ExecuteAction() override;
301 
hasPCHSupport()302   bool hasPCHSupport() const override { return true; }
303 };
304 
305 class GetDependenciesByModuleNameAction : public PreprocessOnlyAction {
306   StringRef ModuleName;
307   void ExecuteAction() override;
308 
309 public:
GetDependenciesByModuleNameAction(StringRef ModuleName)310   GetDependenciesByModuleNameAction(StringRef ModuleName)
311       : ModuleName(ModuleName) {}
312 };
313 
314 }  // end namespace clang
315 
316 #endif
317