From 0649644663c64294785b69588ff0288bb8ae8ff0 Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Thu, 5 Feb 2015 12:08:57 +0100 Subject: [PATCH] data: fixed template specialization parse crash handled conversion to DataType of clang::TemplateArgument when it is of integral kind. --- src/lib/data/parser/cxx/ASTVisitor.cpp | 2 +- src/lib/data/parser/cxx/utilityCxx.cpp | 42 +++++++++++++++++++++++--- src/lib/data/parser/cxx/utilityCxx.h | 1 + 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 8d01ac3a..0eba276d 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -320,7 +320,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration) const clang::TemplateArgumentList &argList = specializationDecl->getTemplateArgs(); for (int i = 0; i < argList.size(); i++) { - std::vector argumentNameHierarchy = utility::qualTypeToDataType(argList.get(i).getAsType()).getTypeNameHierarchy(); + std::vector argumentNameHierarchy = utility::templateArgumentToDataType(argList.get(i)).getTypeNameHierarchy(); m_client->onTemplateRecordArgumentTypeParsed(ParseLocation(), argumentNameHierarchy, specializedRecordNameHierarchy); // TODO: What about the ParseLocation } } diff --git a/src/lib/data/parser/cxx/utilityCxx.cpp b/src/lib/data/parser/cxx/utilityCxx.cpp index e07b6f35..08e2887e 100644 --- a/src/lib/data/parser/cxx/utilityCxx.cpp +++ b/src/lib/data/parser/cxx/utilityCxx.cpp @@ -167,12 +167,28 @@ namespace utility } else if (clang::isa(declaration)) { - int templateArgumentCount = clang::dyn_cast(declaration)->getTemplateArgs().size(); - const clang::ASTTemplateArgumentListInfo* templateArgumentListInfo = clang::dyn_cast(declaration)->getTemplateArgsAsWritten(); + const clang::ClassTemplatePartialSpecializationDecl* partialSpecializationDecl = + clang::dyn_cast(declaration); + + int templateArgumentCount = partialSpecializationDecl->getTemplateArgs().size(); + const clang::ASTTemplateArgumentListInfo* templateArgumentListInfo = partialSpecializationDecl->getTemplateArgsAsWritten(); std::string specializedParameterNamePart = "<"; for (int i = 0; i < templateArgumentCount; i++) { - specializedParameterNamePart += templateArgumentListInfo->getTemplateArgs()[i].getArgument().getAsType().getAsString(); + const clang::TemplateArgument& templateArgument = templateArgumentListInfo->getTemplateArgs()[i].getArgument(); + const clang::TemplateArgument::ArgKind kind = templateArgument.getKind(); + switch (kind) + { + case clang::TemplateArgument::Type: + specializedParameterNamePart += templateArgument.getAsType().getAsString(); + break; + case clang::TemplateArgument::Integral: + specializedParameterNamePart += templateArgument.getIntegralType().getAsString(); + break; + default: + LOG_ERROR("Type of template argument not handled."); + break; + } specializedParameterNamePart += (i < templateArgumentCount - 1) ? ", " : ""; } specializedParameterNamePart += ">"; @@ -184,8 +200,8 @@ namespace utility const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast(declaration)->getTemplateArgs(); for (size_t i = 0; i < templateArgumentList.size(); i++) { - DataType datatype = utility::qualTypeToDataType(templateArgumentList.get(i).getAsType()); - specializedParameterNamePart += datatype.getFullTypeName(); + const clang::TemplateArgument& templateArgument = templateArgumentList.get(i); + specializedParameterNamePart += templateArgumentToDataType(templateArgument).getFullTypeName(); specializedParameterNamePart += (i < templateArgumentList.size() - 1) ? ", " : ""; } specializedParameterNamePart += ">"; @@ -229,4 +245,20 @@ namespace utility } return specializationParentNameHierarchy; } + + DataType templateArgumentToDataType(const clang::TemplateArgument& argument) + { + const clang::TemplateArgument::ArgKind kind = argument.getKind(); + switch (kind) + { + case clang::TemplateArgument::Type: + return utility::qualTypeToDataType(argument.getAsType()); + case clang::TemplateArgument::Integral: + return utility::qualTypeToDataType(argument.getIntegralType()); + default: + LOG_ERROR("Type of template argument not handled."); + break; + } + return DataType(std::vector()); + } } diff --git a/src/lib/data/parser/cxx/utilityCxx.h b/src/lib/data/parser/cxx/utilityCxx.h index c1149d53..07d0af7a 100644 --- a/src/lib/data/parser/cxx/utilityCxx.h +++ b/src/lib/data/parser/cxx/utilityCxx.h @@ -19,6 +19,7 @@ namespace utility std::vector getContextNameHierarchy(clang::DeclContext* declaration); std::string getDeclName(clang::NamedDecl* declaration); std::vector getTemplateSpecializationParentNameHierarchy(clang::ClassTemplateSpecializationDecl* declaration); + DataType templateArgumentToDataType(const clang::TemplateArgument& argument); } #endif // UTILITY_CLANG_H