Skip to content

Commit f65f80a

Browse files
Fix bugs related to printing types (#661)
* fix GetCompleteName to include template parameters * fix GetFunctionArgDefault to handle uninstantiated args
1 parent 59a5e99 commit f65f80a

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -517,18 +517,28 @@ std::string GetCompleteName(TCppType_t klass) {
517517
auto& C = getSema().getASTContext();
518518
auto* D = (Decl*)klass;
519519

520+
PrintingPolicy Policy = C.getPrintingPolicy();
521+
Policy.SuppressUnwrittenScope = true;
522+
Policy.SuppressScope = true;
523+
Policy.AnonymousTagLocations = false;
524+
Policy.SuppressTemplateArgsInCXXConstructors = false;
525+
Policy.SuppressDefaultTemplateArgs = false;
526+
Policy.AlwaysIncludeTypeForTemplateArgument = true;
527+
520528
if (auto* ND = llvm::dyn_cast_or_null<NamedDecl>(D)) {
521529
if (auto* TD = llvm::dyn_cast<TagDecl>(ND)) {
522530
std::string type_name;
523531
QualType QT = C.getTagDeclType(TD);
524-
PrintingPolicy Policy = C.getPrintingPolicy();
525-
Policy.SuppressUnwrittenScope = true;
526-
Policy.SuppressScope = true;
527-
Policy.AnonymousTagLocations = false;
528532
QT.getAsStringInternal(type_name, Policy);
529-
530533
return type_name;
531534
}
535+
if (auto* FD = llvm::dyn_cast<FunctionDecl>(ND)) {
536+
std::string func_name;
537+
llvm::raw_string_ostream name_stream(func_name);
538+
FD->getNameForDiagnostic(name_stream, Policy, false);
539+
name_stream.flush();
540+
return func_name;
541+
}
532542

533543
return ND->getNameAsString();
534544
}
@@ -3635,7 +3645,11 @@ std::string GetFunctionArgDefault(TCppFunction_t func,
36353645
if (PI->hasDefaultArg()) {
36363646
std::string Result;
36373647
llvm::raw_string_ostream OS(Result);
3638-
Expr* DefaultArgExpr = const_cast<Expr*>(PI->getDefaultArg());
3648+
Expr* DefaultArgExpr = nullptr;
3649+
if (PI->hasUninstantiatedDefaultArg())
3650+
DefaultArgExpr = PI->getUninstantiatedDefaultArg();
3651+
else
3652+
DefaultArgExpr = PI->getDefaultArg();
36393653
DefaultArgExpr->printPretty(OS, nullptr, PrintingPolicy(LangOptions()));
36403654

36413655
// FIXME: Floats are printed in clang with the precision of their underlying

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,15 @@ TEST(FunctionReflectionTest, GetFunctionArgDefault) {
20782078
template<class A>
20792079
void get_size(long k, A, char ch = 'a', double l = 0.0) {}
20802080
2081+
template<typename T>
2082+
struct Other {};
2083+
2084+
template <typename T, typename S = Other<T>>
2085+
struct MyStruct {
2086+
T t;
2087+
S s;
2088+
void fn(T t, S s = S()) {}
2089+
};
20812090
)";
20822091

20832092
GetAllTopLevelDecls(code, Decls);
@@ -2102,6 +2111,20 @@ TEST(FunctionReflectionTest, GetFunctionArgDefault) {
21022111
EXPECT_EQ(Cpp::GetFunctionArgDefault(Decls[4], 1), "");
21032112
EXPECT_EQ(Cpp::GetFunctionArgDefault(Decls[4], 2), "\'a\'");
21042113
EXPECT_EQ(Cpp::GetFunctionArgDefault(Decls[4], 3), "0.");
2114+
2115+
ASTContext& C = Interp->getCI()->getASTContext();
2116+
Cpp::TemplateArgInfo template_args[1] = {C.IntTy.getAsOpaquePtr()};
2117+
Cpp::TCppScope_t my_struct =
2118+
Cpp::InstantiateTemplate(Decls[6], template_args, 1);
2119+
EXPECT_TRUE(my_struct);
2120+
2121+
std::vector<Cpp::TCppFunction_t> fns =
2122+
Cpp::GetFunctionsUsingName(my_struct, "fn");
2123+
EXPECT_EQ(fns.size(), 1);
2124+
2125+
Cpp::TCppScope_t fn = fns[0];
2126+
EXPECT_EQ(Cpp::GetFunctionArgDefault(fn, 0), "");
2127+
EXPECT_EQ(Cpp::GetFunctionArgDefault(fn, 1), "S()");
21052128
}
21062129

21072130
TEST(FunctionReflectionTest, Construct) {

unittests/CppInterOp/ScopeReflectionTest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ TEST(ScopeReflectionTest, GetCompleteName) {
334334
A<int> a;
335335
336336
enum { enum1 };
337+
338+
template<typename T1, typename T2>
339+
void fn(T1 t1, T2 t2) {}
337340
)";
338341
GetAllTopLevelDecls(code, Decls);
339342

@@ -350,7 +353,15 @@ TEST(ScopeReflectionTest, GetCompleteName) {
350353
Cpp::GetVariableType(
351354
Decls[9]))), "A<int>");
352355
EXPECT_EQ(Cpp::GetCompleteName(Decls[10]), "(unnamed)");
356+
EXPECT_EQ(Cpp::GetCompleteName(Decls[11]), "fn");
353357
EXPECT_EQ(Cpp::GetCompleteName(nullptr), "<unnamed>");
358+
359+
ASTContext& C = Interp->getCI()->getASTContext();
360+
Cpp::TemplateArgInfo template_args[2] = {C.IntTy.getAsOpaquePtr(),
361+
C.DoubleTy.getAsOpaquePtr()};
362+
Cpp::TCppScope_t fn = Cpp::InstantiateTemplate(Decls[11], template_args, 2);
363+
EXPECT_TRUE(fn);
364+
EXPECT_EQ(Cpp::GetCompleteName(fn), "fn<int, double>");
354365
}
355366

356367
TEST(ScopeReflectionTest, GetQualifiedName) {

0 commit comments

Comments
 (0)