Last active
November 23, 2023 01:09
-
-
Save sgielen/8685438 to your computer and use it in GitHub Desktop.
Clang plugin by John Bartholomew for finding globals and non-const static variables, unpacked
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
warnglobals.so |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -Wglobals Clang plugin | |
// | |
// Based on example plugins and searching Clang's API documentation. | |
// BEWARE! This is my first ever attempt at a Clang plugin. | |
// | |
// Written by John Bartholomew <jpa.bartholomew@gmail.com> | |
#include "clang/Frontend/FrontendPluginRegistry.h" | |
#include "clang/AST/AST.h" | |
#include "clang/AST/ASTConsumer.h" | |
#include "clang/AST/RecursiveASTVisitor.h" | |
#include "clang/Frontend/CompilerInstance.h" | |
namespace { | |
class PrintGlobalsVisitor : public clang::RecursiveASTVisitor<PrintGlobalsVisitor> { | |
public: | |
explicit PrintGlobalsVisitor(clang::ASTContext *Context, clang::DiagnosticsEngine *Diagnostics) | |
: Context(Context), Diagnostics(Diagnostics) {} | |
bool VisitVarDecl(clang::VarDecl *D) { | |
const clang::SourceManager &SM = Context->getSourceManager(); | |
if (D->hasGlobalStorage() && !D->getType().isConstQualified()) { | |
clang::FullSourceLoc loc = Context->getFullLoc(D->getLocStart()); | |
if (!SM.isInSystemHeader(loc)) { | |
clang::DiagnosticsEngine &D = *Diagnostics; | |
unsigned int id = D.getCustomDiagID(clang::DiagnosticsEngine::Warning, "global variable"); | |
D.Report(loc, id); | |
} | |
} | |
return true; | |
} | |
private: | |
clang::ASTContext *Context; | |
clang::DiagnosticsEngine *Diagnostics; | |
}; | |
class PrintGlobalsConsumer : public clang::ASTConsumer { | |
public: | |
explicit PrintGlobalsConsumer(clang::ASTContext *Context, clang::DiagnosticsEngine *Diagnostics) | |
: Visitor(Context, Diagnostics) {} | |
virtual void HandleTranslationUnit(clang::ASTContext &Context) { | |
Visitor.TraverseDecl(Context.getTranslationUnitDecl()); | |
} | |
private: | |
PrintGlobalsVisitor Visitor; | |
}; | |
class PrintGlobalsAction : public clang::PluginASTAction { | |
protected: | |
clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef) { | |
return new PrintGlobalsConsumer(&CI.getASTContext(), &CI.getDiagnostics()); | |
} | |
bool ParseArgs(const clang::CompilerInstance &CI, | |
const std::vector<std::string>& args) { | |
// To be written... | |
return true; | |
} | |
}; | |
} | |
static clang::FrontendPluginRegistry::Add<PrintGlobalsAction> | |
X("warn-globals", "generate warnings for non-const global variables"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
warnglobals.so: ClangWarnGlobals.cpp | |
clang++ -g -O0 -std=c++98 -shared -fPIC $$(llvm-config --cflags --ldflags --libs support mc) -o "$@" $^ -lclang | |
.PHONY: run | |
run: warnglobals.so | |
clang++ -Xclang -load -Xclang ./warnglobals.so -Xclang -plugin -Xclang warn-globals test.cpp | |
.PHONY: clean | |
clean: | |
rm -f warnglobals.so |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
static int s_some_global = 42; | |
static const int s_some_const_global = 42; | |
static void some_function_with_a_static() { | |
static int s_static_local = 42; | |
} | |
namespace some_namespace { | |
namespace some_sub_namespace { | |
int public_global = 42; | |
} | |
class some_class { | |
static const int static_const_member = 42; | |
static int static_member; | |
}; | |
} | |
int some_namespace::some_class::static_member = 42; | |
int main(int argc, char **argv) { | |
std::cout << "global value: " << s_some_global << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment