diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-11-10 18:38:26 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-11-10 18:38:26 +0000 |
commit | 30af175b76d67b52af6816c3bde51b01271c9064 (patch) | |
tree | 49f4a117d2a261d78ecc0dc27c22bf7f6675f8f3 /clang-plugin | |
parent | 5570704c53a565e9eb70e362ee341d6aacf8b823 (diff) | |
download | rspamd-30af175b76d67b52af6816c3bde51b01271c9064.tar.gz rspamd-30af175b76d67b52af6816c3bde51b01271c9064.zip |
Start do something useful with libclang plugin
Diffstat (limited to 'clang-plugin')
-rw-r--r-- | clang-plugin/plugin.cc | 85 |
1 files changed, 58 insertions, 27 deletions
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 <unordered_map> 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<NamedDecl> (D)) - llvm::errs () << "top-level-decl: \"" << - ND->getNameAsString () << "\"\n"; - } - - return true; - } - void HandleTranslationUnit (ASTContext &context) override { struct Visitor : public RecursiveASTVisitor<Visitor> { + std::unordered_map<std::string, int> 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<NamedDecl> (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<StringLiteral> ( + r.Val.getLValueBase ().get<const Expr *> ()); + 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<FunctionDecl *> 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"; - } } }; |