Skip to content

Instantly share code, notes, and snippets.

Created June 15, 2011 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/1027771 to your computer and use it in GitHub Desktop.
Save anonymous/1027771 to your computer and use it in GitHub Desktop.
prints functions, function calls and function pointers
//===- PrintFunctionNames.cpp ---------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Example clang plugin which simply prints the names of all the top-level decls
// in the input file.
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/AST.h"
#include "clang/Frontend/CompilerInstance.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
#include <iostream>
#include <string>
using namespace std;
namespace {
class PrintFunctionsConsumer : public ASTConsumer, public RecursiveASTVisitor<PrintFunctionsConsumer> {
public:
bool VisitCallExpr(CallExpr *E) {
NamedDecl *callee = dyn_cast<NamedDecl>(E->getCalleeDecl());
if(callee == NULL) {
llvm::errs() << "WTF";
return false;
}
cout << "\tCALL " << callee->getNameAsString() << endl;
return true;
}
bool VisitDecl(Decl *D) {
string kindName(D->getDeclKindName());
if(kindName == "Function") {
NamedDecl *namedDecl = dyn_cast<NamedDecl>(D);
if(namedDecl == NULL) {
llvm::errs() << "WTF";
return false;
}
cout << "FUNCTION " << namedDecl->getNameAsString() << endl;
} else if(kindName == "Var") {
VarDecl *varDecl = dyn_cast<VarDecl>(D);
if(varDecl == NULL) {
llvm::errs() << "WTF";
return false;
}
if(varDecl->getType()->isFunctionPointerType() == true)
cout << "\tFUNCTION POINTER " << varDecl->getNameAsString() << endl;
}
// llvm::errs() << "VisitDecl() = " << D->getDeclKindName() << "\n";
return true;
}
virtual void HandleTranslationUnit(ASTContext &ctx) {
TraverseDecl(ctx.getTranslationUnitDecl());
}
};
class PrintFunctionNamesAction : public PluginASTAction {
protected:
ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
return new PrintFunctionsConsumer();
}
bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string>& args) {
for (unsigned i = 0, e = args.size(); i != e; ++i) {
llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
// Example error handling.
if (args[i] == "-an-error") {
Diagnostic &D = CI.getDiagnostics();
unsigned DiagID = D.getCustomDiagID(
Diagnostic::Error, "invalid argument '" + args[i] + "'");
D.Report(DiagID);
return false;
}
}
if (args.size() && args[0] == "help")
PrintHelp(llvm::errs());
return true;
}
void PrintHelp(llvm::raw_ostream& ros) {
ros << "Help for PrintFunctionNames plugin goes here\n";
}
};
}
static FrontendPluginRegistry::Add<PrintFunctionNamesAction>
X("print-fns", "print function names");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment