diff options
author | Eric Liu <ioeric@google.com> | 2016-12-20 14:39:04 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-12-20 14:39:04 +0000 |
commit | 6bd29d7be19e125401820587a4dd292c17fecabd (patch) | |
tree | ce9b7168132d429900a7d273d59e2ce16c5748f3 /clang-tools-extra/change-namespace | |
parent | c1d4eefa4ed86c7ebe2d47c008f451c0750d795e (diff) |
[change-namespace] do not fix calls to overloaded operator functions.
Summary: Also make sure one function reference is only processed once.
Reviewers: hokein
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D27982
Diffstat (limited to 'clang-tools-extra/change-namespace')
-rw-r--r-- | clang-tools-extra/change-namespace/ChangeNamespace.cpp | 13 | ||||
-rw-r--r-- | clang-tools-extra/change-namespace/ChangeNamespace.h | 4 |
2 files changed, 17 insertions, 0 deletions
diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.cpp b/clang-tools-extra/change-namespace/ChangeNamespace.cpp index 6c04a40880f..0877519478c 100644 --- a/clang-tools-extra/change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/change-namespace/ChangeNamespace.cpp @@ -481,6 +481,11 @@ void ChangeNamespaceTool::run( llvm::cast<NamedDecl>(Var), VarRef); } else if (const auto *FuncRef = Result.Nodes.getNodeAs<DeclRefExpr>("func_ref")) { + // If this reference has been processed as a function call, we do not + // process it again. + if (ProcessedFuncRefs.count(FuncRef)) + return; + ProcessedFuncRefs.insert(FuncRef); const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func_decl"); assert(Func); const auto *Context = Result.Nodes.getNodeAs<Decl>("dc"); @@ -490,8 +495,16 @@ void ChangeNamespaceTool::run( } else { const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call"); assert(Call != nullptr && "Expecting callback for CallExpr."); + const auto *CalleeFuncRef = + llvm::cast<DeclRefExpr>(Call->getCallee()->IgnoreImplicit()); + ProcessedFuncRefs.insert(CalleeFuncRef); const FunctionDecl *Func = Call->getDirectCallee(); assert(Func != nullptr); + // FIXME: ignore overloaded operators. This would miss cases where operators + // are called by qualified names (i.e. "ns::operator <"). Ignore such + // cases for now. + if (Func->isOverloadedOperator()) + return; // Ignore out-of-line static methods since they will be handled by nested // name specifiers. if (Func->getCanonicalDecl()->getStorageClass() == diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.h b/clang-tools-extra/change-namespace/ChangeNamespace.h index 342457adf4c..c8fb7a22355 100644 --- a/clang-tools-extra/change-namespace/ChangeNamespace.h +++ b/clang-tools-extra/change-namespace/ChangeNamespace.h @@ -157,6 +157,10 @@ private: // TypeLocs of CXXCtorInitializer. Types of CXXCtorInitializers do not need to // be fixed. llvm::SmallVector<TypeLoc, 8> BaseCtorInitializerTypeLocs; + // Since a DeclRefExpr for a function call can be matched twice (one as + // CallExpr and one as DeclRefExpr), we record all DeclRefExpr's that have + // been processed so that we don't handle them twice. + llvm::SmallPtrSet<const clang::DeclRefExpr*, 16> ProcessedFuncRefs; }; } // namespace change_namespace |