diff options
-rw-r--r-- | compilerplugins/clang/compat.hxx | 12 | ||||
-rw-r--r-- | compilerplugins/clang/constfields.cxx | 6 | ||||
-rw-r--r-- | compilerplugins/clang/constmethod.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/constparams.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/constvars.cxx | 8 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 38 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.hxx | 15 | ||||
-rw-r--r-- | compilerplugins/clang/singlevalfields.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/unusedfields.cxx | 14 | ||||
-rw-r--r-- | compilerplugins/clang/unusedvariablemore.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/writeonlyvars.cxx | 12 |
11 files changed, 81 insertions, 32 deletions
diff --git a/compilerplugins/clang/compat.hxx b/compilerplugins/clang/compat.hxx index ca752552f677..76f076621394 100644 --- a/compilerplugins/clang/compat.hxx +++ b/compilerplugins/clang/compat.hxx @@ -24,6 +24,12 @@ #include "config_clang.h" +#if CLANG_VERSION >= 110000 +namespace clang { class DynTypedNodeList; } +#else +#include "clang/AST/ASTContext.h" +#endif + // Compatibility wrapper to abstract over (trivial) changes in the Clang API: namespace compat { @@ -289,6 +295,12 @@ inline clang::QualType getDeclaredReturnType(clang::FunctionDecl const * decl) { #endif } +#if CLANG_VERSION >= 110000 +using DynTypedNodeList = clang::DynTypedNodeList; +#else +using DynTypedNodeList = clang::ASTContext::DynTypedNodeList; +#endif + } #endif diff --git a/compilerplugins/clang/constfields.cxx b/compilerplugins/clang/constfields.cxx index 635774810717..b06773c55047 100644 --- a/compilerplugins/clang/constfields.cxx +++ b/compilerplugins/clang/constfields.cxx @@ -360,7 +360,7 @@ bool ConstFields::VisitMemberExpr(const MemberExpr* memberExpr) void ConstFields::check(const FieldDecl* fieldDecl, const Expr* memberExpr) { - auto parentsRange = compiler.getASTContext().getParents(*memberExpr); + auto parentsRange = getParents(*memberExpr); const Stmt* child = memberExpr; const Stmt* parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); @@ -369,7 +369,7 @@ void ConstFields::check(const FieldDecl* fieldDecl, const Expr* memberExpr) bool bDump = false; auto walkUp = [&]() { child = parent; - auto parentsRange = compiler.getASTContext().getParents(*parent); + auto parentsRange = getParents(*parent); parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); }; @@ -379,7 +379,7 @@ void ConstFields::check(const FieldDecl* fieldDecl, const Expr* memberExpr) { // check if we have an expression like // int& r = m_field; - auto parentsRange = compiler.getASTContext().getParents(*child); + auto parentsRange = getParents(*child); if (parentsRange.begin() != parentsRange.end()) { auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>()); diff --git a/compilerplugins/clang/constmethod.cxx b/compilerplugins/clang/constmethod.cxx index 45451152dc99..93496148b458 100644 --- a/compilerplugins/clang/constmethod.cxx +++ b/compilerplugins/clang/constmethod.cxx @@ -194,7 +194,7 @@ bool ConstMethod::checkIfCanBeConst(const Stmt* stmt, const CXXMethodDecl* cxxMe { const Stmt* parent = getParentStmt( stmt ); if (!parent) { - auto parentsRange = compiler.getASTContext().getParents(*stmt); + auto parentsRange = getParents(*stmt); if ( parentsRange.begin() == parentsRange.end()) return true; auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>()); diff --git a/compilerplugins/clang/constparams.cxx b/compilerplugins/clang/constparams.cxx index 95c8184009d7..8059495180a7 100644 --- a/compilerplugins/clang/constparams.cxx +++ b/compilerplugins/clang/constparams.cxx @@ -267,7 +267,7 @@ bool ConstParams::checkIfCanBeConst(const Stmt* stmt, const ParmVarDecl* parmVar if (!parent) { // check if we're inside a CXXCtorInitializer - auto parentsRange = compiler.getASTContext().getParents(*stmt); + auto parentsRange = getParents(*stmt); if ( parentsRange.begin() != parentsRange.end()) { if (auto cxxConstructorDecl = dyn_cast_or_null<CXXConstructorDecl>(parentsRange.begin()->get<Decl>())) diff --git a/compilerplugins/clang/constvars.cxx b/compilerplugins/clang/constvars.cxx index f89301fed205..3c78bd458ffa 100644 --- a/compilerplugins/clang/constvars.cxx +++ b/compilerplugins/clang/constvars.cxx @@ -304,7 +304,7 @@ bool ConstVars::VisitDeclRefExpr(const DeclRefExpr* declRefExpr) void ConstVars::check(const VarDecl* varDecl, const Expr* memberExpr) { - auto parentsRange = compiler.getASTContext().getParents(*memberExpr); + auto parentsRange = getParents(*memberExpr); const Stmt* child = memberExpr; const Stmt* parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); @@ -315,7 +315,7 @@ void ConstVars::check(const VarDecl* varDecl, const Expr* memberExpr) bool bDump = false; auto walkUp = [&]() { child = parent; - auto parentsRange = compiler.getASTContext().getParents(*parent); + auto parentsRange = getParents(*parent); parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); }; @@ -325,7 +325,7 @@ void ConstVars::check(const VarDecl* varDecl, const Expr* memberExpr) { // check if we have an expression like // int& r = var; - auto parentsRange = compiler.getASTContext().getParents(*child); + auto parentsRange = getParents(*child); if (parentsRange.begin() != parentsRange.end()) { auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>()); @@ -334,7 +334,7 @@ void ConstVars::check(const VarDecl* varDecl, const Expr* memberExpr) if (varDecl->isImplicit()) { // so we can walk up from inside a for-range stmt - parentsRange = compiler.getASTContext().getParents(*varDecl); + parentsRange = getParents(*varDecl); if (parentsRange.begin() != parentsRange.end()) parent = parentsRange.begin()->get<Stmt>(); } diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index b885ab5e5555..0ffab3ba36bd 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -184,9 +184,35 @@ bool Plugin::evaluate(const Expr* expr, APSInt& x) return false; } +compat::DynTypedNodeList Plugin::getParents(Decl const & decl) +{ +#if CLANG_VERSION >= 110000 + if (!parentMapContext_) { + parentMapContext_.reset(new ParentMapContext(compiler.getASTContext())); + parentMapContext_->setTraversalKind(TK_AsIs); + } + return parentMapContext_->getParents(decl); +#else + return compiler.getASTContext().getParents(decl); +#endif +} + +compat::DynTypedNodeList Plugin::getParents(Stmt const & stmt) +{ +#if CLANG_VERSION >= 110000 + if (!parentMapContext_) { + parentMapContext_.reset(new ParentMapContext(compiler.getASTContext())); + parentMapContext_->setTraversalKind(TK_AsIs); + } + return parentMapContext_->getParents(stmt); +#else + return compiler.getASTContext().getParents(stmt); +#endif +} + const Stmt* Plugin::getParentStmt( const Stmt* stmt ) { - auto parentsRange = compiler.getASTContext().getParents(*stmt); + auto parentsRange = getParents(*stmt); if ( parentsRange.begin() == parentsRange.end()) return nullptr; return parentsRange.begin()->get<Stmt>(); @@ -194,15 +220,15 @@ const Stmt* Plugin::getParentStmt( const Stmt* stmt ) Stmt* Plugin::getParentStmt( Stmt* stmt ) { - auto parentsRange = compiler.getASTContext().getParents(*stmt); + auto parentsRange = getParents(*stmt); if ( parentsRange.begin() == parentsRange.end()) return nullptr; return const_cast<Stmt*>(parentsRange.begin()->get<Stmt>()); } -const Decl* getFunctionDeclContext(ASTContext& context, const Stmt* stmt) +const Decl* Plugin::getFunctionDeclContext(const Stmt* stmt) { - auto const parents = context.getParents(*stmt); + auto const parents = getParents(*stmt); auto it = parents.begin(); if (it == parents.end()) @@ -218,14 +244,14 @@ const Decl* getFunctionDeclContext(ASTContext& context, const Stmt* stmt) stmt = it->get<Stmt>(); if (stmt) - return getFunctionDeclContext(context, stmt); + return getFunctionDeclContext(stmt); return nullptr; } const FunctionDecl* Plugin::getParentFunctionDecl( const Stmt* stmt ) { - const Decl *decl = getFunctionDeclContext(compiler.getASTContext(), stmt); + const Decl *decl = getFunctionDeclContext(stmt); if (decl) return static_cast<const FunctionDecl*>(decl->getNonClosureContext()); diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx index 361bca922035..2d43371feede 100644 --- a/compilerplugins/clang/plugin.hxx +++ b/compilerplugins/clang/plugin.hxx @@ -18,6 +18,8 @@ #include <clang/Basic/SourceManager.h> #include <clang/Frontend/CompilerInstance.h> #include <clang/Lex/Preprocessor.h> + +#include <memory> #include <unordered_map> #include <vector> @@ -26,6 +28,10 @@ #include "compat.hxx" #include "pluginhandler.hxx" +#if CLANG_VERSION >= 110000 +#include "clang/AST/ParentMapContext.h" +#endif + using namespace clang; using namespace llvm; @@ -78,8 +84,11 @@ protected: Returns the parent of the given AST node. Clang's internal AST representation doesn't provide this information, it can only provide children, but getting the parent is often useful for inspecting a part of the AST. */ + compat::DynTypedNodeList getParents(Decl const & decl); + compat::DynTypedNodeList getParents(Stmt const & stmt); const Stmt* getParentStmt( const Stmt* stmt ); Stmt* getParentStmt( Stmt* stmt ); + const Decl* getFunctionDeclContext(const Stmt* stmt); const FunctionDecl* getParentFunctionDecl( const Stmt* stmt ); /** @@ -112,6 +121,10 @@ private: enum { isRewriter = false }; const char* name; + +#if CLANG_VERSION >= 110000 + std::unique_ptr<ParentMapContext> parentMapContext_; +#endif }; template<typename Derived> @@ -309,8 +322,6 @@ bool hasExternalLinkage(VarDecl const * decl); bool isSmartPointerType(const clang::Type*); bool isSmartPointerType(const Expr*); -const Decl* getFunctionDeclContext(ASTContext& context, const Stmt* stmt); - } // namespace #endif // COMPILEPLUGIN_H diff --git a/compilerplugins/clang/singlevalfields.cxx b/compilerplugins/clang/singlevalfields.cxx index ce60eeea7df0..76902f22737f 100644 --- a/compilerplugins/clang/singlevalfields.cxx +++ b/compilerplugins/clang/singlevalfields.cxx @@ -315,7 +315,7 @@ void SingleValFields::walkPotentialAssign( const DeclaratorDecl* fieldOrVarDecl, while (!bPotentiallyAssignedTo) { // check for field being accessed by a reference variable e.g. Foo& f = m.foo; - auto parentsList = compiler.getASTContext().getParents(*child); + auto parentsList = getParents(*child); auto it = parentsList.begin(); if (it != parentsList.end()) { const VarDecl *varDecl = it->get<VarDecl>(); diff --git a/compilerplugins/clang/unusedfields.cxx b/compilerplugins/clang/unusedfields.cxx index 6bbb35930696..de879fc3476d 100644 --- a/compilerplugins/clang/unusedfields.cxx +++ b/compilerplugins/clang/unusedfields.cxx @@ -531,7 +531,7 @@ void UnusedFields::checkIfReadFrom(const FieldDecl* fieldDecl, const Expr* membe return; } - auto parentsRange = compiler.getASTContext().getParents(*memberExpr); + auto parentsRange = getParents(*memberExpr); const Stmt* child = memberExpr; const Stmt* parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); // walk up the tree until we find something interesting @@ -539,7 +539,7 @@ void UnusedFields::checkIfReadFrom(const FieldDecl* fieldDecl, const Expr* membe bool bDump = false; auto walkUp = [&]() { child = parent; - auto parentsRange = compiler.getASTContext().getParents(*parent); + auto parentsRange = getParents(*parent); parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); }; do @@ -547,7 +547,7 @@ void UnusedFields::checkIfReadFrom(const FieldDecl* fieldDecl, const Expr* membe if (!parent) { // check if we're inside a CXXCtorInitializer or a VarDecl - auto parentsRange = compiler.getASTContext().getParents(*child); + auto parentsRange = getParents(*child); if ( parentsRange.begin() != parentsRange.end()) { const Decl* decl = parentsRange.begin()->get<Decl>(); @@ -779,7 +779,7 @@ void UnusedFields::checkIfWrittenTo(const FieldDecl* fieldDecl, const Expr* memb if (std::find(insideConditionalCheckOfMemberSet.begin(), insideConditionalCheckOfMemberSet.end(), fieldDecl) != insideConditionalCheckOfMemberSet.end()) return; - auto parentsRange = compiler.getASTContext().getParents(*memberExpr); + auto parentsRange = getParents(*memberExpr); const Stmt* child = memberExpr; const Stmt* parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); // walk up the tree until we find something interesting @@ -787,7 +787,7 @@ void UnusedFields::checkIfWrittenTo(const FieldDecl* fieldDecl, const Expr* memb bool bDump = false; auto walkUp = [&]() { child = parent; - auto parentsRange = compiler.getASTContext().getParents(*parent); + auto parentsRange = getParents(*parent); parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); }; do @@ -796,7 +796,7 @@ void UnusedFields::checkIfWrittenTo(const FieldDecl* fieldDecl, const Expr* memb { // check if we have an expression like // int& r = m_field; - auto parentsRange = compiler.getASTContext().getParents(*child); + auto parentsRange = getParents(*child); if (parentsRange.begin() != parentsRange.end()) { auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>()); @@ -1157,7 +1157,7 @@ void UnusedFields::checkTouchedFromOutside(const FieldDecl* fieldDecl, const Exp if (memberExprParentFunction) memberExprParentFunction->dump(); memberExpr->dump(); - const Decl *decl = loplugin::getFunctionDeclContext(compiler.getASTContext(), memberExpr); + const Decl *decl = getFunctionDeclContext(memberExpr); if (decl) decl->dump(); std::cout << "site1" << std::endl; diff --git a/compilerplugins/clang/unusedvariablemore.cxx b/compilerplugins/clang/unusedvariablemore.cxx index ba137199ef4c..38e3bbe81fe0 100644 --- a/compilerplugins/clang/unusedvariablemore.cxx +++ b/compilerplugins/clang/unusedvariablemore.cxx @@ -208,7 +208,7 @@ bool UnusedVariableMore::checkifUnused(Stmt const* stmt, VarDecl const* varDecl) if (!parent) { // check if we're inside a CXXCtorInitializer - auto parentsRange = compiler.getASTContext().getParents(*stmt); + auto parentsRange = getParents(*stmt); if (parentsRange.begin() != parentsRange.end()) { auto parentDecl = parentsRange.begin()->get<Decl>(); diff --git a/compilerplugins/clang/writeonlyvars.cxx b/compilerplugins/clang/writeonlyvars.cxx index 6161b428557a..de8e77cc7610 100644 --- a/compilerplugins/clang/writeonlyvars.cxx +++ b/compilerplugins/clang/writeonlyvars.cxx @@ -593,7 +593,7 @@ bool WriteOnlyVars::TraverseIfStmt(IfStmt* ifStmt) void WriteOnlyVars::checkIfReadFrom(const VarDecl* varDecl, const Expr* memberExpr) { - auto parentsRange = compiler.getASTContext().getParents(*memberExpr); + auto parentsRange = getParents(*memberExpr); const Stmt* child = memberExpr; const Stmt* parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); @@ -602,7 +602,7 @@ void WriteOnlyVars::checkIfReadFrom(const VarDecl* varDecl, const Expr* memberEx bool bDump = false; auto walkupUp = [&]() { child = parent; - auto parentsRange = compiler.getASTContext().getParents(*parent); + auto parentsRange = getParents(*parent); parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); }; @@ -611,7 +611,7 @@ void WriteOnlyVars::checkIfReadFrom(const VarDecl* varDecl, const Expr* memberEx if (!parent) { // check if we're inside a CXXCtorInitializer or a VarDecl - auto parentsRange = compiler.getASTContext().getParents(*child); + auto parentsRange = getParents(*child); if (parentsRange.begin() != parentsRange.end()) { const Decl* decl = parentsRange.begin()->get<Decl>(); @@ -810,7 +810,7 @@ void WriteOnlyVars::checkIfWrittenTo(const VarDecl* varDecl, const Expr* memberE != insideConditionalCheckOfMemberSet.end()) return; - auto parentsRange = compiler.getASTContext().getParents(*memberExpr); + auto parentsRange = getParents(*memberExpr); const Stmt* child = memberExpr; const Stmt* parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); @@ -819,7 +819,7 @@ void WriteOnlyVars::checkIfWrittenTo(const VarDecl* varDecl, const Expr* memberE bool bDump = false; auto walkupUp = [&]() { child = parent; - auto parentsRange = compiler.getASTContext().getParents(*parent); + auto parentsRange = getParents(*parent); parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>(); }; @@ -829,7 +829,7 @@ void WriteOnlyVars::checkIfWrittenTo(const VarDecl* varDecl, const Expr* memberE { // check if we have an expression like // int& r = var; - auto parentsRange = compiler.getASTContext().getParents(*child); + auto parentsRange = getParents(*child); if (parentsRange.begin() != parentsRange.end()) { auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>()); |