From: Vsevolod Stakhov Date: Tue, 10 Nov 2015 18:38:26 +0000 (+0000) Subject: Start do something useful with libclang plugin X-Git-Tag: 1.1.0~598 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=30af175b76d67b52af6816c3bde51b01271c9064;p=rspamd.git Start do something useful with libclang plugin --- diff --git a/clang-plugin/plugin.cc b/clang-plugin/plugin.cc index 204ce7b6f..1d80ba231 100644 --- a/clang-plugin/plugin.cc +++ b/clang-plugin/plugin.cc @@ -26,11 +26,13 @@ #include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/AST/AST.h" +#include "clang/AST/Expr.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Sema/Sema.h" #include "llvm/Support/raw_ostream.h" +#include using namespace clang; @@ -45,45 +47,74 @@ namespace { { } - bool HandleTopLevelDecl (DeclGroupRef DG) override - { - for (DeclGroupRef::iterator i = DG.begin (), e = DG.end (); i != e; - ++i) { - const Decl *D = *i; - if (const NamedDecl *ND = dyn_cast (D)) - llvm::errs () << "top-level-decl: \"" << - ND->getNameAsString () << "\"\n"; - } - - return true; - } - void HandleTranslationUnit (ASTContext &context) override { struct Visitor : public RecursiveASTVisitor { + std::unordered_map printf_functions; + ASTContext *pcontext; Visitor (void) { - } - - bool VisitFunctionDecl (FunctionDecl *FD) + /* name -> format string position */ + printf_functions = { + {"rspamd_printf", 0}, + {"rspamd_default_log_function", 4}, + {"rspamd_snprintf", 2}, + {"rspamd_fprintf", 1} + }; + }; + + bool VisitCallExpr (CallExpr *E) { - if (FD->isLateTemplateParsed ()) - LateParsedDecls.insert (FD); + auto callee = dyn_cast (E->getCalleeDecl ()); + if (callee == NULL) { + llvm::errs () << "Bad callee\n"; + return false; + } + + auto fname = callee->getNameAsString (); + + auto pos_it = printf_functions.find (fname); + + if (pos_it != printf_functions.end ()) { + const auto args = E->getArgs (); + auto pos = pos_it->second; + auto query = args[pos]; + + if (!query->isEvaluatable(*pcontext)) { + llvm::errs () << "Cannot evaluate query\n"; + return false; + } + + clang::Expr::EvalResult r; + + if (!query->EvaluateAsRValue (r, *pcontext)) { + llvm::errs () << "Cannot evaluate query\n"; + return false; + } + + auto qval = dyn_cast ( + r.Val.getLValueBase ().get ()); + if (qval) { + llvm::errs () << "query string: " + << qval->getString () << "\n"; + } + + for (auto i = pos + 1; i < E->getNumArgs (); i ++) { + auto arg = args[i]; + + if (arg) { + arg->dump (); + } + } + } + return true; } - std::set LateParsedDecls; } v; + v.pcontext = &context; v.TraverseDecl (context.getTranslationUnitDecl ()); - clang::Sema &sema = Instance.getSema (); - for (const FunctionDecl *FD : v.LateParsedDecls) { - clang::LateParsedTemplate *LPT = sema.LateParsedTemplateMap.lookup ( - FD); - sema.LateTemplateParser (sema.OpaqueParser, *LPT); - llvm::errs () << "late-parsed-decl: \"" << - FD->getNameAsString () << "\"\n"; - } } };