xref: /llvm-project/clang/examples/LLVMPrintFunctionNames/LLVMPrintFunctionNames.cpp (revision 74197925dcb144ba31c7abfc61494c31c03d1f64)
1 //===- LLVMPrintFunctionNames.cpp
2 //---------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Example clang plugin which simply prints the names of all the functions
11 // within the generated LLVM code.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/AST/AST.h"
16 #include "clang/AST/ASTConsumer.h"
17 #include "clang/AST/RecursiveASTVisitor.h"
18 #include "clang/Frontend/CompilerInstance.h"
19 #include "clang/Frontend/FrontendPluginRegistry.h"
20 #include "clang/Sema/Sema.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/IR/PassManager.h"
23 #include "llvm/Passes/OptimizationLevel.h"
24 #include "llvm/Passes/PassBuilder.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
27 
28 namespace {
29 
30 class PrintPass final : public llvm::AnalysisInfoMixin<PrintPass> {
31   friend struct llvm::AnalysisInfoMixin<PrintPass>;
32 
33 public:
34   using Result = llvm::PreservedAnalyses;
35 
run(llvm::Module & M,llvm::ModuleAnalysisManager & MAM)36   Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM) {
37     for (auto &F : M)
38       llvm::outs() << "[PrintPass] Found function: " << F.getName() << "\n";
39     return llvm::PreservedAnalyses::all();
40   }
isRequired()41   static bool isRequired() { return true; }
42 };
43 
PrintCallback(llvm::PassBuilder & PB)44 void PrintCallback(llvm::PassBuilder &PB) {
45   PB.registerPipelineStartEPCallback(
46       [](llvm::ModulePassManager &MPM, llvm::OptimizationLevel) {
47         MPM.addPass(PrintPass());
48       });
49 }
50 
51 class LLVMPrintFunctionsConsumer : public ASTConsumer {
52 public:
LLVMPrintFunctionsConsumer(CompilerInstance & Instance)53   LLVMPrintFunctionsConsumer(CompilerInstance &Instance) {
54     Instance.getCodeGenOpts().PassBuilderCallbacks.push_back(PrintCallback);
55   }
56 };
57 
58 class LLVMPrintFunctionNamesAction : public PluginASTAction {
59 protected:
CreateASTConsumer(CompilerInstance & CI,llvm::StringRef)60   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
61                                                  llvm::StringRef) override {
62     return std::make_unique<LLVMPrintFunctionsConsumer>(CI);
63   }
ParseArgs(const CompilerInstance &,const std::vector<std::string> &)64   bool ParseArgs(const CompilerInstance &,
65                  const std::vector<std::string> &) override {
66     return true;
67   }
getActionType()68   PluginASTAction::ActionType getActionType() override {
69     return AddBeforeMainAction;
70   }
71 };
72 
73 } // namespace
74 
75 static FrontendPluginRegistry::Add<LLVMPrintFunctionNamesAction>
76     X("llvm-print-fns", "print function names, llvm level");
77