build: merge Coati app and Trial to single executable
* removed trial target * updated deploy scripts to exclude trial * cleanup CMakeLists * removed Eigen dependencies * split parser lib into lib_cxx and lib_java * added ProjectFactory and ProjectFactoryModules * removed old installer projects * updated wix installer * updated readme for wix setup * updated to use obfuscated exe * added qt.conf * added indexing dialog images * added jars * added coatidb files of sample projects * added source code of javaparser sample * removed auto-refresh image * intermediate files of windows installer are created in build folder * preselected desktop shortcut * build bat is executed from deploy_windows script
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
#include "data/parser/cxx/name_resolver/CxxDeclNameResolver.h"
|
||||
|
||||
#include <clang/AST/DeclTemplate.h>
|
||||
#include <clang/AST/ASTContext.h>
|
||||
|
||||
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
CxxDeclNameResolver::CxxDeclNameResolver(const clang::Decl* declaration)
|
||||
: CxxNameResolver(std::vector<const clang::Decl*>())
|
||||
{
|
||||
const clang::Decl* prev = declaration;
|
||||
while (prev)
|
||||
{
|
||||
m_declaration = prev;
|
||||
prev = prev->getPreviousDecl();
|
||||
}
|
||||
}
|
||||
|
||||
CxxDeclNameResolver::CxxDeclNameResolver(const clang::Decl* declaration, std::vector<const clang::Decl*> ignoredContextDecls)
|
||||
: CxxNameResolver(ignoredContextDecls)
|
||||
{
|
||||
const clang::Decl* prev = declaration;
|
||||
while (prev)
|
||||
{
|
||||
m_declaration = prev;
|
||||
prev = prev->getPreviousDecl();
|
||||
}
|
||||
}
|
||||
|
||||
CxxDeclNameResolver::~CxxDeclNameResolver()
|
||||
{
|
||||
}
|
||||
|
||||
NameHierarchy CxxDeclNameResolver::getDeclNameHierarchy()
|
||||
{
|
||||
NameHierarchy contextNameHierarchy;
|
||||
if (m_declaration)
|
||||
{
|
||||
std::shared_ptr<NameElement> declName;
|
||||
|
||||
if (clang::isa<clang::NamedDecl>(m_declaration))
|
||||
{
|
||||
declName = getDeclName(clang::dyn_cast<const clang::NamedDecl>(m_declaration));
|
||||
}
|
||||
else
|
||||
{
|
||||
// LOG_ERROR("unhandled declaration type: " + std::string(m_declaration->getDeclKindName()));
|
||||
}
|
||||
|
||||
contextNameHierarchy = getContextNameHierarchy(m_declaration->getDeclContext());
|
||||
|
||||
if (declName)
|
||||
{
|
||||
contextNameHierarchy.push(declName);
|
||||
}
|
||||
}
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
NameHierarchy CxxDeclNameResolver::getContextNameHierarchy(const clang::DeclContext* declContext)
|
||||
{
|
||||
NameHierarchy contextNameHierarchy;
|
||||
|
||||
if (declContext && !ignoresContext(declContext))
|
||||
{
|
||||
const clang::DeclContext* parentContext = declContext->getParent();
|
||||
if (parentContext)
|
||||
{
|
||||
contextNameHierarchy = getContextNameHierarchy(parentContext);
|
||||
}
|
||||
|
||||
if (const clang::NamedDecl* contextNamedDecl = clang::dyn_cast_or_null<clang::NamedDecl>(declContext))
|
||||
{
|
||||
std::shared_ptr<NameElement> declName = getDeclName(contextNamedDecl);
|
||||
if (declName)
|
||||
{
|
||||
contextNameHierarchy.push(declName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
|
||||
{
|
||||
const clang::NamedDecl* declaration = clang::dyn_cast<clang::NamedDecl>(m_declaration);
|
||||
std::string declNameString = declaration->getNameAsString();
|
||||
if (const clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast_or_null<clang::TypeAliasDecl>(declaration))
|
||||
{
|
||||
clang::TypeAliasTemplateDecl* templatedDeclaration = typeAliasDecl->getDescribedAliasTemplate();
|
||||
if (templatedDeclaration)
|
||||
{
|
||||
return getDeclName(templatedDeclaration);
|
||||
}
|
||||
}
|
||||
if (const clang::CXXRecordDecl* recordDecl = clang::dyn_cast_or_null<clang::CXXRecordDecl>(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::string specializedParameterNamePart = "<";
|
||||
int templateArgumentCount = partialSpecializationDecl->getTemplateArgs().size();
|
||||
const clang::TemplateArgumentList& templateArgumentList = partialSpecializationDecl->getTemplateArgs();
|
||||
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())
|
||||
{
|
||||
specializedParameterNamePart += 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
|
||||
{
|
||||
specializedParameterNamePart += getTemplateArgumentName(templateArgument);
|
||||
}
|
||||
specializedParameterNamePart += (i < templateArgumentCount - 1) ? ", " : "";
|
||||
}
|
||||
specializedParameterNamePart += ">";
|
||||
return std::make_shared<NameElement>(declNameString + specializedParameterNamePart);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
|
||||
{
|
||||
std::string templateArgumentNamePart = "<";
|
||||
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
|
||||
for (size_t i = 0; i < templateArgumentList.size(); i++)
|
||||
{
|
||||
templateArgumentNamePart += getTemplateArgumentName(templateArgumentList.get(i));
|
||||
templateArgumentNamePart += (i < templateArgumentList.size() - 1) ? ", " : "";
|
||||
}
|
||||
templateArgumentNamePart += ">";
|
||||
return std::make_shared<NameElement>(declNameString + templateArgumentNamePart);
|
||||
}
|
||||
else if (recordDecl->isLambda())
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(recordDecl->getLocStart());
|
||||
std::string lambdaName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
|
||||
return std::make_shared<NameElement>(lambdaName, NameElement::Signature("void", "()"));
|
||||
}
|
||||
else if (declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
const std::string recordType = (recordDecl->isStruct() ? "struct" : "class");
|
||||
return std::make_shared<NameElement>("anonymous " + recordType + " (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
{
|
||||
if (const clang::CXXMethodDecl* methodDecl = clang::dyn_cast_or_null<clang::CXXMethodDecl>(declaration))
|
||||
{
|
||||
if (methodDecl->getParent()->isLambda())
|
||||
{
|
||||
// return empty pointer since lambdas will be handled at the level of the parent class... not optimal.
|
||||
return std::shared_ptr<NameElement>();
|
||||
}
|
||||
}
|
||||
|
||||
std::string functionName;
|
||||
|
||||
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
|
||||
if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
|
||||
{
|
||||
functionName = getDeclName(templateFunctionDeclaration)->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
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());
|
||||
typenNameResolver.ignoreContextDecl(functionDecl);
|
||||
std::string returnTypeString = typenNameResolver.qualTypeToDataType(functionDecl->getReturnType())->getFullTypeName();
|
||||
|
||||
std::string parameterString = "(";
|
||||
for (unsigned int i = 0; i < functionDecl->param_size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
parameterString += ", ";
|
||||
}
|
||||
parameterString += typenNameResolver.qualTypeToDataType(functionDecl->parameters()[i]->getType())->getFullTypeName();
|
||||
}
|
||||
parameterString += ")";
|
||||
|
||||
return std::make_shared<NameElement>(
|
||||
functionName,
|
||||
NameElement::Signature((isStatic ? "static " : "") + returnTypeString, parameterString + (isConst ? " const" : "")));
|
||||
}
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
|
||||
{
|
||||
std::string templateParameterNamePart = "<";
|
||||
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
templateParameterNamePart += getTemplateParameterString(parameterList->getParam(i));
|
||||
templateParameterNamePart += (i < parameterList->size() - 1) ? ", " : "";
|
||||
}
|
||||
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());
|
||||
return std::make_shared<NameElement>("anonymous namespace (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
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());
|
||||
return std::make_shared<NameElement>("anonymous enum (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
else if (
|
||||
(
|
||||
clang::isa<clang::TemplateTypeParmDecl>(declaration) ||
|
||||
clang::isa<clang::NonTypeTemplateParmDecl>(declaration) ||
|
||||
clang::isa<clang::TemplateTemplateParmDecl>(declaration)
|
||||
) && declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<NameElement>("anonymous template parameter (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
else if (clang::isa<clang::ParmVarDecl>(declaration) && declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<NameElement>("anonymous parameter (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
|
||||
if (declNameString.size() > 0)
|
||||
{
|
||||
return std::make_shared<NameElement>(declNameString);
|
||||
}
|
||||
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
// LOG_ERROR("could not resolve name of decl at: " + declaration->getLocation().printToString(sourceManager));
|
||||
return std::make_shared<NameElement>("anonymous symbol (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
}
|
||||
|
||||
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
|
||||
{
|
||||
CxxDeclNameResolver resolver(declaration);
|
||||
return resolver.getDeclName();
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getTemplateParameterString(const clang::NamedDecl* parameter)
|
||||
{
|
||||
std::string templateParameterTypeString = "";
|
||||
|
||||
clang::Decl::Kind templateParameterKind = parameter->getKind();
|
||||
switch (templateParameterKind)
|
||||
{
|
||||
case clang::Decl::NonTypeTemplateParm:
|
||||
templateParameterTypeString = getTemplateParameterTypeString(clang::dyn_cast<clang::NonTypeTemplateParmDecl>(parameter));
|
||||
break;
|
||||
case clang::Decl::TemplateTypeParm:
|
||||
templateParameterTypeString = getTemplateParameterTypeString(clang::dyn_cast<clang::TemplateTypeParmDecl>(parameter));
|
||||
break;
|
||||
case clang::Decl::TemplateTemplateParm:
|
||||
templateParameterTypeString = getTemplateParameterTypeString(clang::dyn_cast<clang::TemplateTemplateParmDecl>(parameter));
|
||||
break;
|
||||
default:
|
||||
// LOG_ERROR("Unhandled kind of template parameter.");
|
||||
break;
|
||||
}
|
||||
|
||||
std::string parameterName = parameter->getName();
|
||||
if (!parameterName.empty())
|
||||
{
|
||||
templateParameterTypeString += " " + parameterName;
|
||||
}
|
||||
return templateParameterTypeString;
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter)
|
||||
{
|
||||
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
|
||||
|
||||
if (clang::isa<clang::TemplateDecl>(m_declaration))
|
||||
{
|
||||
typeNameResolver.ignoreContextDecl(clang::dyn_cast<clang::TemplateDecl>(m_declaration)->getTemplatedDecl());
|
||||
}
|
||||
else // works for partial template specializations
|
||||
{
|
||||
typeNameResolver.ignoreContextDecl(m_declaration);
|
||||
}
|
||||
|
||||
std::string typeString = typeNameResolver.qualTypeToDataType(parameter->getType())->getFullTypeName();
|
||||
|
||||
if (parameter->isTemplateParameterPack())
|
||||
{
|
||||
typeString += "...";
|
||||
}
|
||||
|
||||
return typeString;
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getTemplateParameterTypeString(const clang::TemplateTypeParmDecl* parameter)
|
||||
{
|
||||
std::string typeString = (parameter->wasDeclaredWithTypename() ? "typename" : "class");
|
||||
if (parameter->isTemplateParameterPack())
|
||||
{
|
||||
typeString += "...";
|
||||
}
|
||||
return typeString;
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getTemplateParameterTypeString(const clang::TemplateTemplateParmDecl* parameter)
|
||||
{
|
||||
std::string templateParameterTypeString = "template<";
|
||||
clang::TemplateParameterList* parameterList = parameter->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
templateParameterTypeString += getTemplateParameterString(parameterList->getParam(i));
|
||||
templateParameterTypeString += (i < parameterList->size() - 1) ? ", " : "";
|
||||
}
|
||||
templateParameterTypeString += ">";
|
||||
templateParameterTypeString += " typename"; // TODO: what if template template parameter is defined with class keyword?
|
||||
|
||||
if (parameter->isTemplateParameterPack())
|
||||
{
|
||||
templateParameterTypeString += "...";
|
||||
}
|
||||
|
||||
return templateParameterTypeString;
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getTemplateArgumentName(const clang::TemplateArgument& argument)
|
||||
{
|
||||
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
|
||||
return resolver.getTemplateArgumentName(argument);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef CXX_DECL_NAME_RESOLVER_H
|
||||
#define CXX_DECL_NAME_RESOLVER_H
|
||||
|
||||
#include "data/name/NameHierarchy.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
|
||||
|
||||
class CxxDeclNameResolver: public CxxNameResolver
|
||||
{
|
||||
public:
|
||||
CxxDeclNameResolver(const clang::Decl* declaration);
|
||||
CxxDeclNameResolver(const clang::Decl* declaration, std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
virtual ~CxxDeclNameResolver();
|
||||
|
||||
NameHierarchy getDeclNameHierarchy();
|
||||
std::shared_ptr<NameElement> getDeclName();
|
||||
|
||||
private:
|
||||
NameHierarchy getContextNameHierarchy(const clang::DeclContext* 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);
|
||||
std::string getTemplateParameterTypeString(const clang::TemplateTemplateParmDecl* parameter);
|
||||
std::string getTemplateArgumentName(const clang::TemplateArgument& argument);
|
||||
|
||||
const clang::Decl* m_declaration;
|
||||
};
|
||||
|
||||
#endif // CXX_DECL_NAME_RESOLVER_H
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
|
||||
|
||||
CxxNameResolver::CxxNameResolver(std::vector<const clang::Decl*> ignoredContextDecls)
|
||||
: m_ignoredContextDecls(ignoredContextDecls)
|
||||
{
|
||||
}
|
||||
|
||||
CxxNameResolver::~CxxNameResolver()
|
||||
{
|
||||
}
|
||||
|
||||
void CxxNameResolver::ignoreContextDecl(const clang::Decl* decl)
|
||||
{
|
||||
m_ignoredContextDecls.push_back(decl);
|
||||
}
|
||||
|
||||
bool CxxNameResolver::ignoresContext(const clang::DeclContext* declContext)
|
||||
{
|
||||
const clang::Decl* decl = clang::dyn_cast<clang::Decl>(declContext);
|
||||
for (size_t i = 0; i < m_ignoredContextDecls.size(); i++)
|
||||
{
|
||||
if (decl == m_ignoredContextDecls[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const clang::Decl*> CxxNameResolver::getIgnoredContextDecls() const
|
||||
{
|
||||
return m_ignoredContextDecls;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef CXX_NAME_RESOLVER_H
|
||||
#define CXX_NAME_RESOLVER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
|
||||
class CxxNameResolver
|
||||
{
|
||||
public:
|
||||
CxxNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
virtual ~CxxNameResolver();
|
||||
|
||||
void ignoreContextDecl(const clang::Decl* decl);
|
||||
bool ignoresContext(const clang::DeclContext* declContext);
|
||||
|
||||
protected:
|
||||
std::vector<const clang::Decl*> getIgnoredContextDecls() const;
|
||||
|
||||
private:
|
||||
std::vector<const clang::Decl*> m_ignoredContextDecls;
|
||||
};
|
||||
|
||||
#endif // CXX_NAME_RESOLVER_H
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
|
||||
|
||||
#include <clang/AST/PrettyPrinter.h>
|
||||
#include <clang/AST/DeclTemplate.h>
|
||||
|
||||
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
|
||||
#include "data/type/NamedDataType.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver()
|
||||
: CxxNameResolver(std::vector<const clang::Decl*>())
|
||||
{
|
||||
}
|
||||
|
||||
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver(std::vector<const clang::Decl*> ignoredContextDecls)
|
||||
: CxxNameResolver(ignoredContextDecls)
|
||||
{
|
||||
}
|
||||
|
||||
CxxTemplateArgumentNameResolver::~CxxTemplateArgumentNameResolver()
|
||||
{
|
||||
}
|
||||
|
||||
std::string CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clang::TemplateArgument& argument)
|
||||
{
|
||||
// This doesn't work correctly if the template argument is dependent.
|
||||
// If that's required: build name from depth and index of template arg.
|
||||
const clang::TemplateArgument::ArgKind kind = argument.getKind();
|
||||
switch (kind)
|
||||
{
|
||||
case clang::TemplateArgument::Type:
|
||||
{
|
||||
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
|
||||
return typeNameResolver.qualTypeToDataType(argument.getAsType())->getFullTypeName();
|
||||
}
|
||||
case clang::TemplateArgument::Integral:
|
||||
case clang::TemplateArgument::Null:
|
||||
case clang::TemplateArgument::Declaration:
|
||||
case clang::TemplateArgument::NullPtr:
|
||||
case clang::TemplateArgument::Template:
|
||||
case clang::TemplateArgument::TemplateExpansion: // handled correctly? template template parameter...
|
||||
case clang::TemplateArgument::Expression:
|
||||
{
|
||||
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 buf;
|
||||
llvm::raw_string_ostream os(buf);
|
||||
argument.print(pp, os);
|
||||
const std::string typeName = os.str();
|
||||
|
||||
return typeName;
|
||||
}
|
||||
case clang::TemplateArgument::Pack:
|
||||
{
|
||||
std::string typeName = "<";
|
||||
argument.getPackAsArray();
|
||||
llvm::ArrayRef<clang::TemplateArgument> pack = argument.getPackAsArray();
|
||||
for (size_t i = 0; i < pack.size(); i++)
|
||||
{
|
||||
typeName += getTemplateArgumentName(pack[i]);
|
||||
if (i < pack.size() - 1)
|
||||
{
|
||||
typeName += ", ";
|
||||
}
|
||||
}
|
||||
typeName += ">";
|
||||
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef CXX_TEMPLATE_ARGUMENT_NAME_RESOLVER_H
|
||||
#define CXX_TEMPLATE_ARGUMENT_NAME_RESOLVER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
|
||||
|
||||
class DataType;
|
||||
|
||||
class CxxTemplateArgumentNameResolver: public CxxNameResolver
|
||||
{
|
||||
public:
|
||||
CxxTemplateArgumentNameResolver();
|
||||
CxxTemplateArgumentNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
virtual ~CxxTemplateArgumentNameResolver();
|
||||
|
||||
std::string getTemplateArgumentName(const clang::TemplateArgument& argument);
|
||||
};
|
||||
|
||||
#endif // CXX_TEMPLATE_ARGUMENT_NAME_RESOLVER_H
|
||||
@@ -0,0 +1,270 @@
|
||||
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
|
||||
|
||||
#include <clang/AST/PrettyPrinter.h>
|
||||
#include <clang/AST/DeclTemplate.h>
|
||||
#include <clang/AST/ASTContext.h>
|
||||
|
||||
#include "data/parser/cxx/name_resolver/CxxDeclNameResolver.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/NamedDataType.h"
|
||||
#include "data/type/ArrayModifiedDataType.h"
|
||||
#include "data/type/PointerModifiedDataType.h"
|
||||
#include "data/type/ReferenceModifiedDataType.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
CxxTypeNameResolver::CxxTypeNameResolver()
|
||||
: CxxNameResolver(std::vector<const clang::Decl*>())
|
||||
{
|
||||
}
|
||||
|
||||
CxxTypeNameResolver::CxxTypeNameResolver(std::vector<const clang::Decl*> ignoredContextDecls)
|
||||
: CxxNameResolver(ignoredContextDecls)
|
||||
{
|
||||
}
|
||||
|
||||
CxxTypeNameResolver::~CxxTypeNameResolver()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<DataType> CxxTypeNameResolver::qualTypeToDataType(clang::QualType qualType)
|
||||
{
|
||||
std::shared_ptr<DataType> dataType = typeToDataType(qualType.getTypePtr());
|
||||
if (qualType.isConstQualified())
|
||||
{
|
||||
dataType->addQualifier(DataType::QUALIFIER_CONST);
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
||||
std::shared_ptr<DataType> CxxTypeNameResolver::typeToDataType(const clang::Type* type)
|
||||
{
|
||||
std::shared_ptr<DataType> dataType;
|
||||
|
||||
switch (type->getTypeClass())
|
||||
{
|
||||
case clang::Type::Paren:
|
||||
{
|
||||
dataType = qualTypeToDataType(type->getAs<clang::ParenType>()->getInnerType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Typedef:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(type->getAs<clang::TypedefType>()->getDecl(), getIgnoredContextDecls());
|
||||
dataType = std::make_shared<NamedDataType>(declNameResolver.getDeclNameHierarchy());
|
||||
break;
|
||||
}
|
||||
case clang::Type::MemberPointer:
|
||||
{
|
||||
// test this case!
|
||||
}
|
||||
case clang::Type::Pointer:
|
||||
{
|
||||
std::shared_ptr<DataType> innerType = qualTypeToDataType(type->getPointeeType());
|
||||
dataType = std::make_shared<PointerModifiedDataType>(innerType);
|
||||
break;
|
||||
}
|
||||
case clang::Type::ConstantArray:
|
||||
case clang::Type::DependentSizedArray:
|
||||
case clang::Type::IncompleteArray:
|
||||
case clang::Type::VariableArray:
|
||||
{
|
||||
std::shared_ptr<DataType> innerType = qualTypeToDataType(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
|
||||
dataType = std::make_shared<ArrayModifiedDataType>(innerType);
|
||||
break;
|
||||
}
|
||||
case clang::Type::LValueReference:
|
||||
case clang::Type::RValueReference:
|
||||
{
|
||||
std::shared_ptr<DataType> innerType = qualTypeToDataType(type->getPointeeType());
|
||||
dataType = std::make_shared<ReferenceModifiedDataType>(innerType);
|
||||
break;
|
||||
}
|
||||
case clang::Type::Elaborated:
|
||||
{
|
||||
dataType = qualTypeToDataType(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Enum:
|
||||
case clang::Type::Record:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(type->getAs<clang::TagType>()->getDecl(), getIgnoredContextDecls());
|
||||
dataType = std::make_shared<NamedDataType>(declNameResolver.getDeclNameHierarchy());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Builtin:
|
||||
{
|
||||
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 = type->getAs<clang::BuiltinType>()->getName(pp);
|
||||
|
||||
NameHierarchy typeNameHerarchy;
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>(typeName));
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateSpecialization:
|
||||
{
|
||||
NameHierarchy typeNameHerarchy;
|
||||
|
||||
const clang::TagType* tagType = type->getAs<clang::TagType>(); // remove this case when NameHierarchy is split into namepart and parameter part
|
||||
if (tagType)
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(tagType->getDecl(), getIgnoredContextDecls());
|
||||
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
|
||||
}
|
||||
else // specialization of a template template parameter (no concrete class) important, may help: has no underlying decl!
|
||||
{
|
||||
const clang::TemplateSpecializationType* templateSpecializationType = type->getAs<clang::TemplateSpecializationType>();
|
||||
CxxDeclNameResolver declNameResolver(templateSpecializationType->getTemplateName().getAsTemplateDecl(), getIgnoredContextDecls());
|
||||
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
|
||||
|
||||
if (typeNameHerarchy.size() > 0)
|
||||
{
|
||||
std::string templateArgumentNamePart = "<";
|
||||
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
|
||||
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
|
||||
{
|
||||
templateArgumentNamePart += resolver.getTemplateArgumentName(templateSpecializationType->getArg(i));
|
||||
if (i + 1 < templateSpecializationType->getNumArgs())
|
||||
templateArgumentNamePart += ", ";
|
||||
}
|
||||
templateArgumentNamePart += ">";
|
||||
|
||||
std::string declName = typeNameHerarchy.back()->getName();
|
||||
declName = declName.substr(0, declName.rfind("<")); // remove template parameters
|
||||
declName += templateArgumentNamePart; // add template arguments
|
||||
typeNameHerarchy.pop();
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>(declName)); // templateSpecialization has no signature.
|
||||
}
|
||||
}
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateTypeParm:
|
||||
{
|
||||
clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl();
|
||||
|
||||
CxxDeclNameResolver declNameResolver(templateTypeParmDecl, getIgnoredContextDecls());
|
||||
NameHierarchy typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
case clang::Type::SubstTemplateTypeParm:
|
||||
{
|
||||
dataType = qualTypeToDataType(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::DependentName:
|
||||
{
|
||||
const clang::DependentNameType* dependentNameType = clang::dyn_cast<clang::DependentNameType>(type);
|
||||
|
||||
NameHierarchy typeNameHerarchy = getNameHierarchy(dependentNameType->getQualifier());
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>(dependentNameType->getIdentifier()->getName().str()));
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
case clang::Type::PackExpansion:
|
||||
{
|
||||
const clang::PackExpansionType* packExpansionType = clang::dyn_cast<clang::PackExpansionType>(type);
|
||||
dataType = qualTypeToDataType(packExpansionType->getPattern());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Auto:
|
||||
{
|
||||
clang::QualType deducedType = clang::dyn_cast<clang::AutoType>(type)->getDeducedType();
|
||||
if (!deducedType.isNull())
|
||||
{
|
||||
dataType = qualTypeToDataType(deducedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
NameHierarchy typeNameHerarchy;
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>("auto"));
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::Decltype:
|
||||
{
|
||||
const clang::DecltypeType* decltypeType = clang::dyn_cast<clang::DecltypeType>(type);
|
||||
dataType = qualTypeToDataType(decltypeType->getUnderlyingType());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::string typeClassName = type->getTypeClassName();
|
||||
LOG_INFO(std::string("Unhandled kind of type encountered: ") + typeClassName);
|
||||
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"
|
||||
|
||||
clang::SmallString<64> Buf;
|
||||
llvm::raw_svector_ostream StrOS(Buf);
|
||||
clang::QualType::print(type, clang::Qualifiers(), StrOS, pp, clang::Twine());
|
||||
std::string typeName = StrOS.str();
|
||||
|
||||
NameHierarchy typeNameHerarchy;
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>(typeName));
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
||||
NameHierarchy CxxTypeNameResolver::getTypeNameHierarchy(const clang::Type* type)
|
||||
{
|
||||
return typeToDataType(type)->getTypeNameHierarchy();
|
||||
}
|
||||
|
||||
NameHierarchy CxxTypeNameResolver::getNameHierarchy(const clang::NestedNameSpecifier* nestedNameSpecifier)
|
||||
{
|
||||
clang::NestedNameSpecifier::SpecifierKind nnsKind = nestedNameSpecifier->getKind();
|
||||
NameHierarchy typeNameHerarchy;
|
||||
switch (nnsKind)
|
||||
{
|
||||
case clang::NestedNameSpecifier::Identifier:
|
||||
{
|
||||
const clang::NestedNameSpecifier* prefix = nestedNameSpecifier->getPrefix();
|
||||
if (prefix)
|
||||
{
|
||||
typeNameHerarchy = getNameHierarchy(prefix);
|
||||
}
|
||||
typeNameHerarchy.push(std::make_shared<NameElement>(nestedNameSpecifier->getAsIdentifier()->getName()));
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Namespace:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(nestedNameSpecifier->getAsNamespace(), getIgnoredContextDecls());
|
||||
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::NamespaceAlias:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(nestedNameSpecifier->getAsNamespaceAlias(), getIgnoredContextDecls());
|
||||
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::TypeSpec:
|
||||
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
typeNameHerarchy = typeToDataType(nestedNameSpecifier->getAsType())->getTypeNameHierarchy();
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Global:
|
||||
// no context name hierarchy needed.
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Super:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(nestedNameSpecifier->getAsRecordDecl(), getIgnoredContextDecls());
|
||||
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return typeNameHerarchy;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CXX_TYPE_NAME_RESOLVER_H
|
||||
#define CXX_TYPE_NAME_RESOLVER_H
|
||||
|
||||
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
|
||||
#include "data/type/DataType.h"
|
||||
|
||||
class CxxTypeNameResolver: public CxxNameResolver
|
||||
{
|
||||
public:
|
||||
CxxTypeNameResolver();
|
||||
CxxTypeNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
|
||||
virtual ~CxxTypeNameResolver();
|
||||
|
||||
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType);
|
||||
NameHierarchy getTypeNameHierarchy(const clang::Type* type);
|
||||
|
||||
private:
|
||||
std::shared_ptr<DataType> typeToDataType(const clang::Type* type);
|
||||
NameHierarchy getNameHierarchy(const clang::NestedNameSpecifier* nestedNameSpecifier);
|
||||
};
|
||||
|
||||
#endif // CXX_TYPE_NAME_RESOLVER_H
|
||||
Reference in New Issue
Block a user