diff --git a/lib/CppInterOp/CppInterOp.cpp b/lib/CppInterOp/CppInterOp.cpp index 6ee99240f..12b8da247 100755 --- a/lib/CppInterOp/CppInterOp.cpp +++ b/lib/CppInterOp/CppInterOp.cpp @@ -517,18 +517,28 @@ std::string GetCompleteName(TCppType_t klass) { auto& C = getSema().getASTContext(); auto* D = (Decl*)klass; + PrintingPolicy Policy = C.getPrintingPolicy(); + Policy.SuppressUnwrittenScope = true; + Policy.SuppressScope = true; + Policy.AnonymousTagLocations = false; + Policy.SuppressTemplateArgsInCXXConstructors = false; + Policy.SuppressDefaultTemplateArgs = false; + Policy.AlwaysIncludeTypeForTemplateArgument = true; + if (auto* ND = llvm::dyn_cast_or_null(D)) { if (auto* TD = llvm::dyn_cast(ND)) { std::string type_name; QualType QT = C.getTagDeclType(TD); - PrintingPolicy Policy = C.getPrintingPolicy(); - Policy.SuppressUnwrittenScope = true; - Policy.SuppressScope = true; - Policy.AnonymousTagLocations = false; QT.getAsStringInternal(type_name, Policy); - return type_name; } + if (auto* FD = llvm::dyn_cast(ND)) { + std::string func_name; + llvm::raw_string_ostream name_stream(func_name); + FD->getNameForDiagnostic(name_stream, Policy, false); + name_stream.flush(); + return func_name; + } return ND->getNameAsString(); } @@ -3635,7 +3645,11 @@ std::string GetFunctionArgDefault(TCppFunction_t func, if (PI->hasDefaultArg()) { std::string Result; llvm::raw_string_ostream OS(Result); - Expr* DefaultArgExpr = const_cast(PI->getDefaultArg()); + Expr* DefaultArgExpr = nullptr; + if (PI->hasUninstantiatedDefaultArg()) + DefaultArgExpr = PI->getUninstantiatedDefaultArg(); + else + DefaultArgExpr = PI->getDefaultArg(); DefaultArgExpr->printPretty(OS, nullptr, PrintingPolicy(LangOptions())); // FIXME: Floats are printed in clang with the precision of their underlying diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index 983ef8e95..ac050f59b 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -2078,6 +2078,15 @@ TEST(FunctionReflectionTest, GetFunctionArgDefault) { template void get_size(long k, A, char ch = 'a', double l = 0.0) {} + template + struct Other {}; + + template > + struct MyStruct { + T t; + S s; + void fn(T t, S s = S()) {} + }; )"; GetAllTopLevelDecls(code, Decls); @@ -2102,6 +2111,20 @@ TEST(FunctionReflectionTest, GetFunctionArgDefault) { EXPECT_EQ(Cpp::GetFunctionArgDefault(Decls[4], 1), ""); EXPECT_EQ(Cpp::GetFunctionArgDefault(Decls[4], 2), "\'a\'"); EXPECT_EQ(Cpp::GetFunctionArgDefault(Decls[4], 3), "0."); + + ASTContext& C = Interp->getCI()->getASTContext(); + Cpp::TemplateArgInfo template_args[1] = {C.IntTy.getAsOpaquePtr()}; + Cpp::TCppScope_t my_struct = + Cpp::InstantiateTemplate(Decls[6], template_args, 1); + EXPECT_TRUE(my_struct); + + std::vector fns = + Cpp::GetFunctionsUsingName(my_struct, "fn"); + EXPECT_EQ(fns.size(), 1); + + Cpp::TCppScope_t fn = fns[0]; + EXPECT_EQ(Cpp::GetFunctionArgDefault(fn, 0), ""); + EXPECT_EQ(Cpp::GetFunctionArgDefault(fn, 1), "S()"); } TEST(FunctionReflectionTest, Construct) { diff --git a/unittests/CppInterOp/ScopeReflectionTest.cpp b/unittests/CppInterOp/ScopeReflectionTest.cpp index 7fd68c038..0f1942b87 100644 --- a/unittests/CppInterOp/ScopeReflectionTest.cpp +++ b/unittests/CppInterOp/ScopeReflectionTest.cpp @@ -334,6 +334,9 @@ TEST(ScopeReflectionTest, GetCompleteName) { A a; enum { enum1 }; + + template + void fn(T1 t1, T2 t2) {} )"; GetAllTopLevelDecls(code, Decls); @@ -350,7 +353,15 @@ TEST(ScopeReflectionTest, GetCompleteName) { Cpp::GetVariableType( Decls[9]))), "A"); EXPECT_EQ(Cpp::GetCompleteName(Decls[10]), "(unnamed)"); + EXPECT_EQ(Cpp::GetCompleteName(Decls[11]), "fn"); EXPECT_EQ(Cpp::GetCompleteName(nullptr), ""); + + ASTContext& C = Interp->getCI()->getASTContext(); + Cpp::TemplateArgInfo template_args[2] = {C.IntTy.getAsOpaquePtr(), + C.DoubleTy.getAsOpaquePtr()}; + Cpp::TCppScope_t fn = Cpp::InstantiateTemplate(Decls[11], template_args, 2); + EXPECT_TRUE(fn); + EXPECT_EQ(Cpp::GetCompleteName(fn), "fn"); } TEST(ScopeReflectionTest, GetQualifiedName) {