From 31360f56d2ca82b4f150750ad1463462d35773fa Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Thu, 3 Apr 2025 17:00:13 +0200 Subject: [PATCH 1/2] Add tests for variadic function instantiations --- .../CppInterOp/FunctionReflectionTest.cpp | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index ea8b4180d..3f1ddb27f 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -6,6 +6,8 @@ #include "clang/Interpreter/CppInterOp.h" #include "clang/Sema/Sema.h" +#include + #include "clang-c/CXCppInterOp.h" #include "gtest/gtest.h" @@ -846,6 +848,69 @@ TEST(FunctionReflectionTest, GetClassTemplatedMethods_VariadicsAndOthers) { "void MyClass::staticVariadic(T t, Args ...args)"); } +TEST(FunctionReflectionTest, InstantiateVariadicFunction) { + std::vector Decls; + std::string code = R"( + class MyClass {}; + + template + void VariadicFn(Args... args) {} + + template + void VariadicFnExtended(int fixedParam, Args... args) {} + )"; + + GetAllTopLevelDecls(code, Decls); + ASTContext& C = Interp->getCI()->getASTContext(); + + std::vector args1 = {C.DoubleTy.getAsOpaquePtr(), + C.IntTy.getAsOpaquePtr()}; + auto Instance1 = Cpp::InstantiateTemplate(Decls[1], args1.data(), + /*type_size*/ args1.size()); + EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance1)); + EXPECT_EQ(Cpp::GetFunctionSignature(Instance1), + "template<> void VariadicFn<>(double args, int args)"); + + FunctionDecl* FD = cast((Decl*)Instance1); + FunctionDecl* FnTD1 = FD->getTemplateInstantiationPattern(); + EXPECT_TRUE(FnTD1->isThisDeclarationADefinition()); + EXPECT_EQ(FD->getNumParams(), 2); + + const TemplateArgumentList* TA1 = FD->getTemplateSpecializationArgs(); + llvm::ArrayRef Args = TA1->get(0).getPackAsArray(); + EXPECT_EQ(Args.size(), 2); + EXPECT_TRUE(Args[0].getAsType()->isFloatingType()); + EXPECT_TRUE(Args[1].getAsType()->isIntegerType()); + + // handle to MyClass type + auto MyClassType = Cpp::GetTypeFromScope(Decls[0]); + std::vector args2 = {MyClassType, + C.DoubleTy.getAsOpaquePtr()}; + + // instantiate VariadicFnExtended + auto Instance2 = + Cpp::InstantiateTemplate(Decls[2], args2.data(), args2.size()); + EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance2)); + + FunctionDecl* FD2 = cast((Decl*)Instance2); + FunctionDecl* FnTD2 = FD2->getTemplateInstantiationPattern(); + EXPECT_TRUE(FnTD2->isThisDeclarationADefinition()); + + // VariadicFnExtended has one fixed param + 2 elements in TemplateArgument + // pack + EXPECT_EQ(FD2->getNumParams(), 3); + + const TemplateArgumentList* TA2 = FD2->getTemplateSpecializationArgs(); + llvm::ArrayRef PackArgs2 = TA2->get(0).getPackAsArray(); + EXPECT_EQ(PackArgs2.size(), 2); + + EXPECT_TRUE(PackArgs2[0].getAsType()->isRecordType()); // MyClass + EXPECT_TRUE(PackArgs2[1].getAsType()->isFloatingType()); // double + EXPECT_EQ(Cpp::GetFunctionSignature(Instance2), + "template<> void VariadicFnExtended<>(int " + "fixedParam, MyClass args, double args)"); +} + TEST(FunctionReflectionTest, BestOverloadFunctionMatch1) { std::vector Decls; std::string code = R"( From 599860622c2750204df97f19675da6c7b48eb30f Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Tue, 22 Apr 2025 11:27:10 +0200 Subject: [PATCH 2/2] export missing symbols for wasm --- lib/Interpreter/exports.ld | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Interpreter/exports.ld b/lib/Interpreter/exports.ld index 1f7301dd4..49b7b0d83 100644 --- a/lib/Interpreter/exports.ld +++ b/lib/Interpreter/exports.ld @@ -47,5 +47,7 @@ -Wl,--export=_ZNK5clang11DeclContext6lookupENS_15DeclarationNameE -Wl,--export=_ZNK5clang17ClassTemplateDecl18getSpecializationsEv -Wl,--export=_ZNK5clang4Sema15getStdNamespaceEv +-Wl,--export=_ZNK5clang4Type14isFloatingTypeEv +-Wl,--export=_ZNK5clang12FunctionDecl12getNumParamsEv -Wl,--export=__clang_Interpreter_SetValueNoAlloc -Wl,--export=__clang_Interpreter_SetValueWithAlloc \ No newline at end of file