Skip to content

Commit 0930a89

Browse files
committed
Add tests for variadic function instantiations
1 parent da58066 commit 0930a89

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "clang/Interpreter/CppInterOp.h"
77
#include "clang/Sema/Sema.h"
88

9+
#include <llvm/ADT/ArrayRef.h>
10+
911
#include "clang-c/CXCppInterOp.h"
1012

1113
#include "gtest/gtest.h"
@@ -847,6 +849,69 @@ TEST(FunctionReflectionTest, GetClassTemplatedMethods_VariadicsAndOthers) {
847849
"void MyClass::staticVariadic(T t, Args ...args)");
848850
}
849851

852+
TEST(FunctionReflectionTest, InstantiateVariadicFunction) {
853+
std::vector<Decl*> Decls;
854+
std::string code = R"(
855+
class MyClass {};
856+
857+
template<typename... Args>
858+
void VariadicFn(Args... args) {}
859+
860+
template<typename... Args>
861+
void VariadicFnExtended(int fixedParam, Args... args) {}
862+
)";
863+
864+
GetAllTopLevelDecls(code, Decls);
865+
ASTContext& C = Interp->getCI()->getASTContext();
866+
867+
std::vector<Cpp::TemplateArgInfo> args1 = {C.DoubleTy.getAsOpaquePtr(),
868+
C.IntTy.getAsOpaquePtr()};
869+
auto Instance1 = Cpp::InstantiateTemplate(Decls[1], args1.data(),
870+
/*type_size*/ args1.size());
871+
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance1));
872+
EXPECT_EQ(Cpp::GetFunctionSignature(Instance1),
873+
"template<> void VariadicFn<<double, int>>(double args, int args)");
874+
875+
FunctionDecl* FD = cast<FunctionDecl>((Decl*)Instance1);
876+
FunctionDecl* FnTD1 = FD->getTemplateInstantiationPattern();
877+
EXPECT_TRUE(FnTD1->isThisDeclarationADefinition());
878+
EXPECT_EQ(FD->getNumParams(), 2);
879+
880+
const TemplateArgumentList* TA1 = FD->getTemplateSpecializationArgs();
881+
llvm::ArrayRef<TemplateArgument> Args = TA1->get(0).getPackAsArray();
882+
EXPECT_EQ(Args.size(), 2);
883+
EXPECT_TRUE(Args[0].getAsType()->isFloatingType());
884+
EXPECT_TRUE(Args[1].getAsType()->isIntegerType());
885+
886+
// handle to MyClass type
887+
auto MyClassType = Cpp::GetTypeFromScope(Decls[0]);
888+
std::vector<Cpp::TemplateArgInfo> args2 = {MyClassType,
889+
C.DoubleTy.getAsOpaquePtr()};
890+
891+
// instantiate VariadicFnExtended
892+
auto Instance2 =
893+
Cpp::InstantiateTemplate(Decls[2], args2.data(), args2.size());
894+
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance2));
895+
896+
FunctionDecl* FD2 = cast<FunctionDecl>((Decl*)Instance2);
897+
FunctionDecl* FnTD2 = FD2->getTemplateInstantiationPattern();
898+
EXPECT_TRUE(FnTD2->isThisDeclarationADefinition());
899+
900+
// VariadicFnExtended has one fixed param + 2 elements in TemplateArgument
901+
// pack
902+
EXPECT_EQ(FD2->getNumParams(), 3);
903+
904+
const TemplateArgumentList* TA2 = FD2->getTemplateSpecializationArgs();
905+
llvm::ArrayRef<TemplateArgument> PackArgs2 = TA2->get(0).getPackAsArray();
906+
EXPECT_EQ(PackArgs2.size(), 2);
907+
908+
EXPECT_TRUE(PackArgs2[0].getAsType()->isRecordType()); // MyClass
909+
EXPECT_TRUE(PackArgs2[1].getAsType()->isFloatingType()); // double
910+
EXPECT_EQ(Cpp::GetFunctionSignature(Instance2),
911+
"template<> void VariadicFnExtended<<MyClass, double>>(int "
912+
"fixedParam, MyClass args, double args)");
913+
}
914+
850915
TEST(FunctionReflectionTest, BestOverloadFunctionMatch1) {
851916
std::vector<Decl*> Decls;
852917
std::string code = R"(

0 commit comments

Comments
 (0)