File indexing completed on 2026-05-10 08:37:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #ifndef LLVM_CLANG_TOOLING_TOOLING_H
0030 #define LLVM_CLANG_TOOLING_TOOLING_H
0031
0032 #include "clang/AST/ASTConsumer.h"
0033 #include "clang/Basic/FileManager.h"
0034 #include "clang/Basic/LLVM.h"
0035 #include "clang/Frontend/FrontendAction.h"
0036 #include "clang/Frontend/PCHContainerOperations.h"
0037 #include "clang/Tooling/ArgumentsAdjusters.h"
0038 #include "llvm/ADT/ArrayRef.h"
0039 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0040 #include "llvm/ADT/StringMap.h"
0041 #include "llvm/ADT/StringRef.h"
0042 #include "llvm/ADT/StringSet.h"
0043 #include "llvm/ADT/Twine.h"
0044 #include "llvm/Option/Option.h"
0045 #include "llvm/Support/VirtualFileSystem.h"
0046 #include <memory>
0047 #include <string>
0048 #include <utility>
0049 #include <vector>
0050
0051 namespace clang {
0052
0053 class CompilerInstance;
0054 class CompilerInvocation;
0055 class DiagnosticConsumer;
0056 class DiagnosticsEngine;
0057
0058 namespace driver {
0059
0060 class Compilation;
0061
0062 }
0063
0064 namespace tooling {
0065
0066 class CompilationDatabase;
0067
0068
0069
0070
0071
0072 const llvm::opt::ArgStringList *
0073 getCC1Arguments(DiagnosticsEngine *Diagnostics,
0074 driver::Compilation *Compilation);
0075
0076
0077
0078
0079
0080 class ToolAction {
0081 public:
0082 virtual ~ToolAction();
0083
0084
0085 virtual bool
0086 runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
0087 FileManager *Files,
0088 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0089 DiagnosticConsumer *DiagConsumer) = 0;
0090 };
0091
0092
0093
0094
0095
0096
0097
0098 class FrontendActionFactory : public ToolAction {
0099 public:
0100 ~FrontendActionFactory() override;
0101
0102
0103 bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
0104 FileManager *Files,
0105 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0106 DiagnosticConsumer *DiagConsumer) override;
0107
0108
0109 virtual std::unique_ptr<FrontendAction> create() = 0;
0110 };
0111
0112
0113
0114
0115
0116
0117
0118
0119 template <typename T>
0120 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
0121
0122
0123
0124
0125 class SourceFileCallbacks {
0126 public:
0127 virtual ~SourceFileCallbacks() = default;
0128
0129
0130
0131 virtual bool handleBeginSource(CompilerInstance &CI) {
0132 return true;
0133 }
0134
0135
0136
0137 virtual void handleEndSource() {}
0138 };
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 template <typename FactoryT>
0152 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
0153 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 bool runToolOnCode(std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
0165 const Twine &FileName = "input.cc",
0166 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0167 std::make_shared<PCHContainerOperations>());
0168
0169
0170
0171 using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 bool runToolOnCodeWithArgs(
0187 std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
0188 const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
0189 const Twine &ToolName = "clang-tool",
0190 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0191 std::make_shared<PCHContainerOperations>(),
0192 const FileContentMappings &VirtualMappedFiles = FileContentMappings());
0193
0194
0195 bool runToolOnCodeWithArgs(
0196 std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
0197 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
0198 const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
0199 const Twine &ToolName = "clang-tool",
0200 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0201 std::make_shared<PCHContainerOperations>());
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 std::unique_ptr<ASTUnit>
0212 buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
0213 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0214 std::make_shared<PCHContainerOperations>());
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
0234 StringRef Code, const std::vector<std::string> &Args,
0235 StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
0236 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0237 std::make_shared<PCHContainerOperations>(),
0238 ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster(),
0239 const FileContentMappings &VirtualMappedFiles = FileContentMappings(),
0240 DiagnosticConsumer *DiagConsumer = nullptr,
0241 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
0242 llvm::vfs::getRealFileSystem());
0243
0244
0245 class ToolInvocation {
0246 public:
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 ToolInvocation(std::vector<std::string> CommandLine,
0259 std::unique_ptr<FrontendAction> FAction, FileManager *Files,
0260 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0261 std::make_shared<PCHContainerOperations>());
0262
0263
0264
0265
0266
0267
0268
0269
0270 ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
0271 FileManager *Files,
0272 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
0273
0274 ~ToolInvocation();
0275
0276 ToolInvocation(const ToolInvocation &) = delete;
0277 ToolInvocation &operator=(const ToolInvocation &) = delete;
0278
0279
0280
0281 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
0282 this->DiagConsumer = DiagConsumer;
0283 }
0284
0285
0286 void setDiagnosticOptions(DiagnosticOptions *DiagOpts) {
0287 this->DiagOpts = DiagOpts;
0288 }
0289
0290
0291
0292
0293 bool run();
0294
0295 private:
0296 bool runInvocation(const char *BinaryName,
0297 driver::Compilation *Compilation,
0298 std::shared_ptr<CompilerInvocation> Invocation,
0299 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
0300
0301 std::vector<std::string> CommandLine;
0302 ToolAction *Action;
0303 bool OwnsAction;
0304 FileManager *Files;
0305 std::shared_ptr<PCHContainerOperations> PCHContainerOps;
0306 DiagnosticConsumer *DiagConsumer = nullptr;
0307 DiagnosticOptions *DiagOpts = nullptr;
0308 };
0309
0310
0311
0312
0313
0314
0315
0316
0317 class ClangTool {
0318 public:
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 ClangTool(const CompilationDatabase &Compilations,
0332 ArrayRef<std::string> SourcePaths,
0333 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0334 std::make_shared<PCHContainerOperations>(),
0335 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
0336 llvm::vfs::getRealFileSystem(),
0337 IntrusiveRefCntPtr<FileManager> Files = nullptr);
0338
0339 ~ClangTool();
0340
0341
0342 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
0343 this->DiagConsumer = DiagConsumer;
0344 }
0345
0346
0347
0348
0349
0350 void mapVirtualFile(StringRef FilePath, StringRef Content);
0351
0352
0353
0354
0355
0356 void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
0357
0358
0359 void clearArgumentsAdjusters();
0360
0361
0362
0363
0364
0365
0366
0367 int run(ToolAction *Action);
0368
0369
0370
0371 int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
0372
0373
0374
0375 void setPrintErrorMessage(bool PrintErrorMessage);
0376
0377
0378
0379
0380 FileManager &getFiles() { return *Files; }
0381
0382 llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }
0383
0384 private:
0385 const CompilationDatabase &Compilations;
0386 std::vector<std::string> SourcePaths;
0387 std::shared_ptr<PCHContainerOperations> PCHContainerOps;
0388
0389 llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
0390 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
0391 llvm::IntrusiveRefCntPtr<FileManager> Files;
0392
0393
0394 std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
0395
0396 llvm::StringSet<> SeenWorkingDirectories;
0397
0398 ArgumentsAdjuster ArgsAdjuster;
0399
0400 DiagnosticConsumer *DiagConsumer = nullptr;
0401
0402 bool PrintErrorMessage = true;
0403 };
0404
0405 template <typename T>
0406 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
0407 class SimpleFrontendActionFactory : public FrontendActionFactory {
0408 public:
0409 std::unique_ptr<FrontendAction> create() override {
0410 return std::make_unique<T>();
0411 }
0412 };
0413
0414 return std::unique_ptr<FrontendActionFactory>(
0415 new SimpleFrontendActionFactory);
0416 }
0417
0418 template <typename FactoryT>
0419 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
0420 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
0421 class FrontendActionFactoryAdapter : public FrontendActionFactory {
0422 public:
0423 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
0424 SourceFileCallbacks *Callbacks)
0425 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
0426
0427 std::unique_ptr<FrontendAction> create() override {
0428 return std::make_unique<ConsumerFactoryAdaptor>(ConsumerFactory,
0429 Callbacks);
0430 }
0431
0432 private:
0433 class ConsumerFactoryAdaptor : public ASTFrontendAction {
0434 public:
0435 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
0436 SourceFileCallbacks *Callbacks)
0437 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
0438
0439 std::unique_ptr<ASTConsumer>
0440 CreateASTConsumer(CompilerInstance &, StringRef) override {
0441 return ConsumerFactory->newASTConsumer();
0442 }
0443
0444 protected:
0445 bool BeginSourceFileAction(CompilerInstance &CI) override {
0446 if (!ASTFrontendAction::BeginSourceFileAction(CI))
0447 return false;
0448 if (Callbacks)
0449 return Callbacks->handleBeginSource(CI);
0450 return true;
0451 }
0452
0453 void EndSourceFileAction() override {
0454 if (Callbacks)
0455 Callbacks->handleEndSource();
0456 ASTFrontendAction::EndSourceFileAction();
0457 }
0458
0459 private:
0460 FactoryT *ConsumerFactory;
0461 SourceFileCallbacks *Callbacks;
0462 };
0463 FactoryT *ConsumerFactory;
0464 SourceFileCallbacks *Callbacks;
0465 };
0466
0467 return std::unique_ptr<FrontendActionFactory>(
0468 new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483 std::string getAbsolutePath(StringRef File);
0484
0485
0486 llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
0487 StringRef File);
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
0510 StringRef InvokedAs);
0511
0512
0513 void addExpandedResponseFiles(std::vector<std::string> &CommandLine,
0514 llvm::StringRef WorkingDir,
0515 llvm::cl::TokenizerCallback Tokenizer,
0516 llvm::vfs::FileSystem &FS);
0517
0518
0519 CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
0520 ArrayRef<const char *> CC1Args,
0521 const char *const BinaryName);
0522
0523 }
0524
0525 }
0526
0527 #endif