data: basic template parsing
* Implemented basic parsing and storage of template parameter types, template classes and template functions * Added template specialization edge. * Implemented handling of partial specializations. Needs some more tweaking. * Added a lot of test code for template stuff (still needs some cases to be tested) * Removed the isTemplateParameterType from DataType, since it shouldn't be needed * Function qualTypeToDataType uses clang PrintingPolicy to fetch the desired format. * Merged a lot of code for getting the correct names and name hierarchies of definitions * Removed TokenComponentDataType * Merged both of the Storage::addTypeEdge(...) functions * Added "-fno-delayed-template-parsing" flag to parser for parsing test code.
This commit is contained in:
@@ -28,6 +28,11 @@ public:
|
||||
ABSTRACTION_NONE
|
||||
};
|
||||
|
||||
enum RecordType {
|
||||
RECORD_STRUCT,
|
||||
RECORD_CLASS
|
||||
};
|
||||
|
||||
static std::string addAccessPrefix(const std::string& str, AccessType access);
|
||||
static std::string addAbstractionPrefix(const std::string& str, AbstractionType abstraction);
|
||||
static std::string addStaticPrefix(const std::string& str, bool isStatic);
|
||||
@@ -84,6 +89,18 @@ public:
|
||||
virtual Id onGlobalVariableUsageParsed(
|
||||
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy) = 0;
|
||||
virtual Id onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function) = 0;
|
||||
|
||||
virtual Id onTemplateRecordParameterTypeParsed(
|
||||
const ParseLocation& location, const std::string& templateParameterTypeName,
|
||||
const std::vector<std::string>& templateRecordNameHierarchy) = 0;
|
||||
virtual Id onTemplateRecordSpecializationParsed(
|
||||
const ParseLocation& location, const std::vector<std::string>& specializedRecordNameHierarchy,
|
||||
const RecordType specializedRecordType, const std::vector<std::string>& templateRecordNameHierarchy) = 0;
|
||||
virtual Id onTemplateFunctionParameterTypeParsed(
|
||||
const ParseLocation& location, const std::string& templateParameterTypeName,
|
||||
const ParseFunction function) = 0;
|
||||
virtual Id onTemplateFunctionSpecializationParsed(
|
||||
const ParseLocation& location, const ParseFunction specializedFunction, const ParseFunction templateFunction) = 0;
|
||||
};
|
||||
|
||||
#endif // PARSER_CLIENT_H
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "data/type/DataType.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, ParserClient* client)
|
||||
@@ -32,7 +33,7 @@ bool ASTVisitor::VisitTypedefDecl(clang::TypedefDecl* declaration)
|
||||
{
|
||||
m_client->onTypedefParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
getParseTypeUsage(declaration->getTypeSourceInfo()->getTypeLoc(), declaration->getUnderlyingType()),
|
||||
convertAccessType(declaration->getAccess())
|
||||
);
|
||||
@@ -49,19 +50,19 @@ bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
|
||||
{
|
||||
m_client->onClassParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
convertAccessType(declaration->getAccess()),
|
||||
getParseLocationOfRecordBody(declaration)
|
||||
);
|
||||
|
||||
if (declaration->hasDefinition() && declaration->getNumBases())
|
||||
{
|
||||
for (const auto& it : declaration->bases())
|
||||
for (const clang::CXXBaseSpecifier& it : declaration->bases())
|
||||
{
|
||||
m_client->onInheritanceParsed(
|
||||
getParseLocation(it.getSourceRange()),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::splitToVector(getTypeName(it.getType()), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
utility::qualTypeToDataType(it.getType()).getTypeNameHierarchy(),
|
||||
convertAccessType(it.getAccessSpecifier())
|
||||
);
|
||||
}
|
||||
@@ -71,10 +72,11 @@ bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
|
||||
{
|
||||
m_client->onStructParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
convertAccessType(declaration->getAccess()),
|
||||
getParseLocationOfRecordBody(declaration)
|
||||
);
|
||||
// TODO: what about struct inheritance?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +183,7 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
getParseLocationOfFunctionBody(declaration)
|
||||
);
|
||||
|
||||
if (declaration->hasBody() && declaration->isThisDeclarationADefinition())
|
||||
if (declaration->hasBody() && declaration->getBody() != NULL && declaration->isThisDeclarationADefinition())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getBody());
|
||||
@@ -206,7 +208,7 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
m_client->onFieldUsageParsed(
|
||||
getParseLocationForNamedDecl(init->getMember(), init->getMemberLocation()),
|
||||
getParseFunction(declaration),
|
||||
utility::splitToVector(init->getMember()->getQualifiedNameAsString(), "::")
|
||||
utility::getDeclNameHierarchy(init->getMember())
|
||||
);
|
||||
}
|
||||
else if (init->isBaseInitializer())
|
||||
@@ -222,7 +224,6 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -232,11 +233,10 @@ bool ASTVisitor::VisitNamespaceDecl(clang::NamespaceDecl* declaration)
|
||||
{
|
||||
m_client->onNamespaceParsed(
|
||||
declaration->isAnonymousNamespace() ? ParseLocation() : getParseLocationForNamedDecl(declaration),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
getParseLocation(declaration->getSourceRange())
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -246,12 +246,11 @@ bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration)
|
||||
{
|
||||
m_client->onEnumParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
convertAccessType(declaration->getAccess()),
|
||||
getParseLocation(declaration->getSourceRange())
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -261,13 +260,110 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
|
||||
{
|
||||
m_client->onEnumFieldParsed(
|
||||
getParseLocation(declaration->getSourceRange()),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::")
|
||||
utility::getDeclNameHierarchy(declaration)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
|
||||
{
|
||||
std::vector<std::string> templateRecordNameHierarchy = utility::getDeclNameHierarchy(declaration);
|
||||
|
||||
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
|
||||
for (int i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
clang::NamedDecl* namedDecl = parameterList->getParam(i);
|
||||
|
||||
if (hasValidLocation(namedDecl))
|
||||
{
|
||||
std::string templateParameterTypeName = namedDecl->getNameAsString();
|
||||
|
||||
m_client->onTemplateRecordParameterTypeParsed(
|
||||
getParseLocationForNamedDecl(namedDecl),
|
||||
templateParameterTypeName,
|
||||
templateRecordNameHierarchy
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (clang::ClassTemplateDecl::spec_iterator it = declaration->specializations().begin(); // template argument as parameter does not work
|
||||
it != declaration->specializations().end(); it++
|
||||
)
|
||||
{
|
||||
ParserClient::RecordType specializedRecordType = it->isStruct() ? ParserClient::RECORD_STRUCT : ParserClient::RECORD_CLASS;
|
||||
std::vector<std::string> specializedRecordNameHierarchy = utility::getDeclNameHierarchy(*(it));
|
||||
m_client->onTemplateRecordSpecializationParsed(
|
||||
getParseLocationForNamedDecl(*it), specializedRecordNameHierarchy, specializedRecordType, templateRecordNameHierarchy
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* declaration)
|
||||
{
|
||||
//std::vector<std::string> templateRecordNameHierarchy = utility::splitToVector(
|
||||
// declaration->getQualifiedNameAsString(), "::"
|
||||
//);
|
||||
|
||||
//clang::ClassTemplateDecl* baseTemplateDecl = declaration->getSpecializedTemplate();
|
||||
|
||||
//std::string specializedParameterNamePart = "<";
|
||||
//const clang::TemplateArgumentList& templateArgumentList = declaration->getTemplateArgs();
|
||||
//for (int i = 0; i < templateArgumentList.size(); i++)
|
||||
//{
|
||||
// DataType datatype = utility::qualTypeToDataType(templateArgumentList.get(i).getAsType());
|
||||
// if (datatype.isTemplateParameterType())
|
||||
// {
|
||||
// specializedParameterNamePart += baseTemplateDecl->getTemplateParameters()->getParam(i)->getNameAsString();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// specializedParameterNamePart += datatype.getFullTypeName();
|
||||
// }
|
||||
// specializedParameterNamePart += (i < templateArgumentList.size() - 1) ? ", " : "";
|
||||
//}
|
||||
//specializedParameterNamePart += ">";
|
||||
|
||||
//int foo = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration)
|
||||
{
|
||||
const ParseFunction templateFunction = getParseFunction(declaration->getTemplatedDecl());
|
||||
for (clang::FunctionTemplateDecl::spec_iterator it = declaration->specializations().begin(); it != declaration->specializations().end(); it++)
|
||||
{
|
||||
ParseLocation specializedFunctionLocation = getParseLocationForNamedDecl(*(it));
|
||||
ParseFunction specializedFunction = getParseFunction(*(it));
|
||||
m_client->onTemplateFunctionSpecializationParsed(
|
||||
specializedFunctionLocation,
|
||||
specializedFunction,
|
||||
templateFunction);
|
||||
|
||||
m_client->onFunctionParsed(specializedFunctionLocation, specializedFunction, getParseLocationOfFunctionBody(*(it)));
|
||||
}
|
||||
clang::TemplateParameterList* parameterList = declaration->getTemplateParameters();
|
||||
for (int i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
clang::NamedDecl* namedDecl = parameterList->getParam(i);
|
||||
|
||||
if (hasValidLocation(namedDecl))
|
||||
{
|
||||
std::string templateParameterTypeName = namedDecl->getNameAsString();
|
||||
|
||||
m_client->onTemplateFunctionParameterTypeParsed(
|
||||
getParseLocationForNamedDecl(namedDecl),
|
||||
templateParameterTypeName,
|
||||
templateFunction
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr)
|
||||
{
|
||||
// if (clang::FunctionDecl *CalleeDecl = CE->getDirectCallee())
|
||||
@@ -340,7 +436,7 @@ void ASTVisitor::VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::Mem
|
||||
m_client->onFieldUsageParsed(
|
||||
parseLocation,
|
||||
getParseFunction(decl),
|
||||
utility::splitToVector(expr->getMemberDecl()->getQualifiedNameAsString(), "::")
|
||||
utility::getDeclNameHierarchy(expr->getMemberDecl())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -354,7 +450,7 @@ void ASTVisitor::VisitDeclRefExprInDeclBody(clang::FunctionDecl* decl, clang::De
|
||||
m_client->onGlobalVariableUsageParsed(
|
||||
parseLocation,
|
||||
getParseFunction(decl),
|
||||
utility::splitToVector(expr->getDecl()->getQualifiedNameAsString(), "::")
|
||||
utility::getDeclNameHierarchy(expr->getDecl())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -504,16 +600,21 @@ std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* decla
|
||||
|
||||
ParseVariable ASTVisitor::getParseVariable(clang::DeclaratorDecl* declaration) const
|
||||
{
|
||||
bool isStatic = false;
|
||||
bool isStatic;
|
||||
std::vector<std::string> hameHierarchy = utility::getDeclNameHierarchy(declaration);
|
||||
if (clang::isa<clang::VarDecl>(declaration))
|
||||
{
|
||||
clang::VarDecl* varDecl = clang::dyn_cast<clang::VarDecl>(declaration);
|
||||
isStatic = varDecl->isStaticDataMember() || varDecl->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
else if (clang::isa<clang::FieldDecl>(declaration))
|
||||
{
|
||||
isStatic = false; // fieldDecls cannot be static. If they are, they are treated as VarDecls
|
||||
}
|
||||
|
||||
return ParseVariable(
|
||||
getParseTypeUsage(declaration->getTypeSourceInfo()->getTypeLoc(), declaration->getType()),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
hameHierarchy,
|
||||
isStatic
|
||||
);
|
||||
}
|
||||
@@ -522,6 +623,7 @@ ParseFunction ASTVisitor::getParseFunction(clang::FunctionDecl* declaration) con
|
||||
{
|
||||
bool isStatic = false;
|
||||
bool isConst = false;
|
||||
|
||||
if (clang::isa<clang::CXXMethodDecl>(declaration))
|
||||
{
|
||||
clang::CXXMethodDecl* methodDecl = clang::dyn_cast<clang::CXXMethodDecl>(declaration);
|
||||
@@ -535,7 +637,7 @@ ParseFunction ASTVisitor::getParseFunction(clang::FunctionDecl* declaration) con
|
||||
|
||||
return ParseFunction(
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
utility::splitToVector(declaration->getQualifiedNameAsString(), "::"),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
getParameters(declaration),
|
||||
isStatic,
|
||||
isConst
|
||||
|
||||
@@ -16,11 +16,11 @@ public:
|
||||
virtual ~ASTVisitor();
|
||||
|
||||
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file.
|
||||
// virtual bool VisitTranslationUnitDecl(clang::TranslationUnitDecl* decl)
|
||||
// {
|
||||
// decl->dump();
|
||||
// return true;
|
||||
// }
|
||||
//virtual bool VisitTranslationUnitDecl(clang::TranslationUnitDecl* decl)
|
||||
//{
|
||||
// decl->dump();
|
||||
// return true;
|
||||
//}
|
||||
|
||||
// RecursiveASTVisitor implementation
|
||||
virtual bool VisitStmt(const clang::Stmt* statement); // avoid visiting
|
||||
@@ -36,6 +36,10 @@ public:
|
||||
virtual bool VisitEnumDecl(clang::EnumDecl* declaration); // enums
|
||||
virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields
|
||||
|
||||
virtual bool VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration);
|
||||
virtual bool VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* declaration);
|
||||
virtual bool VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration);
|
||||
|
||||
// ASTBodyVisitorClient implementation
|
||||
virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr); // calls
|
||||
virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr); // calls in initialization of global variables
|
||||
|
||||
@@ -26,6 +26,10 @@ void CxxParser::parseFiles(
|
||||
// verbose
|
||||
// args.push_back("-v");
|
||||
|
||||
// The option -fno-delayed-template-parsing signals that templates that there should
|
||||
// be AST elements for unused template functions as well.
|
||||
args.push_back("-fno-delayed-template-parsing");
|
||||
|
||||
// The option -c signals that no executable is built.
|
||||
args.push_back("-c");
|
||||
|
||||
@@ -72,5 +76,7 @@ void CxxParser::parseFiles(
|
||||
void CxxParser::parseFile(std::shared_ptr<TextAccess> textAccess)
|
||||
{
|
||||
ASTActionFactory actionFactory(m_client);
|
||||
clang::tooling::runToolOnCode(actionFactory.create(), textAccess->getText());
|
||||
std::vector<std::string> args;
|
||||
args.push_back("-fno-delayed-template-parsing");
|
||||
clang::tooling::runToolOnCodeWithArgs(actionFactory.create(), textAccess->getText(), args);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
|
||||
#include <clang/AST/PrettyPrinter.h>
|
||||
#include <clang/AST/DeclTemplate.h>
|
||||
#include <clang/AST/ASTContext.h>
|
||||
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/modifier/DataTypeModifierArray.h"
|
||||
#include "data/type/modifier/DataTypeModifierPointer.h"
|
||||
@@ -7,12 +11,13 @@
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
#include "utility/utilityString.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
DataType qualTypeToDataType(clang::QualType qualType)
|
||||
{
|
||||
std::string typeName;
|
||||
std::vector<std::string> typeNameHerarchy;
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
|
||||
@@ -21,7 +26,7 @@ namespace utility
|
||||
const clang::Type* type = qualType.getTypePtr();
|
||||
if (type->getAs<clang::TypedefType>())
|
||||
{
|
||||
typeName = utility::substrAfter(qualType.getAsString(), ' ');
|
||||
typeNameHerarchy.push_back(utility::substrAfter(qualType.getAsString(), ' '));
|
||||
break;
|
||||
}
|
||||
else if (type->isPointerType())
|
||||
@@ -54,17 +59,35 @@ namespace utility
|
||||
|
||||
qualType = type->getPointeeType();
|
||||
}
|
||||
else if (type->isStructureOrClassType() || type->isEnumeralType())
|
||||
{
|
||||
// we are working on the string here to not lose the namespace information stored in the name.
|
||||
typeName = utility::substrAfter(qualType.getAsString(), ' ');
|
||||
|
||||
// typeName = qualType.getBaseTypeIdentifier()->getName(); // this one does not keep namespace information.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = qualType.getUnqualifiedType().getAsString();
|
||||
const clang::Type* type = qualType.getUnqualifiedType().getTypePtr();
|
||||
|
||||
if (clang::isa<clang::TagType>(type))
|
||||
{
|
||||
typeNameHerarchy = getDeclNameHierarchy(clang::dyn_cast<clang::TagType>(type)->getDecl());
|
||||
}
|
||||
else
|
||||
{
|
||||
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
|
||||
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
|
||||
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
|
||||
std::string typeName = qualType.getUnqualifiedType().getAsString(pp);
|
||||
|
||||
if (type->isTemplateTypeParmType())
|
||||
{
|
||||
clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmType>(qualType.getUnqualifiedType())->getDecl();
|
||||
if (templateTypeParmDecl)
|
||||
{
|
||||
typeNameHerarchy = getContextNameHierarchy(templateTypeParmDecl->getDeclContext());
|
||||
typeNameHerarchy.back() += "::" + typeName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -73,12 +96,90 @@ namespace utility
|
||||
{
|
||||
qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
}
|
||||
return DataType(typeNameHerarchy, qualifierList, modifierStack);
|
||||
}
|
||||
|
||||
if (typeName == "_Bool")
|
||||
std::vector<std::string> getDeclNameHierarchy(clang::Decl* declaration)
|
||||
{
|
||||
std::string declName = "";
|
||||
|
||||
if (clang::isa<clang::NamedDecl>(declaration))
|
||||
{
|
||||
typeName = "bool";
|
||||
declName = getDeclName(clang::dyn_cast<clang::NamedDecl>(declaration));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("unhandled declaration type");
|
||||
}
|
||||
std::vector<std::string> contextNameHierarchy = getContextNameHierarchy(declaration->getDeclContext());
|
||||
contextNameHierarchy.push_back(declName);
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
std::vector<std::string> getContextNameHierarchy(clang::DeclContext* declContext)
|
||||
{
|
||||
std::vector<std::string> contextNameHierarchy;
|
||||
|
||||
clang::DeclContext* parentContext = declContext->getParent();
|
||||
if (parentContext)
|
||||
{
|
||||
contextNameHierarchy = getContextNameHierarchy(parentContext);
|
||||
}
|
||||
|
||||
return DataType(typeName, qualifierList, modifierStack);
|
||||
if (clang::isa<clang::NamedDecl>(declContext))
|
||||
{
|
||||
std::string declName = getDeclName(clang::dyn_cast<clang::NamedDecl>(declContext));
|
||||
if (declName != "")
|
||||
{
|
||||
contextNameHierarchy.push_back(declName);
|
||||
}
|
||||
}
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
std::string getDeclName(clang::NamedDecl* declaration)
|
||||
{
|
||||
std::string declName = declaration->getNameAsString();
|
||||
|
||||
if (clang::isa<clang::CXXRecordDecl>(declaration))
|
||||
{
|
||||
clang::ClassTemplateDecl* templateClassDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(declaration)->getDescribedClassTemplate();
|
||||
if (templateClassDeclaration)
|
||||
{
|
||||
declName = getDeclName(templateClassDeclaration);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
|
||||
{
|
||||
std::string specializedParameterNamePart = "<";
|
||||
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
|
||||
for (int i = 0; i < templateArgumentList.size(); i++)
|
||||
{
|
||||
DataType datatype = utility::qualTypeToDataType(templateArgumentList.get(i).getAsType());
|
||||
specializedParameterNamePart += datatype.getFullTypeName();
|
||||
specializedParameterNamePart += (i < templateArgumentList.size() - 1) ? ", " : "";
|
||||
}
|
||||
specializedParameterNamePart += ">";
|
||||
declName += specializedParameterNamePart;
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration))
|
||||
{
|
||||
std::string templateParameterNamePart = "<";
|
||||
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
|
||||
for (int i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
clang::NamedDecl* namedDecl = parameterList->getParam(i);
|
||||
|
||||
templateParameterNamePart += namedDecl->getNameAsString();
|
||||
templateParameterNamePart += (i < parameterList->size() - 1) ? ", " : "";
|
||||
}
|
||||
templateParameterNamePart += ">";
|
||||
declName += templateParameterNamePart;
|
||||
}
|
||||
else if (clang::isa<clang::NamespaceDecl>(declaration) && clang::dyn_cast<clang::NamespaceDecl>(declaration)->isAnonymousNamespace())
|
||||
{
|
||||
declName = "(anonymous namespace)";
|
||||
}
|
||||
return declName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,21 @@
|
||||
#define UTILITY_CLANG_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
|
||||
class DataType;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
DataType qualTypeToDataType(clang::QualType qualType);
|
||||
|
||||
std::vector<std::string> getDeclNameHierarchy(clang::Decl* declaration);
|
||||
std::vector<std::string> getContextNameHierarchy(clang::DeclContext* declaration);
|
||||
std::string getDeclName(clang::NamedDecl* declaration);
|
||||
}
|
||||
|
||||
#endif // UTILITY_CLANG_H
|
||||
|
||||
Reference in New Issue
Block a user