This revision was automatically updated to reflect the committed changes. balazske marked an inline comment as done. Closed by commit rG6e5199104914: [clang][AST] Handle overload callee type in CallExpr::getCallReturnType. (authored by balazske).
Changed prior to commit: https://reviews.llvm.org/D95244?vs=336333&id=336764#toc 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 @@ -1391,8 +1391,15 @@ 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>();
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 @@ -1391,8 +1391,15 @@ 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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits