[PATCH] D27982: [change-namespace] do not fix calls to overloaded operator functions.
Eric Liu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 20 04:58:00 PST 2016
ioeric updated this revision to Diff 82098.
ioeric added a comment.
- minor fix.
https://reviews.llvm.org/D27982
Files:
change-namespace/ChangeNamespace.cpp
change-namespace/ChangeNamespace.h
unittests/change-namespace/ChangeNamespaceTests.cpp
Index: unittests/change-namespace/ChangeNamespaceTests.cpp
===================================================================
--- unittests/change-namespace/ChangeNamespaceTests.cpp
+++ unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -575,6 +575,47 @@
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
+// FIXME: function calls to overloaded operators are not fixed now even if they
+// are referenced by qualified names.
+TEST_F(ChangeNamespaceTest, FixOverloadedOperatorFunctionNameSpecifiers) {
+ std::string Code =
+ "namespace na {\n"
+ "class A {\n"
+ "public:\n"
+ " int x;\n"
+ " bool operator==(const A &RHS) const { return x == RHS.x; }\n"
+ "};\n"
+ "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n"
+ "namespace nb {\n"
+ "bool f() {\n"
+ " A x, y;\n"
+ " auto f = operator<;"
+ " return (x == y) && (x < y) && (operator<(x, y));"
+ "}\n"
+ "} // namespace nb\n"
+ "} // namespace na\n";
+ std::string Expected =
+ "namespace na {\n"
+ "class A {\n"
+ "public:\n"
+ " int x;\n"
+ " bool operator==(const A &RHS) const { return x == RHS.x; }\n"
+ "};\n"
+ "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n"
+ "\n"
+ "} // namespace na\n"
+ "namespace x {\n"
+ "namespace y {\n"
+ "bool f() {\n"
+ " ::na::A x, y;\n"
+ " auto f = ::na::operator<;"
+ " return (x == y) && (x < y) && (operator<(x,y));"
+ "}\n"
+ "} // namespace y\n"
+ "} // namespace x\n";
+ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) {
std::string Code = "namespace na {\n"
"class A {\n"
Index: change-namespace/ChangeNamespace.h
===================================================================
--- change-namespace/ChangeNamespace.h
+++ change-namespace/ChangeNamespace.h
@@ -157,6 +157,10 @@
// 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
Index: change-namespace/ChangeNamespace.cpp
===================================================================
--- change-namespace/ChangeNamespace.cpp
+++ change-namespace/ChangeNamespace.cpp
@@ -481,6 +481,11 @@
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 @@
} 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() ==
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27982.82098.patch
Type: text/x-patch
Size: 4052 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161220/1577c998/attachment-0001.bin>
More information about the cfe-commits
mailing list