data: lambda handling
* implemented handling lambdas as functions * functions can have child nodes now * NameElements in NameHierarchy can have signatures now. * fixed crash that occurred when message listener was used while being half way through its destruction process.
This commit is contained in:
@@ -38,30 +38,13 @@ void ASTBodyVisitor::VisitChildren(clang::Stmt* stmt)
|
||||
|
||||
void ASTBodyVisitor::VisitCallExpr(clang::CallExpr* expr)
|
||||
{
|
||||
bool ignore = false;
|
||||
|
||||
// check if lambda call
|
||||
if (clang::isa<clang::CXXOperatorCallExpr>(expr))
|
||||
if (m_functionDecl)
|
||||
{
|
||||
clang::Decl* calleeDecl = expr->getCalleeDecl();
|
||||
|
||||
if (calleeDecl && clang::isa<clang::CXXMethodDecl>(calleeDecl))
|
||||
{
|
||||
clang::CXXRecordDecl* recordDecl = clang::dyn_cast<clang::CXXMethodDecl>(calleeDecl)->getParent();
|
||||
ignore = recordDecl->isLambda();
|
||||
}
|
||||
m_client->VisitCallExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
|
||||
if (!ignore)
|
||||
else
|
||||
{
|
||||
if (m_functionDecl)
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_varDecl, expr);
|
||||
}
|
||||
m_client->VisitCallExprInDeclBody(m_varDecl, expr);
|
||||
}
|
||||
|
||||
VisitStmt(expr);
|
||||
@@ -176,6 +159,11 @@ void ASTBodyVisitor::VisitDeclRefExpr(clang::DeclRefExpr* expr)
|
||||
VisitStmt(expr);
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitLambdaExpr(clang::LambdaExpr* expr)
|
||||
{
|
||||
// Don't visit the lambda's children. The ASTVisitor creates a new ASTBodyVisitor for these.
|
||||
}
|
||||
|
||||
void ASTBodyVisitor::VisitDeclStmt(clang::DeclStmt* stmt)
|
||||
{
|
||||
for (clang::Decl* decl : stmt->decls())
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
void VisitCXXNewExpr(clang::CXXNewExpr* expr);
|
||||
void VisitMemberExpr(clang::make_ptr<clang::MemberExpr>::type expr);
|
||||
void VisitDeclRefExpr(clang::make_ptr<clang::DeclRefExpr>::type expr);
|
||||
void VisitLambdaExpr(clang::LambdaExpr* expr);
|
||||
void VisitDeclStmt(clang::DeclStmt* stmt);
|
||||
|
||||
private:
|
||||
|
||||
@@ -166,6 +166,15 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitLambdaExpr(clang::LambdaExpr* expr)
|
||||
{
|
||||
if (isLocatedInUnparsedProjectFile(expr->getCallOperator()))
|
||||
{
|
||||
processFunctionDecl(expr->getCallOperator());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitParmVarDecl(clang::ParmVarDecl* declaration)
|
||||
{
|
||||
// todo: handle parameters here!
|
||||
@@ -755,7 +764,7 @@ void ASTVisitor::processFunctionDecl(clang::FunctionDecl* declaration)
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
getParseFunction(declaration),
|
||||
getParseLocationOfFunctionBody(declaration)
|
||||
);
|
||||
);
|
||||
|
||||
// handle template arguments of return type.
|
||||
clang::TypeLoc functionLoc = declaration->getTypeSourceInfo()->getTypeLoc();
|
||||
@@ -772,7 +781,7 @@ void ASTVisitor::processFunctionDecl(clang::FunctionDecl* declaration)
|
||||
if (declaration->hasBody() &&
|
||||
declaration->isThisDeclarationADefinition() &&
|
||||
!declaration->isDependentContext()
|
||||
)
|
||||
)
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getBody());
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
virtual bool VisitVarDecl(clang::VarDecl* declaration); // global variables and static fields
|
||||
virtual bool VisitFieldDecl(clang::FieldDecl* declaration); // fields
|
||||
virtual bool VisitFunctionDecl(clang::FunctionDecl* declaration); // functions
|
||||
virtual bool VisitLambdaExpr(clang::LambdaExpr* expr); // lambdas
|
||||
virtual bool VisitParmVarDecl(clang::ParmVarDecl* declaration);
|
||||
virtual bool VisitCXXMethodDecl(clang::CXXMethodDecl* declaration); // methods
|
||||
virtual bool VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration); // initialization list
|
||||
@@ -67,14 +68,12 @@ public:
|
||||
virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl); // type usages
|
||||
|
||||
private:
|
||||
|
||||
void processFunctionDecl(clang::FunctionDecl* declaration);
|
||||
void processTemplateArgumentsOfExplicitSpecialization(clang::FunctionDecl* declaration);
|
||||
void processTemplateArgumentsOfExplicitSpecialization(clang::ClassTemplateSpecializationDecl* specializationDecl);
|
||||
void processTemplateArguments(clang::DeclRefExpr* expr);
|
||||
void processTemplateArguments(clang::TemplateSpecializationTypeLoc loc);
|
||||
|
||||
|
||||
bool isLocatedInUnparsedProjectFile(const clang::Decl* declaration) const;
|
||||
bool isLocatedInProjectFile(const ParseLocation& location) const;
|
||||
bool isLocatedInProjectFile(const clang::Decl* declaration) const;
|
||||
|
||||
@@ -29,7 +29,7 @@ NameHierarchy CxxDeclNameResolver::getDeclNameHierarchy()
|
||||
NameHierarchy contextNameHierarchy;
|
||||
if (m_declaration)
|
||||
{
|
||||
std::string declName = "";
|
||||
std::shared_ptr<NameElement> declName;
|
||||
|
||||
if (clang::isa<clang::NamedDecl>(m_declaration))
|
||||
{
|
||||
@@ -47,13 +47,13 @@ NameHierarchy CxxDeclNameResolver::getDeclNameHierarchy()
|
||||
clang::isa<clang::TemplateTemplateParmDecl>(m_declaration)) &&
|
||||
contextNameHierarchy.size() > 0)
|
||||
{
|
||||
std::string lastContextElementName = contextNameHierarchy.back()->getFullName();
|
||||
std::string lastContextElementName = contextNameHierarchy.back()->getFullName(); // TODO: what about the signature in this case?
|
||||
contextNameHierarchy.pop();
|
||||
contextNameHierarchy.push(std::make_shared<NameElement>(lastContextElementName + "::" + declName));
|
||||
contextNameHierarchy.push(std::make_shared<NameElement>(lastContextElementName + "::" + declName->getFullName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
contextNameHierarchy.push(std::make_shared<NameElement>(declName));
|
||||
contextNameHierarchy.push(declName);
|
||||
}
|
||||
}
|
||||
return contextNameHierarchy;
|
||||
@@ -73,26 +73,26 @@ NameHierarchy CxxDeclNameResolver::getContextNameHierarchy(const clang::DeclCont
|
||||
|
||||
if (clang::isa<clang::NamedDecl>(declContext))
|
||||
{
|
||||
std::string declName = getDeclName(clang::dyn_cast<clang::NamedDecl>(declContext));
|
||||
if (declName != "")
|
||||
std::shared_ptr<NameElement> declName = getDeclName(clang::dyn_cast<clang::NamedDecl>(declContext));
|
||||
if (declName)
|
||||
{
|
||||
contextNameHierarchy.push(std::make_shared<NameElement>(declName));
|
||||
contextNameHierarchy.push(declName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getDeclName()
|
||||
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
|
||||
{
|
||||
const clang::NamedDecl* declaration = clang::dyn_cast<clang::NamedDecl>(m_declaration);
|
||||
std::string declName = declaration->getNameAsString();
|
||||
std::string declNameString = declaration->getNameAsString();
|
||||
if (clang::isa<clang::CXXRecordDecl>(declaration))
|
||||
{
|
||||
clang::ClassTemplateDecl* templateClassDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(declaration)->getDescribedClassTemplate();
|
||||
if (templateClassDeclaration)
|
||||
{
|
||||
declName = getDeclName(templateClassDeclaration);
|
||||
return getDeclName(templateClassDeclaration);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(declaration))
|
||||
{
|
||||
@@ -129,7 +129,7 @@ std::string CxxDeclNameResolver::getDeclName()
|
||||
specializedParameterNamePart += (i < templateArgumentCount - 1) ? ", " : "";
|
||||
}
|
||||
specializedParameterNamePart += ">";
|
||||
declName += specializedParameterNamePart;
|
||||
return std::make_shared<NameElement>(declNameString + specializedParameterNamePart);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
|
||||
{
|
||||
@@ -141,29 +141,78 @@ std::string CxxDeclNameResolver::getDeclName()
|
||||
templateArgumentNamePart += (i < templateArgumentList.size() - 1) ? ", " : "";
|
||||
}
|
||||
templateArgumentNamePart += ">";
|
||||
declName += templateArgumentNamePart;
|
||||
return std::make_shared<NameElement>(declNameString + templateArgumentNamePart);
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
{
|
||||
clang::FunctionTemplateDecl* templateFunctionDeclaration = clang::dyn_cast<clang::FunctionDecl>(declaration)->getDescribedFunctionTemplate();
|
||||
if (templateFunctionDeclaration)
|
||||
if (const clang::CXXMethodDecl* methodDecl = clang::dyn_cast_or_null<clang::CXXMethodDecl>(declaration))
|
||||
{
|
||||
declName = getDeclName(templateFunctionDeclaration);
|
||||
}
|
||||
else if (clang::dyn_cast<clang::FunctionDecl>(declaration)->isFunctionTemplateSpecialization())
|
||||
{
|
||||
std::string templateArgumentNamePart = "<";
|
||||
const clang::TemplateArgumentList* templateArgumentList = clang::dyn_cast<clang::FunctionDecl>(declaration)->getTemplateSpecializationArgs();
|
||||
for (size_t i = 0; i < templateArgumentList->size(); i++)
|
||||
if (methodDecl->getParent()->isLambda())
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
|
||||
templateArgumentNamePart += getTemplateArgumentName(templateArgument);
|
||||
templateArgumentNamePart += (i < templateArgumentList->size() - 1) ? ", " : "";
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(methodDecl->getParent()->getLocStart());
|
||||
std::string lambdaName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
|
||||
return std::make_shared<NameElement>(lambdaName, lambdaName);
|
||||
}
|
||||
templateArgumentNamePart += ">";
|
||||
declName += templateArgumentNamePart;
|
||||
}
|
||||
|
||||
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
|
||||
|
||||
if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
|
||||
{
|
||||
return getDeclName(templateFunctionDeclaration);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string functionName = declNameString;
|
||||
if (functionDecl->isFunctionTemplateSpecialization())
|
||||
{
|
||||
std::string templateArgumentNamePart = "<";
|
||||
const clang::TemplateArgumentList* templateArgumentList = functionDecl->getTemplateSpecializationArgs();
|
||||
for (size_t i = 0; i < templateArgumentList->size(); i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
|
||||
templateArgumentNamePart += getTemplateArgumentName(templateArgument);
|
||||
templateArgumentNamePart += (i < templateArgumentList->size() - 1) ? ", " : "";
|
||||
}
|
||||
templateArgumentNamePart += ">";
|
||||
functionName += templateArgumentNamePart;
|
||||
}
|
||||
|
||||
bool isStatic = false;
|
||||
bool isConst = false;
|
||||
|
||||
if (clang::isa<clang::CXXMethodDecl>(declaration))
|
||||
{
|
||||
const clang::CXXMethodDecl* methodDecl = clang::dyn_cast<const clang::CXXMethodDecl>(declaration);
|
||||
isStatic = methodDecl->isStatic();
|
||||
isConst = methodDecl->isConst();
|
||||
}
|
||||
else
|
||||
{
|
||||
isStatic = functionDecl->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
|
||||
CxxTypeNameResolver typenNameResolver(getIgnoredContextDecls());
|
||||
std::string returnTypeString = typenNameResolver.qualTypeToDataType(functionDecl->getReturnType())->getFullTypeName();
|
||||
|
||||
std::string parameterString = "(";
|
||||
for (unsigned int i = 0; i < functionDecl->param_size(); i++)
|
||||
{
|
||||
parameterString += typenNameResolver.qualTypeToDataType(functionDecl->parameters()[i]->getType())->getFullTypeName();
|
||||
if (i < functionDecl->param_size() - 1)
|
||||
{
|
||||
parameterString += ", ";
|
||||
}
|
||||
}
|
||||
parameterString += ")";
|
||||
|
||||
return std::make_shared<NameElement>(
|
||||
functionName + parameterString + (isConst ? "const" : ""),
|
||||
(isStatic ? "static " : "") + returnTypeString + " " + functionName + parameterString + (isConst ? " const" : ""));
|
||||
}
|
||||
|
||||
}
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
|
||||
{
|
||||
@@ -175,25 +224,29 @@ std::string CxxDeclNameResolver::getDeclName()
|
||||
templateParameterNamePart += (i < parameterList->size() - 1) ? ", " : "";
|
||||
}
|
||||
templateParameterNamePart += ">";
|
||||
declName += templateParameterNamePart;
|
||||
return std::make_shared<NameElement>(declNameString + templateParameterNamePart);
|
||||
}
|
||||
else if (clang::isa<clang::NamespaceDecl>(declaration) && clang::dyn_cast<clang::NamespaceDecl>(declaration)->isAnonymousNamespace())
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
declName = "anonymous namespace (" + FilePath(presumedBegin.getFilename()).fileName() + ")";
|
||||
return std::make_shared<NameElement>("anonymous namespace (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
else if (clang::isa<clang::EnumDecl>(declaration) && declName.size() == 0)
|
||||
else if (clang::isa<clang::EnumDecl>(declaration) && declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
declName = "anonymous enum (" + FilePath(presumedBegin.getFilename()).fileName() + ")";
|
||||
return std::make_shared<NameElement>("anonymous enum (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
|
||||
return declName;
|
||||
if (declNameString.size() > 0)
|
||||
{
|
||||
return std::make_shared<NameElement>(declNameString);
|
||||
}
|
||||
return std::shared_ptr<NameElement>();
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
|
||||
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
|
||||
{
|
||||
CxxDeclNameResolver resolver(declaration);
|
||||
return resolver.getDeclName();
|
||||
|
||||
@@ -9,14 +9,14 @@ class CxxDeclNameResolver: public CxxNameResolver
|
||||
public:
|
||||
CxxDeclNameResolver(const clang::Decl* declaration);
|
||||
CxxDeclNameResolver(const clang::Decl* declaration, std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
~CxxDeclNameResolver();
|
||||
virtual ~CxxDeclNameResolver();
|
||||
|
||||
NameHierarchy getDeclNameHierarchy();
|
||||
std::string getDeclName();
|
||||
std::shared_ptr<NameElement> getDeclName();
|
||||
|
||||
private:
|
||||
NameHierarchy getContextNameHierarchy(const clang::DeclContext* declaration);
|
||||
std::string getDeclName(const clang::NamedDecl* declaration);
|
||||
std::shared_ptr<NameElement> getDeclName(const clang::NamedDecl* declaration);
|
||||
std::string getTemplateParameterString(const clang::NamedDecl* parameter);
|
||||
std::string getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter);
|
||||
std::string getTemplateParameterTypeString(const clang::TemplateTypeParmDecl* parameter);
|
||||
|
||||
@@ -9,7 +9,7 @@ class CxxNameResolver
|
||||
{
|
||||
public:
|
||||
CxxNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
~CxxNameResolver();
|
||||
virtual ~CxxNameResolver();
|
||||
|
||||
void ignoreContextDecl(const clang::Decl* decl);
|
||||
bool ignoresContext(const clang::DeclContext* declContext);
|
||||
|
||||
@@ -12,7 +12,7 @@ class CxxTemplateArgumentNameResolver: public CxxNameResolver
|
||||
public:
|
||||
CxxTemplateArgumentNameResolver();
|
||||
CxxTemplateArgumentNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
~CxxTemplateArgumentNameResolver();
|
||||
virtual ~CxxTemplateArgumentNameResolver();
|
||||
|
||||
std::string getTemplateArgumentName(const clang::TemplateArgument& argument);
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ class CxxTypeNameResolver: public CxxNameResolver
|
||||
public:
|
||||
CxxTypeNameResolver();
|
||||
CxxTypeNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
~CxxTypeNameResolver();
|
||||
virtual ~CxxTypeNameResolver();
|
||||
|
||||
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user