logic: fixed potential crash when solving decls in lambda captures
* fixed potential crash when solving decls in lambda captures * fixed solving type of anonymous structs/classes in c code * added null checks in name resolvers
This commit is contained in:
@@ -312,13 +312,13 @@ bool CxxAstVisitor::TraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc
|
||||
|
||||
bool CxxAstVisitor::TraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture)
|
||||
{
|
||||
clang::VarDecl* d = capture->getCapturedVar();
|
||||
if (lambdaExpr->isInitCapture(capture))
|
||||
{
|
||||
TraverseDecl(d);
|
||||
TraverseDecl(capture->getCapturedVar());
|
||||
}
|
||||
else
|
||||
else if (capture->capturesVariable())
|
||||
{
|
||||
clang::VarDecl* d = capture->getCapturedVar();
|
||||
SymbolKind symbolKind = getSymbolKind(d);
|
||||
if (symbolKind == SYMBOL_LOCAL_VARIABLE || symbolKind == SYMBOL_PARAMETER)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,12 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl
|
||||
}
|
||||
}
|
||||
|
||||
if ((clang::isa<clang::CXXRecordDecl>(declaration)) &&
|
||||
(clang::dyn_cast<clang::CXXRecordDecl>(declaration)->isLambda()))
|
||||
{
|
||||
declaration = clang::dyn_cast<clang::CXXRecordDecl>(declaration)->getLambdaCallOperator();
|
||||
}
|
||||
|
||||
std::shared_ptr<CxxDeclName> declName;
|
||||
if (declaration)
|
||||
{
|
||||
@@ -94,60 +100,9 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
return getDeclName(templatedDeclaration);
|
||||
}
|
||||
}
|
||||
if (const clang::CXXRecordDecl* recordDecl = clang::dyn_cast_or_null<clang::CXXRecordDecl>(declaration))
|
||||
if (const clang::RecordDecl* recordDecl = clang::dyn_cast_or_null<clang::RecordDecl>(declaration))
|
||||
{
|
||||
clang::ClassTemplateDecl* templateClassDeclaration = recordDecl->getDescribedClassTemplate();
|
||||
if (templateClassDeclaration)
|
||||
{
|
||||
return getDeclName(templateClassDeclaration);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(declaration))
|
||||
{
|
||||
const clang::ClassTemplatePartialSpecializationDecl* partialSpecializationDecl =
|
||||
clang::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(declaration);
|
||||
|
||||
clang::TemplateParameterList* parameterList = partialSpecializationDecl->getTemplateParameters();
|
||||
unsigned int currentParameterIndex = 0;
|
||||
|
||||
std::vector<std::string> templateParameters;
|
||||
const clang::TemplateArgumentList& templateArgumentList = partialSpecializationDecl->getTemplateArgs();
|
||||
const int templateArgumentCount = templateArgumentList.size();
|
||||
for (int i = 0; i < templateArgumentCount; i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList.get(i);
|
||||
if (templateArgument.isDependent()) // IMPORTANT_TODO: fix case when arg depends on template parameter of outer template class, or depends on first template parameter.
|
||||
{
|
||||
if(currentParameterIndex < parameterList->size())
|
||||
{
|
||||
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(currentParameterIndex)));
|
||||
}
|
||||
else
|
||||
{
|
||||
//this if fixes the crash, but not the problem TODO
|
||||
// const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
// LOG_ERROR("Template getParam out of Range " + declaration->getLocation().printToString(sourceManager));
|
||||
}
|
||||
currentParameterIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
templateParameters.push_back(getTemplateArgumentName(templateArgument));
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
|
||||
{
|
||||
std::vector<std::string> templateArguments;
|
||||
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
|
||||
for (size_t i = 0; i < templateArgumentList.size(); i++)
|
||||
{
|
||||
templateArguments.push_back(getTemplateArgumentName(templateArgumentList.get(i)));
|
||||
}
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateArguments);
|
||||
}
|
||||
else if (recordDecl->isLambda())
|
||||
if (recordDecl->isLambda())
|
||||
{
|
||||
// we skip this node because its child (the lambda call operator) has already been recorded.
|
||||
return std::shared_ptr<CxxDeclName>();
|
||||
@@ -159,6 +114,60 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
const std::string symbolKindName = (recordDecl->isStruct() ? "struct" : "class");
|
||||
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(symbolKindName, presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
else if (const clang::CXXRecordDecl* cxxRecordDecl = clang::dyn_cast_or_null<clang::CXXRecordDecl>(declaration))
|
||||
{
|
||||
clang::ClassTemplateDecl* templateClassDeclaration = cxxRecordDecl->getDescribedClassTemplate();
|
||||
if (templateClassDeclaration)
|
||||
{
|
||||
return getDeclName(templateClassDeclaration);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(declaration))
|
||||
{
|
||||
const clang::ClassTemplatePartialSpecializationDecl* partialSpecializationDecl =
|
||||
clang::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(declaration);
|
||||
|
||||
clang::TemplateParameterList* parameterList = partialSpecializationDecl->getTemplateParameters();
|
||||
unsigned int currentParameterIndex = 0;
|
||||
|
||||
std::vector<std::string> templateParameters;
|
||||
const clang::TemplateArgumentList& templateArgumentList = partialSpecializationDecl->getTemplateArgs();
|
||||
const int templateArgumentCount = templateArgumentList.size();
|
||||
for (int i = 0; i < templateArgumentCount; i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList.get(i);
|
||||
if (templateArgument.isDependent()) // IMPORTANT_TODO: fix case when arg depends on template parameter of outer template class, or depends on first template parameter.
|
||||
{
|
||||
if(currentParameterIndex < parameterList->size())
|
||||
{
|
||||
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(currentParameterIndex)));
|
||||
}
|
||||
else
|
||||
{
|
||||
//this if fixes the crash, but not the problem TODO
|
||||
// const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
// LOG_ERROR("Template getParam out of Range " + declaration->getLocation().printToString(sourceManager));
|
||||
}
|
||||
currentParameterIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
templateParameters.push_back(getTemplateArgumentName(templateArgument));
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
|
||||
{
|
||||
std::vector<std::string> templateArguments;
|
||||
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
|
||||
for (size_t i = 0; i < templateArgumentList.size(); i++)
|
||||
{
|
||||
templateArguments.push_back(getTemplateArgumentName(templateArgumentList.get(i)));
|
||||
}
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
{
|
||||
@@ -167,7 +176,6 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
std::string functionName = declNameString;
|
||||
std::vector<std::string> templateArguments;
|
||||
|
||||
|
||||
if ((clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)) &&
|
||||
(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->isLambda()))
|
||||
{
|
||||
@@ -325,14 +333,23 @@ std::string CxxDeclNameResolver::getTemplateParameterTypeString(const clang::Non
|
||||
{
|
||||
typeNameResolver.ignoreContextDecl(m_currentDecl);
|
||||
}
|
||||
|
||||
std::string typeString = "";
|
||||
|
||||
std::string typeString = typeNameResolver.getName(parameter->getType())->toString();
|
||||
std::shared_ptr<CxxTypeName> typeName = typeNameResolver.getName(parameter->getType());
|
||||
if (typeName)
|
||||
{
|
||||
typeString = typeName->toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("unable to solve type of non-type template parameter declaration");
|
||||
}
|
||||
|
||||
if (parameter->isTemplateParameterPack())
|
||||
{
|
||||
typeString += "...";
|
||||
}
|
||||
|
||||
return typeString;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,16 @@ std::string CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clang
|
||||
case clang::TemplateArgument::Type:
|
||||
{
|
||||
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
|
||||
return typeNameResolver.getName(argument.getAsType())->toString();
|
||||
std::shared_ptr<CxxTypeName> typeName = typeNameResolver.getName(argument.getAsType());
|
||||
if (typeName)
|
||||
{
|
||||
return typeName->toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("Unable to solve name for template type argument");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::TemplateArgument::Integral:
|
||||
case clang::TemplateArgument::Null:
|
||||
|
||||
@@ -26,7 +26,7 @@ CxxTypeNameResolver::~CxxTypeNameResolver()
|
||||
std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::QualType& qualType)
|
||||
{
|
||||
std::shared_ptr<CxxTypeName> typeName = getName(qualType.getTypePtr());
|
||||
if (qualType.isConstQualified())
|
||||
if (typeName && qualType.isConstQualified())
|
||||
{
|
||||
typeName->addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
|
||||
}
|
||||
@@ -48,12 +48,14 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TypedefType>()->getDecl());
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::MemberPointer:
|
||||
@@ -92,12 +94,14 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TagType>()->getDecl());
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::Builtin:
|
||||
@@ -118,12 +122,14 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(tagType->getDecl());
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
}
|
||||
else // specialization of a template template parameter (no concrete class) important, may help: has no underlying decl!
|
||||
{
|
||||
@@ -141,7 +147,9 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
|
||||
}
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(), templateArguments, declName->getParent()
|
||||
declName->getName(),
|
||||
templateArguments,
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
else
|
||||
@@ -155,12 +163,14 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl());
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::SubstTemplateTypeParm:
|
||||
|
||||
Reference in New Issue
Block a user