Commit 850c0c7c authored by ussrhero's avatar ussrhero

support template struct with clang parser

parent b92e0fbc
......@@ -642,19 +642,65 @@ public:
CXXRecordDecl * definition = Declaration->getDefinition();
if ( definition && definition->isInvalidDecl() )
return true;
if (definition)
{
if (definition->isInvalidDecl())
return true;
std::string name = Declaration->getQualifiedNameAsString();
auto templateDecl = definition->getDescribedClassTemplate();
if (templateDecl)
{
for (auto specIt = templateDecl->spec_begin(); specIt != templateDecl->spec_end(); specIt++)
{
auto structSpec = *specIt;
std::stringstream fullNameBuilder;
fullNameBuilder << structSpec->getQualifiedNameAsString() << "<";
auto const& structSpecArgList = structSpec->getTemplateArgs();
for (auto i = 0; i < structSpecArgList.size(); ++i)
{
if (i != 0)
fullNameBuilder << ",";
switch (structSpecArgList[i].getKind())
{
case clang::TemplateArgument::ArgKind::Integral:
fullNameBuilder << structSpecArgList[i].getAsIntegral().toString(10);
break;
TypeInfoPtr typeInfo;
case clang::TemplateArgument::ArgKind::Type:
fullNameBuilder << structSpecArgList[i].getAsType().getAsString();
break;
if ( definition )
typeInfo = TypeInfoPtr( new TypeInfoClangStruct( strToWStr(name), m_session, definition ) );
default:
throw TypeException(L"unsupported template argument type");
}
}
fullNameBuilder << ">";
auto rr = llvm::dyn_cast<CXXRecordDecl>(structSpec);
auto typeInfo = TypeInfoPtr(new TypeInfoClangStruct(strToWStr(fullNameBuilder.str()), m_session, rr));
(*m_typeMap)[fullNameBuilder.str()] = typeInfo;
}
}
else
{
std::string name = Declaration->getQualifiedNameAsString();
(*m_typeMap)[name] = TypeInfoPtr(new TypeInfoClangStruct(strToWStr(name), m_session, definition));
}
}
else
typeInfo = TypeInfoPtr( new TypeInfoClangStructNoDef( strToWStr(name), m_session, Declaration ) );
(*m_typeMap)[name] = typeInfo;
{
std::string name = Declaration->getQualifiedNameAsString();
(*m_typeMap)[name] = TypeInfoPtr(new TypeInfoClangStructNoDef(strToWStr(name), m_session, Declaration));
}
} catch(TypeException& )
{}
......
......@@ -430,3 +430,42 @@ TEST_F(ClangTest, TemplateFunc)
EXPECT_THROW( compileType(template_func_src3, L"Generic::intMethod"), TypeException );
EXPECT_THROW( compileType(template_func_src3, L"Generic::tMethod"), TypeException );
}
TEST_F(ClangTest, TemplateStruct)
{
static const wchar_t srcCode[] = L"\
template<typename T1, typename T2> \
struct TestStruct { \
T1 field1; \
T2 field2; \
}; \
TestStruct<int,float> var1; \
TestStruct<char, unsigned long> var2; \
";
TypeInfoProviderPtr typeProvider;
ASSERT_NO_THROW(typeProvider = getTypeInfoProviderFromSource(srcCode));
EXPECT_EQ(L"Int4B", typeProvider->getTypeByName(L"TestStruct<int,float>")->getElement(0)->getName());
EXPECT_EQ(L"UInt4B", typeProvider->getTypeByName(L"TestStruct<char,unsigned long>")->getElement(1)->getName());
EXPECT_THROW(typeProvider->getTypeByName(L"TestStruct"), TypeException);
EXPECT_THROW(typeProvider->getTypeByName(L"TestStruct<float>"), TypeException);
}
TEST_F(ClangTest, TemplateValueStruct)
{
static const wchar_t srcCode[] = L"\
template<int v1, long v2> \
struct TestStruct { \
int field1; \
}; \
TestStruct<2,-3> var1; \
";
TypeInfoProviderPtr typeProvider;
ASSERT_NO_THROW(typeProvider = getTypeInfoProviderFromSource(srcCode));
EXPECT_NO_THROW(typeProvider->getTypeByName(L"TestStruct<2,-3>"));
EXPECT_THROW(typeProvider->getTypeByName(L"TestStruct<2,3>"), TypeException);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment