summaryrefslogtreecommitdiff
path: root/clang-tools-extra/change-namespace
diff options
context:
space:
mode:
authorEric Liu <ioeric@google.com>2016-12-20 14:39:04 +0000
committerEric Liu <ioeric@google.com>2016-12-20 14:39:04 +0000
commit6bd29d7be19e125401820587a4dd292c17fecabd (patch)
treece9b7168132d429900a7d273d59e2ce16c5748f3 /clang-tools-extra/change-namespace
parentc1d4eefa4ed86c7ebe2d47c008f451c0750d795e (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.cpp13
-rw-r--r--clang-tools-extra/change-namespace/ChangeNamespace.h4
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