balazske updated this revision to Diff 336333.
balazske added a comment.
Rebase, changed test according to review comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D95244/new/
https://reviews.llvm.org/D95244
Files:
clang/lib/AST/Expr.cpp
clang/unittests/Tooling/SourceCodeTest.cpp
Index: clang/unittests/Tooling/SourceCodeTest.cpp
===================================================================
--- clang/unittests/Tooling/SourceCodeTest.cpp
+++ clang/unittests/Tooling/SourceCodeTest.cpp
@@ -621,4 +621,71 @@
};
Visitor.runOver(Code);
}
+
+TEST(SourceCodeTest, GetCallReturnType_Dependent) {
+ llvm::Annotations Code{R"cpp(
+template<class T, class F>
+void templ(const T& t, F f) {}
+
+template<class T, class F>
+void templ1(const T& t, F f) {
+ $test1[[f(t)]];
+}
+
+int f_overload(int) { return 1; }
+int f_overload(double) { return 2; }
+
+void f1() {
+ int i = 0;
+ templ(i, [](const auto &p) {
+ $test2[[f_overload(p)]];
+ });
+}
+
+struct A {
+ void f_overload(int);
+ void f_overload(double);
+};
+
+void f2() {
+ int i = 0;
+ templ(i, [](const auto &p) {
+ A a;
+ $test3[[a.f_overload(p)]];
+ });
+}
+)cpp"};
+
+ llvm::Annotations::Range R1 = Code.range("test1");
+ llvm::Annotations::Range R2 = Code.range("test2");
+ llvm::Annotations::Range R3 = Code.range("test3");
+
+ CallsVisitor Visitor;
+ Visitor.OnCall = [&R1, &R2, &R3](CallExpr *Expr, ASTContext *Context) {
+ unsigned Begin = Context->getSourceManager().getFileOffset(
+ Expr->getSourceRange().getBegin());
+ unsigned End = Context->getSourceManager().getFileOffset(
+ Expr->getSourceRange().getEnd());
+ llvm::Annotations::Range R{Begin, End + 1};
+
+ QualType CalleeType = Expr->getCallee()->getType();
+ if (R == R1) {
+ ASSERT_TRUE(CalleeType->isDependentType());
+ EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy);
+ } else if (R == R2) {
+ ASSERT_FALSE(CalleeType->isDependentType());
+ ASSERT_TRUE(CalleeType->isSpecificPlaceholderType(BuiltinType::Overload));
+ ASSERT_TRUE(isa<UnresolvedLookupExpr>(Expr->getCallee()));
+ EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy);
+ } else if (R == R3) {
+ ASSERT_FALSE(CalleeType->isDependentType());
+ ASSERT_TRUE(
+ CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember));
+ ASSERT_TRUE(isa<UnresolvedMemberExpr>(Expr->getCallee()));
+ EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy);
+ }
+ };
+ Visitor.runOver(Code.code(), CallsVisitor::Lang_CXX14);
+}
+
} // end anonymous namespace
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1383,6 +1383,7 @@
QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const {
const Expr *Callee = getCallee();
QualType CalleeType = Callee->getType();
+
if (const auto *FnTypePtr = CalleeType->getAs<PointerType>()) {
CalleeType = FnTypePtr->getPointeeType();
} else if (const auto *BPT = CalleeType->getAs<BlockPointerType>()) {
@@ -1391,8 +1392,16 @@
if (isa<CXXPseudoDestructorExpr>(Callee->IgnoreParens()))
return Ctx.VoidTy;
+ if (isa<UnresolvedMemberExpr>(Callee->IgnoreParens()))
+ return Ctx.DependentTy;
+
// This should never be overloaded and so should never return null.
CalleeType = Expr::findBoundMemberType(Callee);
+ assert(!CalleeType.isNull());
+
+ } else if (CalleeType->isDependentType() ||
+ CalleeType->isSpecificPlaceholderType(BuiltinType::Overload)) {
+ return Ctx.DependentTy;
}
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits