logic: indexer and name resolving fixes
* made header and excluded filepaths of filemanager canonical * implemented solving Attributed- and InjectedClassNameType * handled clang returning null objects in NameResolvers
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "data/StorageProvider.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
int StorageProvider::getStorageCount() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
@@ -57,5 +59,18 @@ std::shared_ptr<IntermediateStorage> StorageProvider::popInjectionSource()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StorageProvider::logCurrentState() const
|
||||
{
|
||||
std::string logString = "Storages waiting for injection:";
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
for (std::shared_ptr<IntermediateStorage> storage: m_storages)
|
||||
{
|
||||
logString += " " + std::to_string(storage->getSourceLocationCount()) + ";";
|
||||
}
|
||||
}
|
||||
LOG_INFO(logString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
// returns empty shared_ptr if no storages available
|
||||
std::shared_ptr<IntermediateStorage> popInjectionSource();
|
||||
|
||||
void logCurrentState() const;
|
||||
|
||||
private:
|
||||
std::list<std::shared_ptr<IntermediateStorage>> m_storages; // larger storages are in front
|
||||
mutable std::mutex m_storagesMutex;
|
||||
|
||||
@@ -27,8 +27,8 @@ void FileManager::setPaths(
|
||||
std::vector<std::string> sourceExtensions
|
||||
){
|
||||
m_sourcePaths = sourcePaths;
|
||||
m_headerPaths = headerPaths;
|
||||
m_excludePaths = excludePaths;
|
||||
m_headerPaths = makeCanonical(headerPaths);
|
||||
m_excludePaths = makeCanonical(excludePaths);
|
||||
m_sourceExtensions = sourceExtensions;
|
||||
}
|
||||
|
||||
@@ -159,6 +159,16 @@ const FileInfo FileManager::getFileInfo(const FilePath& filePath) const
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::vector<FilePath> FileManager::makeCanonical(const std::vector<FilePath>& filePaths)
|
||||
{
|
||||
std::vector<FilePath> ret;
|
||||
for (const FilePath filePath: filePaths)
|
||||
{
|
||||
ret.push_back(filePath.canonical());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FileManager::isExcluded(const FilePath& filePath) const
|
||||
{
|
||||
for (FilePath path : m_excludePaths)
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
virtual const FileInfo getFileInfo(const FilePath& filePath) const;
|
||||
|
||||
private:
|
||||
std::vector<FilePath> makeCanonical(const std::vector<FilePath>& filePaths);
|
||||
bool isExcluded(const FilePath& filePath) const;
|
||||
|
||||
std::map<FilePath, FileInfo> m_files;
|
||||
|
||||
@@ -1215,6 +1215,7 @@ bool CxxAstVisitor::checkIgnoresTypeLoc(const clang::TypeLoc& tl)
|
||||
(!tl.getAs<clang::TypedefTypeLoc>().isNull()) ||
|
||||
(!tl.getAs<clang::TemplateTypeParmTypeLoc>().isNull()) ||
|
||||
(!tl.getAs<clang::TemplateSpecializationTypeLoc>().isNull()) ||
|
||||
(!tl.getAs<clang::InjectedClassNameTypeLoc>().isNull()) ||
|
||||
(!tl.getAs<clang::DependentNameTypeLoc>().isNull()) ||
|
||||
(!tl.getAs<clang::DependentTemplateSpecializationTypeLoc>().isNull()) ||
|
||||
(!tl.getAs<clang::BuiltinTypeLoc>().isNull()) ||
|
||||
|
||||
@@ -44,7 +44,7 @@ NameHierarchy CxxFunctionDeclName::toNameHierarchy() const
|
||||
{
|
||||
signaturePrefix += "static ";
|
||||
}
|
||||
signaturePrefix += m_returnTypeName->toString();
|
||||
signaturePrefix += CxxTypeName::makeUnsolvedIfNull(m_returnTypeName)->toString();
|
||||
|
||||
std::string signaturePostfix = "(";
|
||||
for (size_t i = 0; i < m_parameterTypeNames.size(); i++)
|
||||
@@ -53,7 +53,7 @@ NameHierarchy CxxFunctionDeclName::toNameHierarchy() const
|
||||
{
|
||||
signaturePostfix += ", ";
|
||||
}
|
||||
signaturePostfix += m_parameterTypeNames[i]->toString();
|
||||
signaturePostfix += CxxTypeName::makeUnsolvedIfNull(m_parameterTypeNames[i])->toString();
|
||||
}
|
||||
signaturePostfix += ")";
|
||||
if (m_isConst)
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
#include "data/parser/cxx/name/CxxTypeName.h"
|
||||
|
||||
std::shared_ptr<CxxTypeName> CxxTypeName::makeUnsolvedIfNull(std::shared_ptr<CxxTypeName> name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
return std::make_shared<CxxTypeName>(
|
||||
"unsolved-type", std::vector<std::string>()
|
||||
);
|
||||
}
|
||||
|
||||
CxxTypeName::Modifier::Modifier(std::string symbol)
|
||||
: symbol(symbol)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
class CxxTypeName: public CxxName
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<CxxTypeName> makeUnsolvedIfNull(std::shared_ptr<CxxTypeName> name);
|
||||
|
||||
struct Modifier
|
||||
{
|
||||
Modifier(std::string symbol);
|
||||
|
||||
@@ -38,13 +38,15 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl
|
||||
}
|
||||
}
|
||||
|
||||
if ((clang::isa<clang::CXXRecordDecl>(declaration)) &&
|
||||
std::shared_ptr<CxxDeclName> declName;
|
||||
|
||||
if ((declaration) &&
|
||||
(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)
|
||||
{
|
||||
declName = getDeclName(clang::dyn_cast<const clang::NamedDecl>(declaration));
|
||||
@@ -89,195 +91,198 @@ std::shared_ptr<CxxName> CxxDeclNameResolver::getContextName(const clang::DeclCo
|
||||
|
||||
std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
|
||||
{
|
||||
ScopedSwitcher<const clang::NamedDecl*> switcher(m_currentDecl, declaration);
|
||||
if (declaration)
|
||||
{
|
||||
ScopedSwitcher<const clang::NamedDecl*> switcher(m_currentDecl, 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)
|
||||
std::string declNameString = declaration->getNameAsString();
|
||||
if (const clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast_or_null<clang::TypeAliasDecl>(declaration))
|
||||
{
|
||||
return getDeclName(templatedDeclaration);
|
||||
}
|
||||
}
|
||||
if (const clang::RecordDecl* recordDecl = clang::dyn_cast_or_null<clang::RecordDecl>(declaration))
|
||||
{
|
||||
if (recordDecl->isLambda())
|
||||
{
|
||||
// we skip this node because its child (the lambda call operator) has already been recorded.
|
||||
return std::shared_ptr<CxxDeclName>();
|
||||
}
|
||||
else if (declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
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)
|
||||
clang::TypeAliasTemplateDecl* templatedDeclaration = typeAliasDecl->getDescribedAliasTemplate();
|
||||
if (templatedDeclaration)
|
||||
{
|
||||
return getDeclName(templateClassDeclaration);
|
||||
return getDeclName(templatedDeclaration);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(declaration))
|
||||
}
|
||||
if (const clang::RecordDecl* recordDecl = clang::dyn_cast_or_null<clang::RecordDecl>(declaration))
|
||||
{
|
||||
if (recordDecl->isLambda())
|
||||
{
|
||||
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++)
|
||||
// we skip this node because its child (the lambda call operator) has already been recorded.
|
||||
return std::shared_ptr<CxxDeclName>();
|
||||
}
|
||||
else if (declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
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)
|
||||
{
|
||||
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.
|
||||
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++)
|
||||
{
|
||||
if(currentParameterIndex < parameterList->size())
|
||||
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.
|
||||
{
|
||||
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(currentParameterIndex)));
|
||||
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
|
||||
{
|
||||
//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));
|
||||
templateParameters.push_back(getTemplateArgumentName(templateArgument));
|
||||
}
|
||||
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++)
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
|
||||
}
|
||||
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
|
||||
{
|
||||
templateArguments.push_back(getTemplateArgumentName(templateArgumentList.get(i)));
|
||||
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);
|
||||
}
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
{
|
||||
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
{
|
||||
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
|
||||
|
||||
std::string functionName = declNameString;
|
||||
std::vector<std::string> templateArguments;
|
||||
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()))
|
||||
if ((clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)) &&
|
||||
(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->isLambda()))
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->getLocStart());
|
||||
functionName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
|
||||
}
|
||||
else if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
|
||||
{
|
||||
std::shared_ptr<CxxDeclName> templateDeclName = getDeclName(templateFunctionDeclaration);
|
||||
functionName = templateDeclName->getName();
|
||||
templateArguments = templateDeclName->getTemplateParameterNames();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (functionDecl->isFunctionTemplateSpecialization())
|
||||
{
|
||||
const clang::TemplateArgumentList* templateArgumentList = functionDecl->getTemplateSpecializationArgs();
|
||||
for (size_t i = 0; i < templateArgumentList->size(); i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
|
||||
templateArguments.push_back(getTemplateArgumentName(templateArgument));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::shared_ptr<CxxTypeName> returnTypeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->getReturnType()));
|
||||
|
||||
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames;
|
||||
for (unsigned int i = 0; i < functionDecl->param_size(); i++)
|
||||
{
|
||||
parameterTypeNames.push_back(CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->parameters()[i]->getType())));
|
||||
}
|
||||
|
||||
return std::make_shared<CxxFunctionDeclName>(
|
||||
functionName,
|
||||
templateArguments,
|
||||
returnTypeName,
|
||||
parameterTypeNames,
|
||||
isConst,
|
||||
isStatic
|
||||
);
|
||||
}
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
|
||||
{
|
||||
std::vector<std::string> templateParameters;
|
||||
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(i)));
|
||||
}
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
|
||||
}
|
||||
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(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->getLocStart());
|
||||
functionName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("namespace", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
else if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
|
||||
else if (clang::isa<clang::EnumDecl>(declaration) && declNameString.size() == 0)
|
||||
{
|
||||
std::shared_ptr<CxxDeclName> templateDeclName = getDeclName(templateFunctionDeclaration);
|
||||
functionName = templateDeclName->getName();
|
||||
templateArguments = templateDeclName->getTemplateParameterNames();
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("enum", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
else
|
||||
else if (
|
||||
(
|
||||
clang::isa<clang::TemplateTypeParmDecl>(declaration) ||
|
||||
clang::isa<clang::NonTypeTemplateParmDecl>(declaration) ||
|
||||
clang::isa<clang::TemplateTemplateParmDecl>(declaration)
|
||||
) && declNameString.size() == 0)
|
||||
{
|
||||
if (functionDecl->isFunctionTemplateSpecialization())
|
||||
{
|
||||
const clang::TemplateArgumentList* templateArgumentList = functionDecl->getTemplateSpecializationArgs();
|
||||
for (size_t i = 0; i < templateArgumentList->size(); i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
|
||||
templateArguments.push_back(getTemplateArgumentName(templateArgument));
|
||||
}
|
||||
}
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("template parameter", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
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<CxxDeclName>(getNameForAnonymousSymbol("parameter", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
|
||||
bool isStatic = false;
|
||||
bool isConst = false;
|
||||
|
||||
if (clang::isa<clang::CXXMethodDecl>(declaration))
|
||||
if (declNameString.size() > 0)
|
||||
{
|
||||
const clang::CXXMethodDecl* methodDecl = clang::dyn_cast<const clang::CXXMethodDecl>(declaration);
|
||||
isStatic = methodDecl->isStatic();
|
||||
isConst = methodDecl->isConst();
|
||||
return std::make_shared<CxxDeclName>(declNameString, std::vector<std::string>(), std::shared_ptr<CxxName>());
|
||||
}
|
||||
else
|
||||
{
|
||||
isStatic = functionDecl->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
|
||||
CxxTypeNameResolver typenNameResolver(getIgnoredContextDecls());
|
||||
typenNameResolver.ignoreContextDecl(functionDecl);
|
||||
std::shared_ptr<CxxTypeName> returnTypeName = typenNameResolver.getName(functionDecl->getReturnType());
|
||||
|
||||
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames;
|
||||
for (unsigned int i = 0; i < functionDecl->param_size(); i++)
|
||||
{
|
||||
parameterTypeNames.push_back(typenNameResolver.getName(functionDecl->parameters()[i]->getType()));
|
||||
}
|
||||
|
||||
return std::make_shared<CxxFunctionDeclName>(
|
||||
functionName,
|
||||
templateArguments,
|
||||
returnTypeName,
|
||||
parameterTypeNames,
|
||||
isConst,
|
||||
isStatic
|
||||
);
|
||||
}
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
|
||||
{
|
||||
std::vector<std::string> templateParameters;
|
||||
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(i)));
|
||||
}
|
||||
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
|
||||
}
|
||||
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<CxxDeclName>(getNameForAnonymousSymbol("namespace", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
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<CxxDeclName>(getNameForAnonymousSymbol("enum", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
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<CxxDeclName>(getNameForAnonymousSymbol("template parameter", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
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<CxxDeclName>(getNameForAnonymousSymbol("parameter", presumedBegin), std::vector<std::string>());
|
||||
}
|
||||
|
||||
if (declNameString.size() > 0)
|
||||
{
|
||||
return std::make_shared<CxxDeclName>(declNameString, std::vector<std::string>(), std::shared_ptr<CxxName>());
|
||||
}
|
||||
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
@@ -300,27 +305,30 @@ std::string CxxDeclNameResolver::getTemplateParameterString(const clang::NamedDe
|
||||
{
|
||||
std::string templateParameterTypeString = "";
|
||||
|
||||
clang::Decl::Kind templateParameterKind = parameter->getKind();
|
||||
switch (templateParameterKind)
|
||||
if (parameter)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
std::string parameterName = parameter->getName();
|
||||
if (!parameterName.empty())
|
||||
{
|
||||
templateParameterTypeString += " " + parameterName;
|
||||
}
|
||||
}
|
||||
return templateParameterTypeString;
|
||||
}
|
||||
@@ -340,15 +348,8 @@ std::string CxxDeclNameResolver::getTemplateParameterTypeString(const clang::Non
|
||||
|
||||
std::string typeString = "";
|
||||
|
||||
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");
|
||||
}
|
||||
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(parameter->getType()));
|
||||
typeString = typeName->toString();
|
||||
|
||||
if (parameter->isTemplateParameterPack())
|
||||
{
|
||||
|
||||
@@ -24,58 +24,58 @@ CxxSpecifierNameResolver::~CxxSpecifierNameResolver()
|
||||
std::shared_ptr<CxxName> CxxSpecifierNameResolver::getName(const clang::NestedNameSpecifier* nestedNameSpecifier)
|
||||
{
|
||||
std::shared_ptr<CxxName> name;
|
||||
if (!nestedNameSpecifier)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
clang::NestedNameSpecifier::SpecifierKind nnsKind = nestedNameSpecifier->getKind();
|
||||
switch (nnsKind)
|
||||
if (nestedNameSpecifier)
|
||||
{
|
||||
case clang::NestedNameSpecifier::Identifier:
|
||||
clang::NestedNameSpecifier::SpecifierKind nnsKind = nestedNameSpecifier->getKind();
|
||||
switch (nnsKind)
|
||||
{
|
||||
name = std::make_shared<CxxDeclName>(
|
||||
nestedNameSpecifier->getAsIdentifier()->getName(), std::vector<std::string>()
|
||||
);
|
||||
|
||||
if (const clang::NestedNameSpecifier* prefix = nestedNameSpecifier->getPrefix())
|
||||
case clang::NestedNameSpecifier::Identifier:
|
||||
{
|
||||
std::shared_ptr<CxxName> parentName = getName(prefix);
|
||||
if (parentName)
|
||||
name = std::make_shared<CxxDeclName>(
|
||||
nestedNameSpecifier->getAsIdentifier()->getName(), std::vector<std::string>()
|
||||
);
|
||||
|
||||
if (const clang::NestedNameSpecifier* prefix = nestedNameSpecifier->getPrefix())
|
||||
{
|
||||
name->setParent(parentName);
|
||||
std::shared_ptr<CxxName> parentName = getName(prefix);
|
||||
if (parentName)
|
||||
{
|
||||
name->setParent(parentName);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Namespace:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespace());
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::NamespaceAlias:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespaceAlias());
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::TypeSpec:
|
||||
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
{
|
||||
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
|
||||
name = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(nestedNameSpecifier->getAsType()));
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Global:
|
||||
// no context name hierarchy needed.
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Super:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
name = declNameResolver.getName(nestedNameSpecifier->getAsRecordDecl());
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Namespace:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespace());
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::NamespaceAlias:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespaceAlias());
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::TypeSpec:
|
||||
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
{
|
||||
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
|
||||
name = typeNameResolver.getName(nestedNameSpecifier->getAsType());
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Global:
|
||||
// no context name hierarchy needed.
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Super:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
name = declNameResolver.getName(nestedNameSpecifier->getAsRecordDecl());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -30,16 +30,8 @@ std::string CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clang
|
||||
case clang::TemplateArgument::Type:
|
||||
{
|
||||
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
|
||||
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;
|
||||
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(argument.getAsType()));
|
||||
return typeName->toString();
|
||||
}
|
||||
case clang::TemplateArgument::Integral:
|
||||
case clang::TemplateArgument::Null:
|
||||
|
||||
@@ -37,244 +37,266 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
|
||||
{
|
||||
std::shared_ptr<CxxTypeName> typeName;
|
||||
|
||||
switch (type->getTypeClass())
|
||||
if (type)
|
||||
{
|
||||
case clang::Type::Paren:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::ParenType>()->getInnerType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Typedef:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TypedefType>()->getDecl());
|
||||
if (declName)
|
||||
switch (type->getTypeClass())
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::MemberPointer:
|
||||
case clang::Type::Pointer:
|
||||
{
|
||||
typeName = getName(type->getPointeeType());
|
||||
typeName->addModifier(CxxTypeName::Modifier("*"));
|
||||
break;
|
||||
}
|
||||
case clang::Type::ConstantArray:
|
||||
case clang::Type::DependentSizedArray:
|
||||
case clang::Type::IncompleteArray:
|
||||
case clang::Type::VariableArray:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
|
||||
typeName->addModifier(CxxTypeName::Modifier("[]"));
|
||||
break;
|
||||
}
|
||||
case clang::Type::LValueReference:
|
||||
case clang::Type::RValueReference:
|
||||
{
|
||||
typeName = getName(type->getPointeeType());
|
||||
typeName->addModifier(CxxTypeName::Modifier("&"));
|
||||
break;
|
||||
}
|
||||
case clang::Type::Elaborated:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Enum:
|
||||
case clang::Type::Record:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TagType>()->getDecl());
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
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"
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
type->getAs<clang::BuiltinType>()->getName(pp), std::vector<std::string>()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateSpecialization:
|
||||
{
|
||||
const clang::TagType* tagType = type->getAs<clang::TagType>(); // remove this case when NameHierarchy is split into namepart and parameter part
|
||||
if (tagType)
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(tagType->getDecl());
|
||||
if (declName)
|
||||
case clang::Type::Paren:
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
typeName = getName(type->getAs<clang::ParenType>()->getInnerType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
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(getIgnoredContextDecls());
|
||||
const std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(templateSpecializationType->getTemplateName().getAsTemplateDecl());
|
||||
|
||||
if (declName)
|
||||
case clang::Type::Attributed:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::AttributedType>()->getModifiedType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::InjectedClassName:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::InjectedClassNameType>()->getInjectedSpecializationType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Typedef:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TypedefType>()->getDecl());
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
std::vector<std::string>(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::MemberPointer:
|
||||
case clang::Type::Pointer:
|
||||
{
|
||||
typeName = getName(type->getPointeeType());
|
||||
if (typeName)
|
||||
{
|
||||
typeName->addModifier(CxxTypeName::Modifier("*"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::ConstantArray:
|
||||
case clang::Type::DependentSizedArray:
|
||||
case clang::Type::IncompleteArray:
|
||||
case clang::Type::VariableArray:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
|
||||
if (typeName)
|
||||
{
|
||||
typeName->addModifier(CxxTypeName::Modifier("[]"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::LValueReference:
|
||||
case clang::Type::RValueReference:
|
||||
{
|
||||
typeName = getName(type->getPointeeType());
|
||||
if (typeName)
|
||||
{
|
||||
typeName->addModifier(CxxTypeName::Modifier("&"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::Elaborated:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Enum:
|
||||
case clang::Type::Record:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TagType>()->getDecl());
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(), // contains template arguments if decl is a template specialization
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
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"
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
type->getAs<clang::BuiltinType>()->getName(pp), std::vector<std::string>()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateSpecialization:
|
||||
{
|
||||
const clang::TagType* tagType = type->getAs<clang::TagType>(); // remove this case when NameHierarchy is split into namepart and parameter part
|
||||
if (tagType)
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(tagType->getDecl());
|
||||
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!
|
||||
{
|
||||
const clang::TemplateSpecializationType* templateSpecializationType = type->getAs<clang::TemplateSpecializationType>();
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
const std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(templateSpecializationType->getTemplateName().getAsTemplateDecl());
|
||||
|
||||
if (declName)
|
||||
{
|
||||
std::vector<std::string> templateArguments;
|
||||
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
|
||||
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
|
||||
{
|
||||
templateArguments.push_back(resolver.getTemplateArgumentName(templateSpecializationType->getArg(i)));
|
||||
}
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
templateArguments,
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("no decl found");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateTypeParm:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl());
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::SubstTemplateTypeParm:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::DependentName:
|
||||
{
|
||||
const clang::DependentNameType* dependentType = clang::dyn_cast<clang::DependentNameType>(type);
|
||||
|
||||
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentType->getQualifier());
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
dependentType->getIdentifier()->getName().str(), std::vector<std::string>(), specifierName
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::DependentTemplateSpecialization:
|
||||
{
|
||||
const clang::DependentTemplateSpecializationType* dependentType = clang::dyn_cast<clang::DependentTemplateSpecializationType>(type);
|
||||
|
||||
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentType->getQualifier());
|
||||
|
||||
std::vector<std::string> templateArguments;
|
||||
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
|
||||
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
|
||||
for (size_t i = 0; i < dependentType->getNumArgs(); i++)
|
||||
{
|
||||
templateArguments.push_back(resolver.getTemplateArgumentName(templateSpecializationType->getArg(i)));
|
||||
templateArguments.push_back(resolver.getTemplateArgumentName(dependentType->getArg(i)));
|
||||
}
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
templateArguments,
|
||||
declName->getParent()
|
||||
dependentType->getIdentifier()->getName().str(), templateArguments, specifierName
|
||||
);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case clang::Type::PackExpansion:
|
||||
{
|
||||
LOG_WARNING("no decl found");
|
||||
typeName = getName(clang::dyn_cast<clang::PackExpansionType>(type)->getPattern());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateTypeParm:
|
||||
{
|
||||
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl());
|
||||
if (declName)
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
declName->getName(),
|
||||
declName->getTemplateParameterNames(),
|
||||
declName->getParent()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::SubstTemplateTypeParm:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::DependentName:
|
||||
{
|
||||
const clang::DependentNameType* dependentType = clang::dyn_cast<clang::DependentNameType>(type);
|
||||
|
||||
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentType->getQualifier());
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
dependentType->getIdentifier()->getName().str(), std::vector<std::string>(), specifierName
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::DependentTemplateSpecialization:
|
||||
{
|
||||
const clang::DependentTemplateSpecializationType* dependentType = clang::dyn_cast<clang::DependentTemplateSpecializationType>(type);
|
||||
|
||||
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
|
||||
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentType->getQualifier());
|
||||
|
||||
std::vector<std::string> templateArguments;
|
||||
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
|
||||
for (size_t i = 0; i < dependentType->getNumArgs(); i++)
|
||||
{
|
||||
templateArguments.push_back(resolver.getTemplateArgumentName(dependentType->getArg(i)));
|
||||
}
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
dependentType->getIdentifier()->getName().str(), templateArguments, specifierName
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::PackExpansion:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::PackExpansionType>(type)->getPattern());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Auto:
|
||||
{
|
||||
clang::QualType deducedType = clang::dyn_cast<clang::AutoType>(type)->getDeducedType();
|
||||
if (!deducedType.isNull())
|
||||
{
|
||||
typeName = getName(deducedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
"auto", std::vector<std::string>()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::Decltype:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::DecltypeType>(type)->getUnderlyingType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::FunctionProto:
|
||||
{
|
||||
const clang::FunctionProtoType* protoType = clang::dyn_cast<clang::FunctionProtoType>(type);
|
||||
std::string nameString = getName(protoType->getReturnType())->toString();
|
||||
nameString += "(";
|
||||
for (size_t i = 0; i < protoType->getNumParams(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
case clang::Type::Auto:
|
||||
{
|
||||
nameString += ", ";
|
||||
clang::QualType deducedType = clang::dyn_cast<clang::AutoType>(type)->getDeducedType();
|
||||
if (!deducedType.isNull())
|
||||
{
|
||||
typeName = getName(deducedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
"auto", std::vector<std::string>()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case clang::Type::Decltype:
|
||||
{
|
||||
typeName = getName(clang::dyn_cast<clang::DecltypeType>(type)->getUnderlyingType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::FunctionProto:
|
||||
{
|
||||
const clang::FunctionProtoType* protoType = clang::dyn_cast<clang::FunctionProtoType>(type);
|
||||
std::string nameString = CxxTypeName::makeUnsolvedIfNull(getName(protoType->getReturnType()))->toString();
|
||||
nameString += "(";
|
||||
for (size_t i = 0; i < protoType->getNumParams(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
nameString += ", ";
|
||||
}
|
||||
nameString += CxxTypeName::makeUnsolvedIfNull(getName(protoType->getParamType(i)))->toString();
|
||||
}
|
||||
nameString += ")";
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
nameString, std::vector<std::string>()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::Adjusted:
|
||||
case clang::Type::Decayed:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::AdjustedType>()->getOriginalType());
|
||||
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 nameString = StrOS.str();
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
nameString, std::vector<std::string>()
|
||||
);
|
||||
break;
|
||||
}
|
||||
nameString += getName(protoType->getParamType(i))->toString();
|
||||
}
|
||||
nameString += ")";
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
nameString, std::vector<std::string>()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case clang::Type::Adjusted:
|
||||
case clang::Type::Decayed:
|
||||
{
|
||||
typeName = getName(type->getAs<clang::AdjustedType>()->getOriginalType());
|
||||
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 nameString = StrOS.str();
|
||||
|
||||
typeName = std::make_shared<CxxTypeName>(
|
||||
nameString, std::vector<std::string>()
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
@@ -1296,11 +1296,6 @@ public:
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void test_cxx_parser_finds_type_usage_of_global_variable()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
@@ -2030,6 +2025,24 @@ public:
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_usage_of_injected_type_in_method_declaration()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"template <typename T>\n"
|
||||
"class Foo\n"
|
||||
"{\n"
|
||||
" Foo& operator=(const Foo&) = delete;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->typeUses, "Foo<Foo<typename T>::T> & Foo<typename T>::operator=(const Foo<Foo<typename T>::T> &) -> Foo<Foo<typename T>::T> <4:2 4:4>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->typeUses, "Foo<Foo<typename T>::T> & Foo<typename T>::operator=(const Foo<Foo<typename T>::T> &) -> Foo<Foo<typename T>::T> <4:23 4:25>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_use_of_qualified_type_in_function()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
|
||||
Reference in New Issue
Block a user