cxx: Improved performance of CxxAstVisitor, CxxNameResolver and CxxName types

* use unique_ptr for CxxName handling
* create CxxNameResolver from other
* improved string handling in CxxName types
* only traverse decls within projects
* use macro in ast visitor to call into each component instead of virtual calls
* improved CxxName caching performance
* refactored CxxNameResolver classes to use less locals
This commit is contained in:
Eberhard Graether
2018-09-21 14:48:51 +02:00
parent 513988e51b
commit 56dcddfb83
43 changed files with 752 additions and 1236 deletions
+5
View File
@@ -100,3 +100,8 @@ const NameElement::Signature& NameElement::getSignature()
{
return m_signature;
}
void NameElement::setSignature(std::wstring prefix, std::wstring postfix)
{
m_signature = Signature(std::move(prefix), std::move(postfix));
}
+5 -3
View File
@@ -24,8 +24,8 @@ public:
std::wstring getParameterString() const;
private:
const std::wstring m_prefix;
const std::wstring m_postfix;
std::wstring m_prefix;
std::wstring m_postfix;
};
NameElement(std::wstring name);
@@ -35,12 +35,14 @@ public:
const std::wstring& getName() const;
std::wstring getNameWithSignature() const;
std::wstring getNameWithSignatureParameters() const;
bool hasSignature() const;
const Signature& getSignature();
void setSignature(std::wstring prefix, std::wstring postfix);
private:
const std::wstring m_name;
const Signature m_signature;
Signature m_signature;
};
#endif // NAME_ELEMENT_H
+2 -2
View File
@@ -30,7 +30,7 @@ OrderedCache<KeyType, ValType>::OrderedCache(std::function<ValType(const KeyType
template <typename KeyType, typename ValType>
ValType OrderedCache<KeyType, ValType>::getValue(const KeyType& key)
{
typename std::map<KeyType, ValType>::const_iterator it = m_map.find(key);
auto it = m_map.find(key);
if (it != m_map.end())
{
++m_hitCount;
@@ -38,7 +38,7 @@ ValType OrderedCache<KeyType, ValType>::getValue(const KeyType& key)
}
++m_missCount;
ValType val = m_calculator(key);
m_map.insert(std::pair<KeyType, ValType>(key, val));
m_map.emplace(key, val);
return val;
}
+2 -2
View File
@@ -30,7 +30,7 @@ UnorderedCache<KeyType, ValType, Hasher>::UnorderedCache(std::function<ValType(c
template <typename KeyType, typename ValType, typename Hasher>
ValType UnorderedCache<KeyType, ValType, Hasher>::getValue(const KeyType& key)
{
typename std::unordered_map<KeyType, ValType, Hasher>::const_iterator it = m_map.find(key);
auto it = m_map.find(key);
if (it != m_map.end())
{
++m_hitCount;
@@ -38,7 +38,7 @@ ValType UnorderedCache<KeyType, ValType, Hasher>::getValue(const KeyType& key)
}
++m_missCount;
ValType val = m_calculator(key);
m_map.insert(std::pair<KeyType, ValType>(key, val));
m_map.emplace(key, val);
return val;
}
+87 -210
View File
@@ -7,13 +7,6 @@
#include "CxxTypeNameResolver.h"
#include "CanonicalFilePathCache.h"
#include "CxxAstVisitorComponent.h"
#include "CxxAstVisitorComponentBraceRecorder.h"
#include "CxxAstVisitorComponentContext.h"
#include "CxxAstVisitorComponentDeclRefKind.h"
#include "CxxAstVisitorComponentTypeRefKind.h"
#include "CxxAstVisitorComponentImplicitCode.h"
#include "CxxAstVisitorComponentIndexer.h"
#include "utilityClang.h"
#include "ParserClient.h"
#include "ParseLocation.h"
@@ -29,85 +22,79 @@ CxxAstVisitor::CxxAstVisitor(
: m_astContext(astContext)
, m_preprocessor(preprocessor)
, m_client(client)
, m_contextComponent(this)
, m_declRefKindComponent(this)
, m_typeRefKindComponent(this)
, m_implicitCodeComponent(this)
, m_indexerComponent(this, astContext, client)
, m_braceRecorderComponent(this, astContext, client)
, m_canonicalFilePathCache(canonicalFilePathCache)
{
m_declNameCache = std::make_shared<DeclNameCache>([&](const clang::NamedDecl* decl) -> NameHierarchy
, m_declNameCache([&](const clang::NamedDecl* decl) -> NameHierarchy
{
if (decl)
{
CxxDeclNameResolver resolver(m_canonicalFilePathCache);
if (std::shared_ptr<CxxDeclName> declName = resolver.getName(decl))
std::shared_ptr<CxxDeclName> declName = CxxDeclNameResolver(m_canonicalFilePathCache.get()).getName(decl);
if (declName)
{
return declName->toNameHierarchy();
}
}
return NameHierarchy(L"global", NAME_DELIMITER_UNKNOWN);
}
);
m_typeNameCache = std::make_shared<TypeNameCache>([&](const clang::Type* type) -> NameHierarchy
)
, m_typeNameCache([&](const clang::Type* type) -> NameHierarchy
{
if (type)
{
CxxTypeNameResolver resolver(m_canonicalFilePathCache);
if (std::shared_ptr<CxxTypeName> typeName = resolver.getName(type))
std::shared_ptr<CxxTypeName> typeName = CxxTypeNameResolver(m_canonicalFilePathCache.get()).getName(type);
if (typeName)
{
return typeName->toNameHierarchy();
}
}
return NameHierarchy(L"global", NAME_DELIMITER_UNKNOWN);
}
);
m_contextComponent = std::make_shared<CxxAstVisitorComponentContext>(this);
m_components.push_back(m_contextComponent);
m_typeRefKindComponent = std::make_shared<CxxAstVisitorComponentTypeRefKind>(this);
m_components.push_back(m_typeRefKindComponent);
m_declRefKindComponent = std::make_shared<CxxAstVisitorComponentDeclRefKind>(this);
m_components.push_back(m_declRefKindComponent);
m_implicitCodeComponent = std::make_shared<CxxAstVisitorComponentImplicitCode>(this);
m_components.push_back(m_implicitCodeComponent);
m_indexerComponent = std::make_shared<CxxAstVisitorComponentIndexer>(this, astContext, client);
m_components.push_back(m_indexerComponent);
m_braceRecorderComponent = std::make_shared<CxxAstVisitorComponentBraceRecorder>(this, astContext, client);
m_components.push_back(m_braceRecorderComponent);
)
{
}
template <>
std::shared_ptr<CxxAstVisitorComponentContext> CxxAstVisitor::getComponent()
CxxAstVisitorComponentContext* CxxAstVisitor::getComponent()
{
return m_contextComponent;
return &m_contextComponent;
}
template <>
std::shared_ptr<CxxAstVisitorComponentTypeRefKind> CxxAstVisitor::getComponent()
CxxAstVisitorComponentTypeRefKind* CxxAstVisitor::getComponent()
{
return m_typeRefKindComponent;
return &m_typeRefKindComponent;
}
template <>
std::shared_ptr<CxxAstVisitorComponentDeclRefKind> CxxAstVisitor::getComponent()
CxxAstVisitorComponentDeclRefKind* CxxAstVisitor::getComponent()
{
return m_declRefKindComponent;
return &m_declRefKindComponent;
}
template <>
std::shared_ptr<CxxAstVisitorComponentIndexer> CxxAstVisitor::getComponent()
CxxAstVisitorComponentIndexer* CxxAstVisitor::getComponent()
{
return m_indexerComponent;
return &m_indexerComponent;
}
std::shared_ptr<DeclNameCache> CxxAstVisitor::getDeclNameCache()
DeclNameCache* CxxAstVisitor::getDeclNameCache()
{
return m_declNameCache;
return &m_declNameCache;
}
std::shared_ptr<TypeNameCache> CxxAstVisitor::getTypeNameCache()
TypeNameCache* CxxAstVisitor::getTypeNameCache()
{
return m_typeNameCache;
return &m_typeNameCache;
}
std::shared_ptr<CanonicalFilePathCache> CxxAstVisitor::getCanonicalFilePathCache()
CanonicalFilePathCache* CxxAstVisitor::getCanonicalFilePathCache()
{
return m_canonicalFilePathCache;
return m_canonicalFilePathCache.get();
}
void CxxAstVisitor::indexDecl(clang::Decl* d)
@@ -122,7 +109,7 @@ bool CxxAstVisitor::shouldVisitTemplateInstantiations() const
bool CxxAstVisitor::shouldVisitImplicitCode() const
{
return m_implicitCodeComponent->shouldVisitImplicitCode();
return m_implicitCodeComponent.shouldVisitImplicitCode();
}
bool CxxAstVisitor::checkIgnoresTypeLoc(const clang::TypeLoc& tl) const
@@ -142,39 +129,37 @@ bool CxxAstVisitor::checkIgnoresTypeLoc(const clang::TypeLoc& tl) const
return true;
}
#define FOREACH_COMPONENT(__METHOD_CALL__) \
{ \
m_contextComponent.__METHOD_CALL__; \
m_typeRefKindComponent.__METHOD_CALL__; \
m_declRefKindComponent.__METHOD_CALL__; \
m_implicitCodeComponent.__METHOD_CALL__; \
m_indexerComponent.__METHOD_CALL__; \
m_braceRecorderComponent.__METHOD_CALL__; \
}
#define DEF_TRAVERSE_CUSTOM_TYPE_PTR(__NAME_TYPE__, __PARAM_TYPE__, CODE_BEFORE, CODE_AFTER) \
bool CxxAstVisitor::Traverse##__NAME_TYPE__(clang::__PARAM_TYPE__* v) \
{ \
for (auto it = m_components.begin(); it != m_components.end(); it++) \
{ \
(*it)->beginTraverse##__NAME_TYPE__(v); \
} \
FOREACH_COMPONENT(beginTraverse##__NAME_TYPE__(v)); \
bool ret = true; \
{ CODE_BEFORE; } \
Base::Traverse##__NAME_TYPE__(v); \
{ CODE_AFTER; } \
for (auto it = m_components.rbegin(); it != m_components.rend(); it++) \
{ \
(*it)->endTraverse##__NAME_TYPE__(v); \
} \
FOREACH_COMPONENT(endTraverse##__NAME_TYPE__(v)); \
return ret; \
}
#define DEF_TRAVERSE_CUSTOM_TYPE(__NAME_TYPE__, __PARAM_TYPE__, CODE_BEFORE, CODE_AFTER) \
bool CxxAstVisitor::Traverse##__NAME_TYPE__(clang::__PARAM_TYPE__ v) \
{ \
for (auto it = m_components.begin(); it != m_components.end(); it++) \
{ \
(*it)->beginTraverse##__NAME_TYPE__(v); \
} \
FOREACH_COMPONENT(beginTraverse##__NAME_TYPE__(v)); \
bool ret = true; \
{ CODE_BEFORE; } \
Base::Traverse##__NAME_TYPE__(v); \
{ CODE_AFTER; } \
for (auto it = m_components.rbegin(); it != m_components.rend(); it++) \
{ \
(*it)->endTraverse##__NAME_TYPE__(v); \
} \
FOREACH_COMPONENT(endTraverse##__NAME_TYPE__(v)); \
return ret; \
}
@@ -186,12 +171,6 @@ bool CxxAstVisitor::checkIgnoresTypeLoc(const clang::TypeLoc& tl) const
bool CxxAstVisitor::TraverseDecl(clang::Decl* decl)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseDecl(decl);
}
bool ret = m_interruptCounter.getCount() == 0;
bool traverse = true;
if (decl)
{
@@ -210,14 +189,12 @@ bool CxxAstVisitor::TraverseDecl(clang::Decl* decl)
if (traverse)
{
FOREACH_COMPONENT(beginTraverseDecl(decl));
Base::TraverseDecl(decl);
FOREACH_COMPONENT(endTraverseDecl(decl));
}
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseDecl(decl);
}
return ret;
return m_interruptCounter.getCount() == 0;
}
// same as Base::TraverseQualifiedTypeLoc(..) but we need to make sure to call this.TraverseTypeLoc(..)
@@ -262,15 +239,9 @@ bool CxxAstVisitor::TraverseCXXRecordDecl(clang::CXXRecordDecl *d)
bool CxxAstVisitor::traverseCXXBaseSpecifier(const clang::CXXBaseSpecifier& d)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseCXXBaseSpecifier();
}
FOREACH_COMPONENT(beginTraverseCXXBaseSpecifier());
bool ret = TraverseTypeLoc(d.getTypeSourceInfo()->getTypeLoc());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseCXXBaseSpecifier();
}
FOREACH_COMPONENT(endTraverseCXXBaseSpecifier());
return ret;
}
@@ -281,15 +252,9 @@ bool CxxAstVisitor::TraverseTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d)
if (d->hasDefaultArgument() && !d->defaultArgumentWasInherited())
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseTemplateDefaultArgumentLoc();
}
FOREACH_COMPONENT(beginTraverseTemplateDefaultArgumentLoc());
TraverseTypeLoc(d->getDefaultArgumentInfo()->getTypeLoc());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseTemplateDefaultArgumentLoc();
}
FOREACH_COMPONENT(endTraverseTemplateDefaultArgumentLoc());
}
traverseDeclContextHelper(clang::dyn_cast<clang::DeclContext>(d));
@@ -305,15 +270,9 @@ bool CxxAstVisitor::TraverseTemplateTemplateParmDecl(clang::TemplateTemplateParm
if (d->hasDefaultArgument() && !d->defaultArgumentWasInherited())
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseTemplateDefaultArgumentLoc();
}
FOREACH_COMPONENT(beginTraverseTemplateDefaultArgumentLoc());
TraverseTemplateArgumentLoc(d->getDefaultArgument());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseTemplateDefaultArgumentLoc();
}
FOREACH_COMPONENT(endTraverseTemplateDefaultArgumentLoc());
}
clang::TemplateParameterList* TPL = d->getTemplateParameters();
@@ -339,10 +298,7 @@ bool CxxAstVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc
bool ret = true;
if (loc)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseNestedNameSpecifierLoc(loc);
}
FOREACH_COMPONENT(beginTraverseNestedNameSpecifierLoc(loc));
//todo: call method of base class...
if (clang::NestedNameSpecifierLoc prefix = loc.getPrefix())
@@ -350,31 +306,22 @@ bool CxxAstVisitor::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc
ret = TraverseNestedNameSpecifierLoc(prefix);
}
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseNestedNameSpecifierLoc(loc);
}
FOREACH_COMPONENT(endTraverseNestedNameSpecifierLoc(loc));
}
return ret;
}
bool CxxAstVisitor::TraverseConstructorInitializer(clang::CXXCtorInitializer* init)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
FOREACH_COMPONENT(beginTraverseConstructorInitializer(init));
bool ret = VisitConstructorInitializer(init);
if (ret)
{
(*it)->beginTraverseConstructorInitializer(init);
ret = Base::TraverseConstructorInitializer(init);
}
if (!VisitConstructorInitializer(init))
{
return false;
}
bool ret = Base::TraverseConstructorInitializer(init);
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseConstructorInitializer(init);
}
FOREACH_COMPONENT(endTraverseConstructorInitializer(init));
return ret;
}
@@ -396,28 +343,15 @@ bool CxxAstVisitor::TraverseCXXOperatorCallExpr(clang::CXXOperatorCallExpr* s)
bool CxxAstVisitor::TraverseCXXConstructExpr(clang::CXXConstructExpr* s)
{
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseCallCommonCallee();
}
WalkUpFromCXXConstructExpr(s);
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->endTraverseCallCommonCallee();
}
}
FOREACH_COMPONENT(beginTraverseCallCommonCallee());
WalkUpFromCXXConstructExpr(s);
FOREACH_COMPONENT(endTraverseCallCommonCallee());
for (unsigned int i = 0; i < s->getNumArgs(); ++i)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseCallCommonArgument();
}
FOREACH_COMPONENT(beginTraverseCallCommonArgument());
TraverseStmt(s->getArg(i));
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseCallCommonArgument();
}
FOREACH_COMPONENT(endTraverseCallCommonArgument());
}
return true;
}
@@ -435,62 +369,33 @@ DEF_TRAVERSE_TYPE_PTR(UnresolvedMemberExpr, {}, {})
bool CxxAstVisitor::TraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseTemplateArgumentLoc(loc);
}
FOREACH_COMPONENT(beginTraverseTemplateArgumentLoc(loc));
bool ret = Base::TraverseTemplateArgumentLoc(loc);
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseTemplateArgumentLoc(loc);
}
FOREACH_COMPONENT(endTraverseTemplateArgumentLoc(loc));
return ret;
}
bool CxxAstVisitor::TraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture, clang::Expr *Init)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseLambdaCapture(lambdaExpr, capture);
}
FOREACH_COMPONENT(beginTraverseLambdaCapture(lambdaExpr, capture));
bool ret = true;
if (lambdaExpr->isInitCapture(capture))
{
ret = TraverseDecl(capture->getCapturedVar());
}
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseLambdaCapture(lambdaExpr, capture);
}
FOREACH_COMPONENT(endTraverseLambdaCapture(lambdaExpr, capture));
return ret;
}
bool CxxAstVisitor::TraverseBinComma(clang::BinaryOperator* s)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseBinCommaLhs();
}
FOREACH_COMPONENT(beginTraverseBinCommaLhs());
TraverseStmt(s->getLHS());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseBinCommaLhs();
}
FOREACH_COMPONENT(endTraverseBinCommaLhs());
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseBinCommaRhs();
}
FOREACH_COMPONENT(beginTraverseBinCommaRhs());
TraverseStmt(s->getRHS());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseBinCommaRhs();
}
FOREACH_COMPONENT(endTraverseBinCommaRhs());
return true;
}
@@ -519,52 +424,28 @@ void CxxAstVisitor::traverseDeclContextHelper(clang::DeclContext* d)
bool CxxAstVisitor::TraverseCallCommon(clang::CallExpr* s)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseCallCommonCallee();
}
FOREACH_COMPONENT(beginTraverseCallCommonCallee());
TraverseStmt(s->getCallee());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseCallCommonCallee();
}
FOREACH_COMPONENT(endTraverseCallCommonCallee());
for (unsigned int i = 0; i < s->getNumArgs(); ++i)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseCallCommonArgument();
}
FOREACH_COMPONENT(beginTraverseCallCommonArgument());
TraverseStmt(s->getArg(i));
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseCallCommonArgument();
}
FOREACH_COMPONENT(endTraverseCallCommonArgument());
}
return true;
}
bool CxxAstVisitor::TraverseAssignCommon(clang::BinaryOperator* s)
{
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseAssignCommonLhs();
}
FOREACH_COMPONENT(beginTraverseAssignCommonLhs());
TraverseStmt(s->getLHS());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseAssignCommonLhs();
}
FOREACH_COMPONENT(endTraverseAssignCommonLhs());
for (auto it = m_components.begin(); it != m_components.end(); it++)
{
(*it)->beginTraverseAssignCommonRhs();
}
FOREACH_COMPONENT(beginTraverseAssignCommonRhs());
TraverseStmt(s->getRHS());
for (auto it = m_components.rbegin(); it != m_components.rend(); it++)
{
(*it)->endTraverseAssignCommonRhs();
}
FOREACH_COMPONENT(endTraverseAssignCommonRhs());
return true;
}
@@ -576,20 +457,14 @@ bool CxxAstVisitor::TraverseAssignCommon(clang::BinaryOperator* s)
#define DEF_VISIT_CUSTOM_TYPE_PTR(__NAME_TYPE__, __PARAM_TYPE__) \
bool CxxAstVisitor::Visit##__NAME_TYPE__(clang::__PARAM_TYPE__* v) \
{ \
for (auto it = m_components.begin(); it != m_components.end(); it++) \
{ \
(*it)->visit##__NAME_TYPE__(v); \
} \
FOREACH_COMPONENT(visit##__NAME_TYPE__(v)); \
return true; \
}
#define DEF_VISIT_CUSTOM_TYPE(__NAME_TYPE__, __PARAM_TYPE__) \
bool CxxAstVisitor::Visit##__NAME_TYPE__(clang::__PARAM_TYPE__ v) \
{ \
for (auto it = m_components.begin(); it != m_components.end(); it++) \
{ \
(*it)->visit##__NAME_TYPE__(v); \
} \
FOREACH_COMPONENT(visit##__NAME_TYPE__(v)); \
return true; \
}
@@ -637,6 +512,8 @@ DEF_VISIT_CUSTOM_TYPE_PTR(ConstructorInitializer, CXXCtorInitializer)
#undef DEF_VISIT_TYPE_PTR
#undef DEF_VISIT_TYPE
#undef FOREACH_COMPONENT
ParseLocation CxxAstVisitor::getParseLocationOfTagDeclBody(clang::TagDecl* decl) const
{
if (decl->isThisDeclarationADefinition())
+28 -29
View File
@@ -5,22 +5,21 @@
#include <clang/AST/RecursiveASTVisitor.h>
#include "CxxContext.h"
#include "MessageInterruptTasksCounter.h"
#include "CxxAstVisitorComponentBraceRecorder.h"
#include "CxxAstVisitorComponentContext.h"
#include "CxxAstVisitorComponentDeclRefKind.h"
#include "CxxAstVisitorComponentImplicitCode.h"
#include "CxxAstVisitorComponentIndexer.h"
#include "CxxAstVisitorComponentTypeRefKind.h"
#include "CxxContext.h"
class CanonicalFilePathCache;
class ParserClient;
struct ParseLocation;
class FilePath;
class CxxAstVisitorComponent;
class CxxAstVisitorComponentBraceRecorder;
class CxxAstVisitorComponentContext;
class CxxAstVisitorComponentDeclRefKind;
class CxxAstVisitorComponentTypeRefKind;
class CxxAstVisitorComponentImplicitCode;
class CxxAstVisitorComponentIndexer;
// methods are called in this order:
// TraverseDecl()
@@ -33,7 +32,8 @@ class CxxAstVisitorComponentIndexer;
// | `- VisitFunctionDecl()
// `- TraverseChildNodes()
class CxxAstVisitor: public clang::RecursiveASTVisitor<CxxAstVisitor>
class CxxAstVisitor
: public clang::RecursiveASTVisitor<CxxAstVisitor>
{
public:
CxxAstVisitor(
@@ -45,11 +45,11 @@ public:
virtual ~CxxAstVisitor() = default;
template <typename T>
std::shared_ptr<T> getComponent();
T* getComponent();
std::shared_ptr<DeclNameCache> getDeclNameCache();
std::shared_ptr<TypeNameCache> getTypeNameCache();
std::shared_ptr<CanonicalFilePathCache> getCanonicalFilePathCache();
DeclNameCache* getDeclNameCache();
TypeNameCache* getTypeNameCache();
CanonicalFilePathCache* getCanonicalFilePathCache();
// Indexing entry point
void indexDecl(clang::Decl *d);
@@ -159,32 +159,31 @@ private:
clang::ASTContext* m_astContext;
clang::Preprocessor* m_preprocessor;
std::shared_ptr<ParserClient> m_client;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
CxxAstVisitorComponentContext m_contextComponent;
CxxAstVisitorComponentDeclRefKind m_declRefKindComponent;
CxxAstVisitorComponentTypeRefKind m_typeRefKindComponent;
CxxAstVisitorComponentImplicitCode m_implicitCodeComponent;
CxxAstVisitorComponentIndexer m_indexerComponent;
CxxAstVisitorComponentBraceRecorder m_braceRecorderComponent;
MessageInterruptTasksCounter m_interruptCounter;
std::vector<std::shared_ptr<CxxAstVisitorComponent>> m_components;
std::shared_ptr<CxxAstVisitorComponentContext> m_contextComponent;
std::shared_ptr<CxxAstVisitorComponentDeclRefKind> m_declRefKindComponent;
std::shared_ptr<CxxAstVisitorComponentTypeRefKind> m_typeRefKindComponent;
std::shared_ptr<CxxAstVisitorComponentImplicitCode> m_implicitCodeComponent;
std::shared_ptr<CxxAstVisitorComponentIndexer> m_indexerComponent;
std::shared_ptr<CxxAstVisitorComponentBraceRecorder> m_braceRecorderComponent;
std::shared_ptr<DeclNameCache> m_declNameCache;
std::shared_ptr<TypeNameCache> m_typeNameCache;
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
DeclNameCache m_declNameCache;
TypeNameCache m_typeNameCache;
};
template <>
std::shared_ptr<CxxAstVisitorComponentContext> CxxAstVisitor::getComponent();
CxxAstVisitorComponentContext* CxxAstVisitor::getComponent();
template <>
std::shared_ptr<CxxAstVisitorComponentTypeRefKind> CxxAstVisitor::getComponent();
CxxAstVisitorComponentTypeRefKind* CxxAstVisitor::getComponent();
template <>
std::shared_ptr<CxxAstVisitorComponentDeclRefKind> CxxAstVisitor::getComponent();
CxxAstVisitorComponentDeclRefKind* CxxAstVisitor::getComponent();
template <>
std::shared_ptr<CxxAstVisitorComponentIndexer> CxxAstVisitor::getComponent();
CxxAstVisitorComponentIndexer* CxxAstVisitor::getComponent();
#endif // CXX_AST_VISITOR_H
@@ -1,7 +1,9 @@
#ifndef CXX_AST_VISITOR_COMPONENT_H
#define CXX_AST_VISITOR_COMPONENT_H
#include "CxxAstVisitor.h"
#include <clang/AST/RecursiveASTVisitor.h>
class CxxAstVisitor;
// CxxAstVisitorComponent: This is the base class for all ast visitor components.
// Each component can override it's begin-/endTraverse and visit methods in order to provide some functionality. The CxxAstVisitor
@@ -10,15 +12,14 @@ class CxxAstVisitorComponent
{
public:
CxxAstVisitorComponent(CxxAstVisitor* astVisitor);
virtual ~CxxAstVisitorComponent() = default;
#define DEF_TRAVERSE_CUSTOM_TYPE_PTR(__NAME_TYPE__, __PARAM_TYPE__) \
virtual void beginTraverse##__NAME_TYPE__(clang::__PARAM_TYPE__ *v) {} \
virtual void endTraverse##__NAME_TYPE__(clang::__PARAM_TYPE__ *v) {}
void beginTraverse##__NAME_TYPE__(clang::__PARAM_TYPE__ *v) {} \
void endTraverse##__NAME_TYPE__(clang::__PARAM_TYPE__ *v) {}
#define DEF_TRAVERSE_CUSTOM_TYPE(__NAME_TYPE__, __PARAM_TYPE__) \
virtual void beginTraverse##__NAME_TYPE__(const clang::__PARAM_TYPE__ &v) {}\
virtual void endTraverse##__NAME_TYPE__(const clang::__PARAM_TYPE__ &v) {}
void beginTraverse##__NAME_TYPE__(const clang::__PARAM_TYPE__ &v) {} \
void endTraverse##__NAME_TYPE__(const clang::__PARAM_TYPE__ &v) {}
#define DEF_TRAVERSE_TYPE_PTR(__TYPE__) \
DEF_TRAVERSE_CUSTOM_TYPE_PTR(__TYPE__, __TYPE__)
@@ -52,29 +53,29 @@ DEF_TRAVERSE_TYPE_PTR(UnresolvedLookupExpr)
DEF_TRAVERSE_TYPE_PTR(UnresolvedMemberExpr)
virtual void beginTraverseCallCommonCallee() {}
virtual void endTraverseCallCommonCallee() {}
void beginTraverseCallCommonCallee() {}
void endTraverseCallCommonCallee() {}
virtual void beginTraverseCallCommonArgument() {}
virtual void endTraverseCallCommonArgument() {}
void beginTraverseCallCommonArgument() {}
void endTraverseCallCommonArgument() {}
virtual void beginTraverseBinCommaLhs() {}
virtual void endTraverseBinCommaLhs() {}
void beginTraverseBinCommaLhs() {}
void endTraverseBinCommaLhs() {}
virtual void beginTraverseBinCommaRhs() {}
virtual void endTraverseBinCommaRhs() {}
void beginTraverseBinCommaRhs() {}
void endTraverseBinCommaRhs() {}
virtual void beginTraverseAssignCommonLhs() {}
virtual void endTraverseAssignCommonLhs() {}
void beginTraverseAssignCommonLhs() {}
void endTraverseAssignCommonLhs() {}
virtual void beginTraverseAssignCommonRhs() {}
virtual void endTraverseAssignCommonRhs() {}
void beginTraverseAssignCommonRhs() {}
void endTraverseAssignCommonRhs() {}
virtual void beginTraverseCXXBaseSpecifier() {}
virtual void endTraverseCXXBaseSpecifier() {}
void beginTraverseCXXBaseSpecifier() {}
void endTraverseCXXBaseSpecifier() {}
virtual void beginTraverseTemplateDefaultArgumentLoc() {}
virtual void endTraverseTemplateDefaultArgumentLoc() {}
void beginTraverseTemplateDefaultArgumentLoc() {}
void endTraverseTemplateDefaultArgumentLoc() {}
DEF_TRAVERSE_TYPE(NestedNameSpecifierLoc)
@@ -82,47 +83,47 @@ DEF_TRAVERSE_CUSTOM_TYPE_PTR(ConstructorInitializer, CXXCtorInitializer)
DEF_TRAVERSE_TYPE_PTR(CXXTemporaryObjectExpr)
virtual void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) {}
virtual void endTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) {}
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) {}
void endTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) {}
virtual void beginTraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture) {}
virtual void endTraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture) {}
void beginTraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture) {}
void endTraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture) {}
virtual void visitTagDecl(clang::TagDecl* d) {}
virtual void visitClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl* d) {}
virtual void visitVarDecl(clang::VarDecl* d) {}
virtual void visitVarTemplateSpecializationDecl(clang::VarTemplateSpecializationDecl* d) {}
virtual void visitFieldDecl(clang::FieldDecl* d) {}
virtual void visitFunctionDecl(clang::FunctionDecl* d) {}
virtual void visitCXXMethodDecl(clang::CXXMethodDecl* d) {}
virtual void visitEnumConstantDecl(clang::EnumConstantDecl* d) {}
virtual void visitNamespaceDecl(clang::NamespaceDecl* d) {}
virtual void visitNamespaceAliasDecl(clang::NamespaceAliasDecl* d) {}
virtual void visitTypedefDecl(clang::TypedefDecl* d) {}
virtual void visitTypeAliasDecl(clang::TypeAliasDecl* d) {}
virtual void visitUsingDirectiveDecl(clang::UsingDirectiveDecl* d) {}
virtual void visitUsingDecl(clang::UsingDecl* d) {}
virtual void visitNonTypeTemplateParmDecl(clang::NonTypeTemplateParmDecl* d) {}
virtual void visitTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d) {}
virtual void visitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d) {}
void visitTagDecl(clang::TagDecl* d) {}
void visitClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl* d) {}
void visitVarDecl(clang::VarDecl* d) {}
void visitVarTemplateSpecializationDecl(clang::VarTemplateSpecializationDecl* d) {}
void visitFieldDecl(clang::FieldDecl* d) {}
void visitFunctionDecl(clang::FunctionDecl* d) {}
void visitCXXMethodDecl(clang::CXXMethodDecl* d) {}
void visitEnumConstantDecl(clang::EnumConstantDecl* d) {}
void visitNamespaceDecl(clang::NamespaceDecl* d) {}
void visitNamespaceAliasDecl(clang::NamespaceAliasDecl* d) {}
void visitTypedefDecl(clang::TypedefDecl* d) {}
void visitTypeAliasDecl(clang::TypeAliasDecl* d) {}
void visitUsingDirectiveDecl(clang::UsingDirectiveDecl* d) {}
void visitUsingDecl(clang::UsingDecl* d) {}
void visitNonTypeTemplateParmDecl(clang::NonTypeTemplateParmDecl* d) {}
void visitTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d) {}
void visitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d) {}
virtual void visitTypeLoc(clang::TypeLoc tl) {}
void visitTypeLoc(clang::TypeLoc tl) {}
virtual void visitCastExpr(clang::CastExpr* s) {}
virtual void visitUnaryAddrOf(clang::UnaryOperator* s) {}
virtual void visitUnaryDeref(clang::UnaryOperator* s) {}
virtual void visitDeclStmt(clang::DeclStmt* s) {}
virtual void visitReturnStmt(clang::ReturnStmt* s) {}
virtual void visitCompoundStmt(clang::CompoundStmt* s) {};
virtual void visitInitListExpr(clang::InitListExpr* s) {}
virtual void visitDeclRefExpr(clang::DeclRefExpr* s) {}
virtual void visitMemberExpr(clang::MemberExpr* s) {}
virtual void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) {}
virtual void visitCXXConstructExpr(clang::CXXConstructExpr* s) {}
virtual void visitLambdaExpr(clang::LambdaExpr* s) {}
virtual void visitMSAsmStmt(clang::MSAsmStmt* s) {}
void visitCastExpr(clang::CastExpr* s) {}
void visitUnaryAddrOf(clang::UnaryOperator* s) {}
void visitUnaryDeref(clang::UnaryOperator* s) {}
void visitDeclStmt(clang::DeclStmt* s) {}
void visitReturnStmt(clang::ReturnStmt* s) {}
void visitCompoundStmt(clang::CompoundStmt* s) {};
void visitInitListExpr(clang::InitListExpr* s) {}
void visitDeclRefExpr(clang::DeclRefExpr* s) {}
void visitMemberExpr(clang::MemberExpr* s) {}
void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) {}
void visitCXXConstructExpr(clang::CXXConstructExpr* s) {}
void visitLambdaExpr(clang::LambdaExpr* s) {}
void visitMSAsmStmt(clang::MSAsmStmt* s) {}
virtual void visitConstructorInitializer(clang::CXXCtorInitializer* init) {}
void visitConstructorInitializer(clang::CXXCtorInitializer* init) {}
#undef DEF_TRAVERSE_CUSTOM_TYPE_PTR
#undef DEF_TRAVERSE_CUSTOM_TYPE
@@ -2,9 +2,9 @@
#include <clang/Lex/Preprocessor.h>
#include "CxxAstVisitor.h"
#include "CxxAstVisitorComponentContext.h"
#include "utilityClang.h"
#include "ParseLocation.h"
#include "ParserClient.h"
CxxAstVisitorComponentBraceRecorder::CxxAstVisitorComponentBraceRecorder(
@@ -2,18 +2,22 @@
#define CXX_AST_VISITOR_COMPONENT_BRACE_RECORDER_H
#include "CxxAstVisitorComponent.h"
#include "ParseLocation.h"
class ParserClient;
// This CxxAstVisitorComponent is responsible for recording all matching braces ["{", "}"] throughout the visited AST.
class CxxAstVisitorComponentBraceRecorder: public CxxAstVisitorComponent
class CxxAstVisitorComponentBraceRecorder
: public CxxAstVisitorComponent
{
public:
CxxAstVisitorComponentBraceRecorder(CxxAstVisitor* astVisitor, clang::ASTContext* astContext, std::shared_ptr<ParserClient> client);
void visitTagDecl(clang::TagDecl* d) override;
void visitNamespaceDecl(clang::NamespaceDecl* d) override;
void visitCompoundStmt(clang::CompoundStmt* s) override;
void visitInitListExpr(clang::InitListExpr* s) override;
void visitMSAsmStmt(clang::MSAsmStmt* s) override;
void visitTagDecl(clang::TagDecl* d);
void visitNamespaceDecl(clang::NamespaceDecl* d);
void visitCompoundStmt(clang::CompoundStmt* s);
void visitInitListExpr(clang::InitListExpr* s);
void visitMSAsmStmt(clang::MSAsmStmt* s);
private:
ParseLocation getParseLocation(const clang::SourceLocation& loc) const;
@@ -1,5 +1,7 @@
#include "CxxAstVisitorComponentContext.h"
#include "data/parser/cxx/CxxAstVisitor.h"
CxxAstVisitorComponentContext::CxxAstVisitorComponentContext(CxxAstVisitor* astVisitor)
: CxxAstVisitorComponent(astVisitor)
{
@@ -7,7 +9,7 @@ CxxAstVisitorComponentContext::CxxAstVisitorComponentContext(CxxAstVisitor* astV
const clang::NamedDecl* CxxAstVisitorComponentContext::getTopmostContextDecl() const
{
for (std::vector<std::shared_ptr<CxxContext>>::const_reverse_iterator it = m_contextStack.rbegin(); it != m_contextStack.rend(); it ++)
for (auto it = m_contextStack.rbegin(); it != m_contextStack.rend(); it++)
{
if (*it)
{
@@ -42,19 +44,13 @@ NameHierarchy CxxAstVisitorComponentContext::getContextName(const size_t skip)
return getAstVisitor()->getDeclNameCache()->getValue(nullptr);
}
NameHierarchy CxxAstVisitorComponentContext::getContextName(const NameHierarchy& fallback, const size_t skip)
NameHierarchy CxxAstVisitorComponentContext::getContextName(const NameHierarchy& fallback)
{
size_t skipped = 0;
for (auto it = m_contextStack.rbegin(); it != m_contextStack.rend(); it++)
{
if (*it)
{
if (skipped >= skip)
{
return (*it)->getName();
}
skipped++;
return (*it)->getName();
}
}
return fallback;
@@ -103,8 +99,7 @@ void CxxAstVisitorComponentContext::endTraverseTypeLoc(const clang::TypeLoc& tl)
void CxxAstVisitorComponentContext::beginTraverseLambdaExpr(clang::LambdaExpr* s)
{
clang::CXXMethodDecl* methodDecl = s->getCallOperator();
m_contextStack.push_back(std::make_shared<CxxContextDecl>(methodDecl, getAstVisitor()->getDeclNameCache()));
m_contextStack.push_back(std::make_shared<CxxContextDecl>(s->getCallOperator(), getAstVisitor()->getDeclNameCache()));
}
void CxxAstVisitorComponentContext::endTraverseLambdaExpr(clang::LambdaExpr* s)
@@ -164,8 +159,7 @@ void CxxAstVisitorComponentContext::endTraverseTemplateSpecializationTypeLoc(con
void CxxAstVisitorComponentContext::beginTraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e) // TODO: do this for unresolved and dependent stuff
{
std::shared_ptr<CxxContext> clear;
m_templateArgumentContext.push_back(clear);
m_templateArgumentContext.push_back(nullptr);
}
void CxxAstVisitorComponentContext::endTraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e)
@@ -7,44 +7,45 @@
// This CxxAstVisitorComponent is responsible for recording and providing the decl/type that acts as the context of the currently traversed/visited node.
// Example: void foo() { bar(); }
// For this snippet the declaration of "foo" serves as the context of the call to "bar"
class CxxAstVisitorComponentContext: public CxxAstVisitorComponent
class CxxAstVisitorComponentContext
: public CxxAstVisitorComponent
{
public:
CxxAstVisitorComponentContext(CxxAstVisitor* astVisitor);
const clang::NamedDecl* getTopmostContextDecl() const;
NameHierarchy getContextName(const size_t skip = 0);
NameHierarchy getContextName(const NameHierarchy& fallback, const size_t skip = 0);
NameHierarchy getContextName(const NameHierarchy& fallback);
void beginTraverseDecl(clang::Decl* d) override;
void endTraverseDecl(clang::Decl* d) override;
void beginTraverseDecl(clang::Decl* d);
void endTraverseDecl(clang::Decl* d);
void beginTraverseTypeLoc(const clang::TypeLoc& tl) override;
void endTraverseTypeLoc(const clang::TypeLoc& tl) override;
void beginTraverseTypeLoc(const clang::TypeLoc& tl);
void endTraverseTypeLoc(const clang::TypeLoc& tl);
void beginTraverseLambdaExpr(clang::LambdaExpr* s) override;
void endTraverseLambdaExpr(clang::LambdaExpr* s) override;
void beginTraverseLambdaExpr(clang::LambdaExpr* s);
void endTraverseLambdaExpr(clang::LambdaExpr* s);
void beginTraverseFunctionDecl(clang::FunctionDecl* d) override;
void endTraverseFunctionDecl(clang::FunctionDecl* d) override;
void beginTraverseFunctionDecl(clang::FunctionDecl* d);
void endTraverseFunctionDecl(clang::FunctionDecl* d);
void beginTraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *d) override;
void endTraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *d) override;
void beginTraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *d);
void endTraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *d);
void beginTraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d) override;
void endTraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d) override;
void beginTraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d);
void endTraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d);
void beginTraverseDeclRefExpr(clang::DeclRefExpr* s) override;
void endTraverseDeclRefExpr(clang::DeclRefExpr* s) override;
void beginTraverseDeclRefExpr(clang::DeclRefExpr* s);
void endTraverseDeclRefExpr(clang::DeclRefExpr* s);
void beginTraverseTemplateSpecializationTypeLoc(const clang::TemplateSpecializationTypeLoc& loc) override;
void endTraverseTemplateSpecializationTypeLoc(const clang::TemplateSpecializationTypeLoc& loc) override;
void beginTraverseTemplateSpecializationTypeLoc(const clang::TemplateSpecializationTypeLoc& loc);
void endTraverseTemplateSpecializationTypeLoc(const clang::TemplateSpecializationTypeLoc& loc);
void beginTraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e) override;
void endTraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e) override;
void beginTraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e);
void endTraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e);
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) override;
void endTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) override;
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);
void endTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);
private:
std::vector<std::shared_ptr<CxxContext>> m_contextStack;
@@ -3,68 +3,67 @@
#include <vector>
#include "CxxAstVisitor.h"
#include "CxxAstVisitorComponent.h"
#include "ReferenceKind.h"
// This CxxAstVisitorComponent is responsible for recording and providing the context based ReferenceKind for each reference to a declaration encountered while traversing the AST.
// Example: void foo() { bar(); }
// For this snippet the reference to "bar" is used in the context of a call.
class CxxAstVisitorComponentDeclRefKind: public CxxAstVisitorComponent
class CxxAstVisitorComponentDeclRefKind
: public CxxAstVisitorComponent
{
public:
CxxAstVisitorComponentDeclRefKind(CxxAstVisitor* astVisitor);
ReferenceKind getReferenceKind() const;
void beginTraverseDecl(clang::Decl* d) override;
void endTraverseDecl(clang::Decl* d) override;
void beginTraverseDecl(clang::Decl* d);
void endTraverseDecl(clang::Decl* d);
void beginTraverseStmt(clang::Stmt* s) override;
void endTraverseStmt(clang::Stmt* s) override;
void beginTraverseStmt(clang::Stmt* s);
void endTraverseStmt(clang::Stmt* s);
void beginTraverseType(const clang::QualType& t) override;
void endTraverseType(const clang::QualType& t) override;
void beginTraverseType(const clang::QualType& t);
void endTraverseType(const clang::QualType& t);
void beginTraverseTypeLoc(const clang::TypeLoc& tl) override;
void endTraverseTypeLoc(const clang::TypeLoc& tl) override;
void beginTraverseTypeLoc(const clang::TypeLoc& tl);
void endTraverseTypeLoc(const clang::TypeLoc& tl);
void beginTraverseCallCommonCallee() override;
void beginTraverseCallCommonCallee();
void beginTraverseCallCommonArgument() override;
void beginTraverseCallCommonArgument();
void beginTraverseBinCommaLhs() override;
void beginTraverseBinCommaLhs();
void beginTraverseBinCommaRhs() override;
void beginTraverseBinCommaRhs();
void beginTraverseAssignCommonLhs() override;
void beginTraverseAssignCommonLhs();
void beginTraverseAssignCommonRhs() override;
void beginTraverseAssignCommonRhs();
void beginTraverseConstructorInitializer(clang::CXXCtorInitializer* init) override;
void beginTraverseConstructorInitializer(clang::CXXCtorInitializer* init);
void beginTraverseCXXTemporaryObjectExpr(clang::CXXTemporaryObjectExpr* s) override;
void beginTraverseCXXTemporaryObjectExpr(clang::CXXTemporaryObjectExpr* s);
void beginTraverseUnresolvedMemberExpr(clang::UnresolvedMemberExpr* s) override;
void beginTraverseUnresolvedMemberExpr(clang::UnresolvedMemberExpr* s);
void visitVarDecl(clang::VarDecl* d) override;
void visitVarDecl(clang::VarDecl* d);
void visitCastExpr(clang::CastExpr* s) override;
void visitCastExpr(clang::CastExpr* s);
void visitUnaryAddrOf(clang::UnaryOperator* s) override;
void visitUnaryAddrOf(clang::UnaryOperator* s);
void visitUnaryDeref(clang::UnaryOperator* s) override;
void visitUnaryDeref(clang::UnaryOperator* s);
void visitDeclStmt(clang::DeclStmt* s) override;
void visitDeclStmt(clang::DeclStmt* s);
void visitReturnStmt(clang::ReturnStmt* s) override;
void visitReturnStmt(clang::ReturnStmt* s);
void visitInitListExpr(clang::InitListExpr* s) override;
void visitInitListExpr(clang::InitListExpr* s);
void visitMemberExpr(clang::MemberExpr* s) override;
void visitMemberExpr(clang::MemberExpr* s);
void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) override;
void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s);
private:
void saveAll();
@@ -4,18 +4,19 @@
#include "CxxAstVisitorComponent.h"
// This CxxAstVisitorComponent is responsible for deciding if the AstVisitor should visit implicit code in the current context.
class CxxAstVisitorComponentImplicitCode: public CxxAstVisitorComponent
class CxxAstVisitorComponentImplicitCode
: public CxxAstVisitorComponent
{
public:
CxxAstVisitorComponentImplicitCode(CxxAstVisitor* astVisitor);
bool shouldVisitImplicitCode() const;
void beginTraverseDecl(clang::Decl* d) override;
void endTraverseDecl(clang::Decl* d) override;
void beginTraverseDecl(clang::Decl* d);
void endTraverseDecl(clang::Decl* d);
void beginTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s) override;
void endTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s) override;
void beginTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s);
void endTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s);
private:
std::vector<bool> m_stack;
@@ -6,13 +6,12 @@
#include <clang/Lex/Preprocessor.h>
#include "CanonicalFilePathCache.h"
#include "CxxAstVisitor.h"
#include "CxxAstVisitorComponentContext.h"
#include "CxxAstVisitorComponentDeclRefKind.h"
#include "CxxAstVisitorComponentTypeRefKind.h"
#include "utilityClang.h"
#include "ParseLocation.h"
#include "ParserClient.h"
#include "FileRegister.h"
CxxAstVisitorComponentIndexer::CxxAstVisitorComponentIndexer(
CxxAstVisitor* astVisitor, clang::ASTContext* astContext, std::shared_ptr<ParserClient> client
@@ -839,8 +838,7 @@ ReferenceKind CxxAstVisitorComponentIndexer::consumeDeclRefContextKind()
{
ReferenceKind refKind = REFERENCE_UNDEFINED;
std::shared_ptr<CxxAstVisitorComponentTypeRefKind> typeRefKindComponent = getAstVisitor()->getComponent<CxxAstVisitorComponentTypeRefKind>();
CxxAstVisitorComponentTypeRefKind* typeRefKindComponent = getAstVisitor()->getComponent<CxxAstVisitorComponentTypeRefKind>();
if (typeRefKindComponent->getReferenceKind() == REFERENCE_TYPE_USAGE)
{
refKind = getAstVisitor()->getComponent<CxxAstVisitorComponentDeclRefKind>()->getReferenceKind();
@@ -4,45 +4,50 @@
#include <unordered_map>
#include "CxxAstVisitorComponent.h"
#include "ParseLocation.h"
#include "ReferenceKind.h"
#include "SymbolKind.h"
class ParserClient;
class NameHierarchy;
// This CxxAstVisitorComponent is responsible for recording all symbols and relations throughout the visited AST.
class CxxAstVisitorComponentIndexer: public CxxAstVisitorComponent
class CxxAstVisitorComponentIndexer
: public CxxAstVisitorComponent
{
public:
CxxAstVisitorComponentIndexer(CxxAstVisitor* astVisitor, clang::ASTContext* astContext, std::shared_ptr<ParserClient> client);
void beginTraverseNestedNameSpecifierLoc(const clang::NestedNameSpecifierLoc& loc) override;
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) override;
void beginTraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture) override;
void beginTraverseNestedNameSpecifierLoc(const clang::NestedNameSpecifierLoc& loc);
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);
void beginTraverseLambdaCapture(clang::LambdaExpr *lambdaExpr, const clang::LambdaCapture *capture);
void visitTagDecl(clang::TagDecl* d) override;
void visitClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl* d) override;
void visitVarDecl(clang::VarDecl* d) override;
void visitVarTemplateSpecializationDecl(clang::VarTemplateSpecializationDecl* d) override;
void visitFieldDecl(clang::FieldDecl* d) override;
void visitFunctionDecl(clang::FunctionDecl* d) override;
void visitCXXMethodDecl(clang::CXXMethodDecl* d) override;
void visitEnumConstantDecl(clang::EnumConstantDecl* d) override;
void visitNamespaceDecl(clang::NamespaceDecl* d) override;
void visitNamespaceAliasDecl(clang::NamespaceAliasDecl* d) override;
void visitTypedefDecl(clang::TypedefDecl* d) override;
void visitTypeAliasDecl(clang::TypeAliasDecl* d) override;
void visitUsingDirectiveDecl(clang::UsingDirectiveDecl* d) override;
void visitUsingDecl(clang::UsingDecl* d) override;
void visitNonTypeTemplateParmDecl(clang::NonTypeTemplateParmDecl* d) override;
void visitTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d) override;
void visitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d) override;
void visitTagDecl(clang::TagDecl* d);
void visitClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl* d);
void visitVarDecl(clang::VarDecl* d);
void visitVarTemplateSpecializationDecl(clang::VarTemplateSpecializationDecl* d);
void visitFieldDecl(clang::FieldDecl* d);
void visitFunctionDecl(clang::FunctionDecl* d);
void visitCXXMethodDecl(clang::CXXMethodDecl* d);
void visitEnumConstantDecl(clang::EnumConstantDecl* d);
void visitNamespaceDecl(clang::NamespaceDecl* d);
void visitNamespaceAliasDecl(clang::NamespaceAliasDecl* d);
void visitTypedefDecl(clang::TypedefDecl* d);
void visitTypeAliasDecl(clang::TypeAliasDecl* d);
void visitUsingDirectiveDecl(clang::UsingDirectiveDecl* d);
void visitUsingDecl(clang::UsingDecl* d);
void visitNonTypeTemplateParmDecl(clang::NonTypeTemplateParmDecl* d);
void visitTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d);
void visitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d);
void visitTypeLoc(clang::TypeLoc tl) override;
void visitTypeLoc(clang::TypeLoc tl);
void visitDeclRefExpr(clang::DeclRefExpr* s) override;
void visitMemberExpr(clang::MemberExpr* s) override;
void visitCXXConstructExpr(clang::CXXConstructExpr* s) override;
void visitLambdaExpr(clang::LambdaExpr* s) override;
void visitDeclRefExpr(clang::DeclRefExpr* s);
void visitMemberExpr(clang::MemberExpr* s);
void visitCXXConstructExpr(clang::CXXConstructExpr* s);
void visitLambdaExpr(clang::LambdaExpr* s);
void visitConstructorInitializer(clang::CXXCtorInitializer* init) override;
void visitConstructorInitializer(clang::CXXCtorInitializer* init);
private:
void recordTemplateMemberSpecialization(
@@ -3,29 +3,28 @@
#include <vector>
#include "CxxAstVisitor.h"
#include "CxxAstVisitorComponent.h"
#include "ReferenceKind.h"
// This CxxAstVisitorComponent is responsible for recording and providing the context based ReferenceKind for each reference to a type encountered while traversing the AST.
// Example: class Foo: public Bar {};
// For this snippet the type "Bar" is used in the context of an inheritence.
class CxxAstVisitorComponentTypeRefKind: public CxxAstVisitorComponent
class CxxAstVisitorComponentTypeRefKind
: public CxxAstVisitorComponent
{
public:
CxxAstVisitorComponentTypeRefKind(CxxAstVisitor* astVisitor);
ReferenceKind getReferenceKind() const;
void beginTraverseCXXBaseSpecifier() override;
void endTraverseCXXBaseSpecifier() override;
void beginTraverseCXXBaseSpecifier();
void endTraverseCXXBaseSpecifier();
void beginTraverseTemplateDefaultArgumentLoc() override;
void endTraverseTemplateDefaultArgumentLoc() override;
void beginTraverseTemplateDefaultArgumentLoc();
void endTraverseTemplateDefaultArgumentLoc();
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) override;
void endTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc) override;
void beginTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);
void endTraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);
private:
std::vector<ReferenceKind> m_refKindStack;
+3 -2
View File
@@ -1,6 +1,6 @@
#include "CxxContext.h"
CxxContextDecl::CxxContextDecl(const clang::NamedDecl* decl, std::shared_ptr<DeclNameCache> nameCache)
CxxContextDecl::CxxContextDecl(const clang::NamedDecl* decl, DeclNameCache* nameCache)
: m_decl(decl)
, m_nameCache(nameCache)
{
@@ -16,7 +16,8 @@ const clang::NamedDecl* CxxContextDecl::getDecl()
return m_decl;
}
CxxContextType::CxxContextType(const clang::Type* type, std::shared_ptr<TypeNameCache> nameCache)
CxxContextType::CxxContextType(const clang::Type* type, TypeNameCache* nameCache)
: m_type(type)
, m_nameCache(nameCache)
{
+13 -9
View File
@@ -4,10 +4,10 @@
#include <clang/AST/Decl.h>
#include "NameHierarchy.h"
#include "UnorderedCache.h"
#include "OrderedCache.h"
typedef UnorderedCache<const clang::NamedDecl*, NameHierarchy> DeclNameCache;
typedef UnorderedCache<const clang::Type*, NameHierarchy> TypeNameCache;
typedef OrderedCache<const clang::NamedDecl*, NameHierarchy> DeclNameCache;
typedef OrderedCache<const clang::Type*, NameHierarchy> TypeNameCache;
class CxxContext
{
@@ -17,28 +17,32 @@ public:
virtual const clang::NamedDecl* getDecl() = 0;
};
class CxxContextDecl: public CxxContext
class CxxContextDecl
: public CxxContext
{
public:
CxxContextDecl(const clang::NamedDecl* decl, std::shared_ptr<DeclNameCache> nameCache);
CxxContextDecl(const clang::NamedDecl* decl, DeclNameCache* nameCache);
NameHierarchy getName() override;
const clang::NamedDecl* getDecl() override;
private:
const clang::NamedDecl* m_decl;
std::shared_ptr<DeclNameCache> m_nameCache;
DeclNameCache* m_nameCache;
};
class CxxContextType: public CxxContext
class CxxContextType
: public CxxContext
{
public:
CxxContextType(const clang::Type* type, std::shared_ptr<TypeNameCache> nameCache);
CxxContextType(const clang::Type* type, TypeNameCache* nameCache);
NameHierarchy getName() override;
const clang::NamedDecl* getDecl() override;
private:
const clang::Type* m_type;
std::shared_ptr<TypeNameCache> m_nameCache;
TypeNameCache* m_nameCache;
};
#endif // CXX_CONTEXT_H
@@ -1,68 +1,29 @@
#include "CxxDeclName.h"
//CxxDeclName::CxxDeclName(const std::wstring& name, const std::vector<std::wstring>& templateParameterNames)
// : m_name(name)
// , m_templateParameterNames(templateParameterNames)
//{
//}
CxxDeclName::CxxDeclName(std::wstring&& name, std::vector<std::wstring>&& templateParameterNames)
CxxDeclName::CxxDeclName(std::wstring name)
: m_name(std::move(name))
, m_templateParameterNames(std::move(templateParameterNames))
{
}
//CxxDeclName::CxxDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxName> parent
//)
// : CxxName(parent)
// , m_name(name)
// , m_templateParameterNames(templateParameterNames)
//{
//}
CxxDeclName::CxxDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxName> parent
)
: CxxName(parent)
, m_name(std::move(name))
CxxDeclName::CxxDeclName(std::wstring name, std::vector<std::wstring> templateParameterNames)
: m_name(std::move(name))
, m_templateParameterNames(std::move(templateParameterNames))
{
}
NameHierarchy CxxDeclName::toNameHierarchy() const
{
std::wstring nameString = m_name;
if (!m_templateParameterNames.empty())
{
nameString += L"<";
for (size_t i = 0; i < m_templateParameterNames.size(); i++)
{
if (i != 0)
{
nameString += L", ";
}
nameString += m_templateParameterNames[i];
}
nameString += L">";
}
NameHierarchy ret = getParent() ? getParent()->toNameHierarchy(): NameHierarchy(NAME_DELIMITER_CXX);
ret.push(std::make_shared<NameElement>(nameString));
NameHierarchy ret = getParent() ? getParent()->toNameHierarchy() : NameHierarchy(NAME_DELIMITER_CXX);
ret.push(std::make_shared<NameElement>(m_name + getTemplateSuffix(m_templateParameterNames)));
return ret;
}
std::wstring CxxDeclName::getName() const
const std::wstring& CxxDeclName::getName() const
{
return m_name;
}
std::vector<std::wstring> CxxDeclName::getTemplateParameterNames() const
const std::vector<std::wstring>& CxxDeclName::getTemplateParameterNames() const
{
return m_templateParameterNames;
}
+10 -26
View File
@@ -8,41 +8,25 @@
#include "NameHierarchy.h"
#include "CxxName.h"
class CxxDeclName: public CxxName
class CxxDeclName
: public CxxName
{
public:
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames
//);
CxxDeclName(std::wstring name);
CxxDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames
std::wstring name,
std::vector<std::wstring> templateParameterNames
);
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxName> parent
//);
NameHierarchy toNameHierarchy() const override;
CxxDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxName> parent
);
virtual NameHierarchy toNameHierarchy() const;
std::wstring getName() const;
std::vector<std::wstring> getTemplateParameterNames() const;
const std::wstring& getName() const;
const std::vector<std::wstring>& getTemplateParameterNames() const;
private:
std::wstring m_name;
std::vector<std::wstring> m_templateParameterNames;
const std::wstring m_name;
const std::vector<std::wstring> m_templateParameterNames;
};
#endif // CXX_DECL_NAME_H
@@ -1,65 +1,17 @@
#include "CxxFunctionDeclName.h"
//CxxFunctionDeclName::CxxFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const bool isConst,
// const bool isStatic
//)
// : CxxDeclName(name, templateParameterNames)
// , m_returnTypeName(returnTypeName)
// , m_parameterTypeNames(parameterTypeNames)
// , m_isConst(isConst)
// , m_isStatic(isStatic)
//{
//}
#include <sstream>
CxxFunctionDeclName::CxxFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
std::wstring name,
std::vector<std::wstring> templateParameterNames,
std::unique_ptr<CxxTypeName> returnTypeName,
std::vector<std::unique_ptr<CxxTypeName>> parameterTypeNames,
const bool isConst,
const bool isStatic
)
: CxxDeclName(std::move(name), std::move(templateParameterNames))
, m_returnTypeName(returnTypeName)
, m_parameterTypeNames(std::move(parameterTypeNames))
, m_isConst(isConst)
, m_isStatic(isStatic)
{
}
//CxxFunctionDeclName::CxxFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const bool isConst,
// const bool isStatic,
// std::shared_ptr<CxxName> parent
//)
// : CxxDeclName(name, templateParameterNames, parent)
// , m_returnTypeName(returnTypeName)
// , m_parameterTypeNames(parameterTypeNames)
// , m_isConst(isConst)
// , m_isStatic(isStatic)
//{
//}
CxxFunctionDeclName::CxxFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
const bool isConst,
const bool isStatic,
std::shared_ptr<CxxName> parent
)
: CxxDeclName(std::move(name), std::move(templateParameterNames), parent)
, m_returnTypeName(returnTypeName)
, m_returnTypeName(std::move(returnTypeName))
, m_parameterTypeNames(std::move(parameterTypeNames))
, m_isConst(isConst)
, m_isStatic(isStatic)
@@ -68,37 +20,30 @@ CxxFunctionDeclName::CxxFunctionDeclName(
NameHierarchy CxxFunctionDeclName::toNameHierarchy() const
{
std::wstring signaturePrefix;
std::wstringstream prefix;
if (m_isStatic)
{
signaturePrefix += L"static ";
prefix << L"static ";
}
signaturePrefix += CxxTypeName::makeUnsolvedIfNull(m_returnTypeName)->toString();
prefix << m_returnTypeName->toString();
std::wstring signaturePostfix = L"(";
std::wstringstream postfix;
postfix << L'(';
for (size_t i = 0; i < m_parameterTypeNames.size(); i++)
{
if (i != 0)
{
signaturePostfix += L", ";
postfix << L", ";
}
signaturePostfix += CxxTypeName::makeUnsolvedIfNull(m_parameterTypeNames[i])->toString();
postfix << m_parameterTypeNames[i]->toString();
}
signaturePostfix += L")";
postfix << L')';
if (m_isConst)
{
signaturePostfix += L" const";
postfix << L" const";
}
NameHierarchy ret = CxxDeclName::toNameHierarchy();
std::shared_ptr<NameElement> nameElement = std::make_shared<NameElement>(
ret.back()->getName(),
std::move(signaturePrefix),
std::move(signaturePostfix)
);
ret.pop();
ret.push(nameElement);
ret.back()->setSignature(prefix.str(), postfix.str());
return ret;
}
@@ -7,56 +7,26 @@
#include "CxxDeclName.h"
#include "CxxTypeName.h"
class CxxFunctionDeclName: public CxxDeclName
class CxxFunctionDeclName
: public CxxDeclName
{
public:
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const bool isConst,
// const bool isStatic
//);
CxxFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
std::wstring name,
std::vector<std::wstring> templateParameterNames,
std::unique_ptr<CxxTypeName> returnTypeName,
std::vector<std::unique_ptr<CxxTypeName>> parameterTypeNames,
const bool isConst,
const bool isStatic
);
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const bool isConst,
// const bool isStatic,
// std::shared_ptr<CxxName> parent
//);
CxxFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
const bool isConst,
const bool isStatic,
std::shared_ptr<CxxName> parent
);
virtual NameHierarchy toNameHierarchy() const;
NameHierarchy toNameHierarchy() const override;
private:
std::shared_ptr<CxxTypeName> m_returnTypeName;
std::vector<std::shared_ptr<CxxTypeName>> m_parameterTypeNames;
bool m_isConst;
bool m_isStatic;
const std::unique_ptr<CxxTypeName> m_returnTypeName;
const std::vector<std::unique_ptr<CxxTypeName>> m_parameterTypeNames;
const bool m_isConst;
const bool m_isStatic;
};
#endif // CXX_FUNCTION_DECL_NAME_H
@@ -1,5 +1,7 @@
#include "CxxName.h"
#include "utilityString.h"
CxxName::CxxName()
{
}
@@ -19,3 +21,12 @@ std::shared_ptr<CxxName> CxxName::getParent() const
return m_parent;
}
std::wstring CxxName::getTemplateSuffix(const std::vector<std::wstring>& elements) const
{
if (elements.size())
{
return L'<' + utility::join(elements, L", ") + L'>';
}
return L"";
}
@@ -18,6 +18,8 @@ public:
void setParent(std::shared_ptr<CxxName> parent);
std::shared_ptr<CxxName> getParent() const;
std::wstring getTemplateSuffix(const std::vector<std::wstring>& elements) const;
virtual NameHierarchy toNameHierarchy() const = 0;
private:
@@ -27,11 +27,10 @@ bool CxxQualifierFlags::empty() const
std::wstring CxxQualifierFlags::toString() const
{
std::wstring ret = L"";
if (m_flags & QUALIFIER_CONST)
{
ret += L"const";
return L"const";
}
return ret;
}
return L"";
}
@@ -1,51 +1,13 @@
#include "CxxStaticFunctionDeclName.h"
//CxxStaticFunctionDeclName::CxxStaticFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const std::wstring& translationUnitFileName
//)
// : CxxFunctionDeclName(name, templateParameterNames, returnTypeName, parameterTypeNames, false, true)
// , m_translationUnitFileName(translationUnitFileName)
//{
//}
CxxStaticFunctionDeclName::CxxStaticFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
std::wstring&& translationUnitFileName
std::wstring name,
std::vector<std::wstring> templateParameterNames,
std::unique_ptr<CxxTypeName> returnTypeName,
std::vector<std::unique_ptr<CxxTypeName>> parameterTypeNames,
std::wstring translationUnitFileName
)
: CxxFunctionDeclName(std::move(name), std::move(templateParameterNames), returnTypeName, std::move(parameterTypeNames), false, true)
, m_translationUnitFileName(std::move(translationUnitFileName))
{
}
//CxxStaticFunctionDeclName::CxxStaticFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const std::wstring& translationUnitFileName,
// std::shared_ptr<CxxName> parent
//)
// : CxxFunctionDeclName(name, templateParameterNames, returnTypeName, parameterTypeNames, false, true, parent)
// , m_translationUnitFileName(translationUnitFileName)
//{
//}
CxxStaticFunctionDeclName::CxxStaticFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
std::wstring&& translationUnitFileName,
std::shared_ptr<CxxName> parent
)
: CxxFunctionDeclName(std::move(name), std::move(templateParameterNames), returnTypeName, std::move(parameterTypeNames), false, true, parent)
: CxxFunctionDeclName(std::move(name), std::move(templateParameterNames), std::move(returnTypeName), std::move(parameterTypeNames), false, true)
, m_translationUnitFileName(std::move(translationUnitFileName))
{
}
@@ -53,16 +15,9 @@ CxxStaticFunctionDeclName::CxxStaticFunctionDeclName(
NameHierarchy CxxStaticFunctionDeclName::toNameHierarchy() const
{
NameHierarchy ret = CxxFunctionDeclName::toNameHierarchy();
const NameElement::Signature sig = ret.back()->getSignature();
std::shared_ptr<NameElement> nameElement = std::make_shared<NameElement>(
ret.back()->getName(),
sig.getPrefix(),
sig.getPostfix() + L" (" + m_translationUnitFileName + L")"
ret.back()->setSignature(
ret.back()->getSignature().getPrefix(),
ret.back()->getSignature().getPostfix() + L" (" + m_translationUnitFileName + L')'
);
ret.pop();
ret.push(nameElement);
return ret;
}
@@ -3,46 +3,19 @@
#include "CxxFunctionDeclName.h"
class CxxStaticFunctionDeclName: public CxxFunctionDeclName
class CxxStaticFunctionDeclName
: public CxxFunctionDeclName
{
public:
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxStaticFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const std::wstring& translationUnitFileName
//);
CxxStaticFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
std::wstring&& translationUnitFileName
std::wstring name,
std::vector<std::wstring> templateParameterNames,
std::unique_ptr<CxxTypeName> returnTypeName,
std::vector<std::unique_ptr<CxxTypeName>> parameterTypeNames,
std::wstring translationUnitFileName
);
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxStaticFunctionDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> returnTypeName,
// const std::vector<std::shared_ptr<CxxTypeName>>& parameterTypeNames,
// const std::wstring& translationUnitFileName,
// std::shared_ptr<CxxName> parent
//);
CxxStaticFunctionDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>>&& parameterTypeNames,
std::wstring&& translationUnitFileName,
std::shared_ptr<CxxName> parent
);
virtual NameHierarchy toNameHierarchy() const;
NameHierarchy toNameHierarchy() const override;
private:
std::wstring m_translationUnitFileName;
@@ -1,47 +1,36 @@
#include "CxxTypeName.h"
std::shared_ptr<CxxTypeName> CxxTypeName::makeUnsolvedIfNull(std::shared_ptr<CxxTypeName> name)
#include <sstream>
std::unique_ptr<CxxTypeName> CxxTypeName::makeUnsolvedIfNull(std::unique_ptr<CxxTypeName> name)
{
if (name)
{
return name;
}
return std::make_shared<CxxTypeName>(
L"unsolved-type", std::vector<std::wstring>()
);
return std::make_unique<CxxTypeName>(L"unsolved-type");
}
CxxTypeName::Modifier::Modifier(std::wstring&& symbol)
CxxTypeName::Modifier::Modifier(std::wstring symbol)
: symbol(std::move(symbol))
{
}
//CxxTypeName::CxxTypeName(const std::wstring& name, const std::vector<std::wstring>& templateArguments)
// : m_name(name)
// , m_templateArguments(templateArguments)
//{
//}
CxxTypeName::CxxTypeName(std::wstring name)
: m_name(std::move(name))
{
}
CxxTypeName::CxxTypeName(std::wstring&& name, std::vector<std::wstring>&& templateArguments)
CxxTypeName::CxxTypeName(std::wstring name, std::vector<std::wstring> templateArguments)
: m_name(std::move(name))
, m_templateArguments(std::move(templateArguments))
{
}
//CxxTypeName::CxxTypeName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateArguments,
// std::shared_ptr<CxxName> parent
//)
// : CxxName(parent)
// , m_name(name)
// , m_templateArguments(templateArguments)
//{
//}
CxxTypeName::CxxTypeName(
std::wstring&& name,
std::vector<std::wstring>&& templateArguments,
std::wstring name,
std::vector<std::wstring> templateArguments,
std::shared_ptr<CxxName> parent
)
: CxxName(parent)
@@ -52,8 +41,8 @@ CxxTypeName::CxxTypeName(
NameHierarchy CxxTypeName::toNameHierarchy() const
{
NameHierarchy ret = getParent() ? getParent()->toNameHierarchy(): NameHierarchy(NAME_DELIMITER_CXX);
ret.push(std::make_shared<NameElement>(getTypeNameString()));
NameHierarchy ret = getParent() ? getParent()->toNameHierarchy() : NameHierarchy(NAME_DELIMITER_CXX);
ret.push(std::make_shared<NameElement>(m_name + getTemplateSuffix(m_templateArguments)));
return ret;
}
@@ -69,46 +58,28 @@ void CxxTypeName::addQualifier(const CxxQualifierFlags::QualifierType qualifier)
}
}
void CxxTypeName::addModifier(const Modifier& modifier)
void CxxTypeName::addModifier(Modifier modifier)
{
m_modifiers.push_back(modifier);
m_modifiers.emplace_back(std::move(modifier));
}
std::wstring CxxTypeName::toString() const
{
std::wstring ret = L"";
std::wstringstream ss;
if (!m_qualifierFlags.empty())
{
ret += m_qualifierFlags.toString() + L" ";
ss << m_qualifierFlags.toString() << L' ';
}
ret += toNameHierarchy().getQualifiedName();
for (const Modifier& modifier: m_modifiers)
ss << toNameHierarchy().getQualifiedName();
for (const Modifier& modifier : m_modifiers)
{
ret += L" " + modifier.symbol;
ss << L' ' << modifier.symbol;
if (!modifier.qualifierFlags.empty())
{
ret += L" " + modifier.qualifierFlags.toString();
ss << L' ' << modifier.qualifierFlags.toString();
}
}
return ret;
}
std::wstring CxxTypeName::getTypeNameString() const
{
std::wstring ret = m_name;
if (!m_templateArguments.empty())
{
ret += L"<";
for (size_t i = 0; i < m_templateArguments.size(); i++)
{
if (i != 0)
{
ret += L", ";
}
ret += m_templateArguments[i];
}
ret += L">";
}
return ret;
return ss.str();
}
+15 -26
View File
@@ -9,54 +9,43 @@
#include "CxxName.h"
#include "CxxQualifierFlags.h"
class CxxTypeName: public CxxName
class CxxTypeName
: public CxxName
{
public:
static std::shared_ptr<CxxTypeName> makeUnsolvedIfNull(std::shared_ptr<CxxTypeName> name);
static std::unique_ptr<CxxTypeName> makeUnsolvedIfNull(std::unique_ptr<CxxTypeName> name);
struct Modifier
{
Modifier(std::wstring&& symbol);
std::wstring symbol;
Modifier(std::wstring symbol);
const std::wstring symbol;
CxxQualifierFlags qualifierFlags;
};
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxTypeName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateArguments
//);
CxxTypeName(std::wstring name);
CxxTypeName(
std::wstring&& name,
std::vector<std::wstring>&& templateArguments
std::wstring name,
std::vector<std::wstring> templateArguments
);
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxTypeName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateArguments,
// std::shared_ptr<CxxName> parent
//);
CxxTypeName(
std::wstring&& name,
std::vector<std::wstring>&& templateArguments,
std::wstring name,
std::vector<std::wstring> templateArguments,
std::shared_ptr<CxxName> parent
);
virtual NameHierarchy toNameHierarchy() const;
NameHierarchy toNameHierarchy() const override;
void addQualifier(const CxxQualifierFlags::QualifierType qualifier);
void addModifier(const Modifier& modifier);
void addModifier(Modifier modifier);
std::wstring toString() const;
private:
std::wstring getTypeNameString() const;
std::wstring m_name;
std::vector<std::wstring> m_templateArguments;
const std::wstring m_name;
const std::vector<std::wstring> m_templateArguments;
CxxQualifierFlags m_qualifierFlags;
std::vector<Modifier> m_modifiers;
@@ -1,51 +1,13 @@
#include "CxxVariableDeclName.h"
//CxxVariableDeclName::CxxVariableDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> typeName,
// bool isStatic
//)
// : CxxDeclName(name, templateParameterNames)
// , m_typeName(typeName)
// , m_isStatic(isStatic)
//{
//}
CxxVariableDeclName::CxxVariableDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> typeName,
std::wstring name,
std::vector<std::wstring> templateParameterNames,
std::unique_ptr<CxxTypeName> typeName,
bool isStatic
)
: CxxDeclName(std::move(name), std::move(templateParameterNames))
, m_typeName(typeName)
, m_isStatic(isStatic)
{
}
//CxxVariableDeclName::CxxVariableDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> typeName,
// bool isStatic,
// std::shared_ptr<CxxName> parent
//)
// : CxxDeclName(name, templateParameterNames, parent)
// , m_typeName(typeName)
// , m_isStatic(isStatic)
//{
//}
CxxVariableDeclName::CxxVariableDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> typeName,
bool isStatic,
std::shared_ptr<CxxName> parent
)
: CxxDeclName(std::move(name), std::move(templateParameterNames), parent)
, m_typeName(typeName)
, m_typeName(std::move(typeName))
, m_isStatic(isStatic)
{
}
@@ -57,19 +19,9 @@ NameHierarchy CxxVariableDeclName::toNameHierarchy() const
{
signaturePrefix += L"static ";
}
signaturePrefix += CxxTypeName::makeUnsolvedIfNull(m_typeName)->toString();
const std::wstring signaturePostfix;
signaturePrefix += m_typeName->toString();
NameHierarchy ret = CxxDeclName::toNameHierarchy();
std::shared_ptr<NameElement> nameElement = std::make_shared<NameElement>(
ret.back()->getName(),
std::move(signaturePrefix),
std::move(signaturePostfix)
);
ret.pop();
ret.push(nameElement);
ret.back()->setSignature(std::move(signaturePrefix), L"");
return ret;
}
@@ -7,46 +7,22 @@
#include "CxxDeclName.h"
#include "CxxTypeName.h"
class CxxVariableDeclName: public CxxDeclName
class CxxVariableDeclName
: public CxxDeclName
{
public:
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxVariableDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> typeName,
// bool isStatic
//);
CxxVariableDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> typeName,
std::wstring name,
std::vector<std::wstring> templateParameterNames,
std::unique_ptr<CxxTypeName> typeName,
bool isStatic
);
// uncomment this constructor if required, but try to use the one using move constructors for the members
//CxxVariableDeclName(
// const std::wstring& name,
// const std::vector<std::wstring>& templateParameterNames,
// std::shared_ptr<CxxTypeName> typeName,
// bool isStatic,
// std::shared_ptr<CxxName> parent
//);
CxxVariableDeclName(
std::wstring&& name,
std::vector<std::wstring>&& templateParameterNames,
std::shared_ptr<CxxTypeName> typeName,
bool isStatic,
std::shared_ptr<CxxName> parent
);
virtual NameHierarchy toNameHierarchy() const;
NameHierarchy toNameHierarchy() const override;
private:
std::shared_ptr<CxxTypeName> m_typeName;
bool m_isStatic;
std::unique_ptr<CxxTypeName> m_typeName;
const bool m_isStatic;
};
#endif // CXX_VARIABLE_DECL_NAME_H
@@ -11,30 +11,25 @@
#include "CxxTypeNameResolver.h"
#include "CanonicalFilePathCache.h"
#include "utilityClang.h"
#include "FilePath.h"
#include "ScopedSwitcher.h"
#include "utilityString.h"
CxxDeclNameResolver::CxxDeclNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache, std::vector<const clang::Decl*>())
CxxDeclNameResolver::CxxDeclNameResolver(CanonicalFilePathCache* canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache)
, m_currentDecl(nullptr)
{
}
CxxDeclNameResolver::CxxDeclNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
)
: CxxNameResolver(canonicalFilePathCache, ignoredContextDecls)
CxxDeclNameResolver::CxxDeclNameResolver(const CxxNameResolver* other)
: CxxNameResolver(other)
, m_currentDecl(nullptr)
{
}
std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl* declaration)
std::unique_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl* declaration)
{
declaration = utility::getFirstDecl(declaration);
std::shared_ptr<CxxDeclName> declName;
if ((declaration) &&
(clang::isa<clang::CXXRecordDecl>(declaration)) &&
(clang::dyn_cast<clang::CXXRecordDecl>(declaration)->isLambda()))
@@ -45,8 +40,7 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl
clang::DeclContext::lookup_result Calls = clang::dyn_cast<clang::CXXRecordDecl>(declaration)->lookup(Name);
if (Calls.empty())
{
declaration = nullptr;
declName = std::make_shared<CxxDeclName>(L"unsolved-lambda", std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(L"unsolved-lambda");
}
else
{
@@ -54,94 +48,95 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl
}
}
if (declaration)
if (!declaration)
{
declName = getDeclName(clang::dyn_cast<const clang::NamedDecl>(declaration));
return nullptr;
}
if (declName)
std::unique_ptr<CxxDeclName> declName = getDeclName(clang::dyn_cast<const clang::NamedDecl>(declaration));
if (declName)
{
if (const clang::UsingDecl* usingDecl = clang::dyn_cast_or_null<clang::UsingDecl>(declaration))
{
if (const clang::UsingDecl* usingDecl = clang::dyn_cast_or_null<clang::UsingDecl>(declaration))
declName->setParent(CxxSpecifierNameResolver(this).getName(usingDecl->getQualifier()));
}
else if (
clang::isa<clang::TemplateTypeParmDecl>(declaration) ||
clang::isa<clang::NonTypeTemplateParmDecl>(declaration) ||
clang::isa<clang::TemplateTemplateParmDecl>(declaration)
) {
clang::ASTContext::DynTypedNodeList parents = declaration->getASTContext().getParents(*declaration);
for (const clang::ast_type_traits::DynTypedNode* parent = parents.begin(); parent != parents.end(); parent++)
{
CxxSpecifierNameResolver specifierNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
declName->setParent(specifierNameResolver.getName(usingDecl->getQualifier()));
}
else if (
clang::isa<clang::TemplateTypeParmDecl>(declaration) ||
clang::isa<clang::NonTypeTemplateParmDecl>(declaration) ||
clang::isa<clang::TemplateTemplateParmDecl>(declaration)
) {
clang::ASTContext& context = declaration->getASTContext();
clang::ASTContext::DynTypedNodeList parents = context.getParents(*declaration);
for (const clang::ast_type_traits::DynTypedNode* parent = parents.begin(); parent != parents.end(); parent++)
const clang::Decl* parentDecl = parent->get<clang::Decl>();
while (parentDecl != nullptr)
{
const clang::Decl* parentDecl = parent->get<clang::Decl>();
while (parentDecl != nullptr)
parentDecl = utility::getFirstDecl(parentDecl);
if (clang::isa<clang::TemplateDecl>(parentDecl))
{
parentDecl = utility::getFirstDecl(parentDecl);
const clang::TemplateDecl* parentTemplateDecl = clang::dyn_cast_or_null<clang::TemplateDecl>(parentDecl);
if (!ignoresContext(parentTemplateDecl) && !ignoresContext(parentTemplateDecl->getTemplatedDecl()))
{
declName->setParent(getName(parentTemplateDecl));
}
break;
}
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(parentDecl))
{
const clang::ClassTemplatePartialSpecializationDecl* parentClassTemplateDecl =
clang::dyn_cast_or_null<clang::ClassTemplatePartialSpecializationDecl>(parentDecl);
if (!ignoresContext(parentDecl))
{
declName->setParent(getName(parentClassTemplateDecl));
}
break;
}
else if (clang::isa<clang::VarTemplatePartialSpecializationDecl>(parentDecl))
{
const clang::VarTemplatePartialSpecializationDecl* parentVarTemplateDecl =
clang::dyn_cast_or_null<clang::VarTemplatePartialSpecializationDecl>(parentDecl);
if (!ignoresContext(parentDecl))
{
declName->setParent(getName(parentVarTemplateDecl));
}
break;
}
if (clang::isa<clang::TemplateDecl>(parentDecl))
{
const clang::TemplateDecl* parentTemplateDecl = clang::dyn_cast_or_null<clang::TemplateDecl>(parentDecl);
if (!ignoresContext(parentTemplateDecl) && !ignoresContext(parentTemplateDecl->getTemplatedDecl()))
{
declName->setParent(getName(parentTemplateDecl));
}
break;
}
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(parentDecl))
{
const clang::ClassTemplatePartialSpecializationDecl* parentClassTemplateDecl = clang::dyn_cast_or_null<clang::ClassTemplatePartialSpecializationDecl>(parentDecl);
if (!ignoresContext(parentDecl))
{
declName->setParent(getName(parentClassTemplateDecl));
}
break;
}
else if (clang::isa<clang::VarTemplatePartialSpecializationDecl>(parentDecl))
{
const clang::VarTemplatePartialSpecializationDecl* parentVarTemplateDecl = clang::dyn_cast_or_null<clang::VarTemplatePartialSpecializationDecl>(parentDecl);
if (!ignoresContext(parentDecl))
{
declName->setParent(getName(parentVarTemplateDecl));
}
break;
}
if (const clang::DeclContext* parentDeclContext = parentDecl->getDeclContext())
{
if (ignoresContext(parentDeclContext))
{
break;
}
parentDecl = clang::dyn_cast_or_null<clang::Decl>(parentDeclContext);
if (parentDecl)
{
if (clang::TemplateDecl* describedTemplate = parentDecl->getDescribedTemplate())
{
parentDecl = describedTemplate;
}
}
}
else
if (const clang::DeclContext* parentDeclContext = parentDecl->getDeclContext())
{
if (ignoresContext(parentDeclContext))
{
break;
}
parentDecl = clang::dyn_cast_or_null<clang::Decl>(parentDeclContext);
if (parentDecl)
{
if (clang::TemplateDecl* describedTemplate = parentDecl->getDescribedTemplate())
{
parentDecl = describedTemplate;
}
}
}
else
{
break;
}
}
}
else
{
declName->setParent(getContextName(declaration->getDeclContext()));
}
}
else
{
declName->setParent(getContextName(declaration->getDeclContext()));
}
}
return declName;
}
std::shared_ptr<CxxName> CxxDeclNameResolver::getContextName(const clang::DeclContext* declContext)
std::unique_ptr<CxxName> CxxDeclNameResolver::getContextName(const clang::DeclContext* declContext)
{
std::shared_ptr<CxxName> contextDeclName;
std::unique_ptr<CxxName> contextDeclName;
if (declContext && !ignoresContext(declContext))
{
@@ -161,7 +156,7 @@ std::shared_ptr<CxxName> CxxDeclNameResolver::getContextName(const clang::DeclCo
return contextDeclName;
}
std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
std::unique_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
{
if (declaration)
{
@@ -189,7 +184,7 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
if (recordDecl->isLambda())
{
// we skip this node because its child (the lambda call operator) has already been recorded.
return std::shared_ptr<CxxDeclName>();
return std::unique_ptr<CxxDeclName>();
}
else if (declNameString.empty())
{
@@ -203,20 +198,19 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
symbolKindName = L"union";
}
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(symbolKindName, declaration), std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(getNameForAnonymousSymbol(symbolKindName, declaration));
}
else if (const clang::CXXRecordDecl* cxxRecordDecl = clang::dyn_cast_or_null<clang::CXXRecordDecl>(declaration))
{
clang::ClassTemplateDecl* templateClassDeclaration = cxxRecordDecl->getDescribedClassTemplate();
if (templateClassDeclaration)
if (clang::ClassTemplateDecl* templateClassDeclaration = cxxRecordDecl->getDescribedClassTemplate())
{
return getDeclName(templateClassDeclaration);
}
else if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(declaration))
{
return std::make_shared<CxxDeclName>(
return std::make_unique<CxxDeclName>(
std::move(declNameString),
getTemplateParameterStringsOfPatrialSpecialitarion(
getTemplateParameterStringsOfPartialSpecialization(
clang::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(declaration)
)
);
@@ -224,12 +218,13 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
{
std::vector<std::wstring> templateArguments;
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
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>(std::move(declNameString), std::move(templateArguments));
return std::make_unique<CxxDeclName>(std::move(declNameString), std::move(templateArguments));
}
}
}
@@ -244,7 +239,8 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
(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());
const clang::PresumedLoc& presumedBegin =
sourceManager.getPresumedLoc(clang::dyn_cast_or_null<clang::CXXMethodDecl>(functionDecl)->getParent()->getLocStart());
functionName = L"lambda at " + std::to_wstring(presumedBegin.getLine()) + L":" + std::to_wstring(presumedBegin.getColumn());
}
else if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
@@ -275,31 +271,33 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
isStatic = functionDecl->getStorageClass() == clang::SC_Static;
}
CxxTypeNameResolver typenNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
CxxTypeNameResolver typenNameResolver(this);
typenNameResolver.ignoreContextDecl(functionDecl);
std::shared_ptr<CxxTypeName> returnTypeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->getReturnType()));
std::unique_ptr<CxxTypeName> returnTypeName =
CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->getReturnType()));
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames;
std::vector<std::unique_ptr<CxxTypeName>> parameterTypeNames;
for (unsigned int i = 0; i < functionDecl->param_size(); i++)
{
parameterTypeNames.push_back(CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->parameters()[i]->getType())));
parameterTypeNames.push_back(
CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(functionDecl->parameters()[i]->getType())));
}
if (!clang::isa<clang::CXXMethodDecl>(declaration) && isStatic)
{
return std::make_shared<CxxStaticFunctionDeclName>(
return std::make_unique<CxxStaticFunctionDeclName>(
std::move(functionName),
std::move(templateArguments),
returnTypeName,
std::move(returnTypeName),
std::move(parameterTypeNames),
getTranslationUnitMainFileName(declaration)
);
}
return std::make_shared<CxxFunctionDeclName>(
return std::make_unique<CxxFunctionDeclName>(
std::move(functionName),
std::move(templateArguments),
returnTypeName,
std::move(returnTypeName),
std::move(parameterTypeNames),
isConst,
isStatic
@@ -313,19 +311,19 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
else if (clang::isa<clang::FieldDecl>(declaration))
{
const clang::FieldDecl* fieldDecl = clang::dyn_cast<clang::FieldDecl>(declaration);
CxxTypeNameResolver typenNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
CxxTypeNameResolver typenNameResolver(this);
typenNameResolver.ignoreContextDecl(fieldDecl);
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(fieldDecl->getType()));
return std::make_shared<CxxVariableDeclName>(std::move(declNameString), std::vector<std::wstring>(), typeName, false);
std::unique_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(fieldDecl->getType()));
return std::make_unique<CxxVariableDeclName>(std::move(declNameString), std::vector<std::wstring>(), std::move(typeName), false);
}
else if (clang::isa<clang::NamespaceDecl>(declaration) && clang::dyn_cast<clang::NamespaceDecl>(declaration)->isAnonymousNamespace())
{
declaration = clang::dyn_cast<clang::NamespaceDecl>(declaration)->getOriginalNamespace();
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(L"namespace", declaration), std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(getNameForAnonymousSymbol(L"namespace", declaration));
}
else if (clang::isa<clang::EnumDecl>(declaration) && declNameString.empty())
{
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(L"enum", declaration), std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(getNameForAnonymousSymbol(L"enum", declaration));
}
else if (
(
@@ -334,11 +332,11 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
clang::isa<clang::TemplateTemplateParmDecl>(declaration)
) && declNameString.empty())
{
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(L"template parameter", declaration), std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(getNameForAnonymousSymbol(L"template parameter", declaration));
}
else if (clang::isa<clang::ParmVarDecl>(declaration) && declNameString.empty())
{
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(L"parameter", declaration), std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(getNameForAnonymousSymbol(L"parameter", declaration));
}
else if (clang::isa<clang::VarDecl>(declaration))
{
@@ -356,32 +354,32 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
// nothing todo, varDecl is global (and non-static)
}
CxxTypeNameResolver typenNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
CxxTypeNameResolver typenNameResolver(this);
typenNameResolver.ignoreContextDecl(varDecl);
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(varDecl->getType()));
std::unique_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(varDecl->getType()));
std::wstring varName = declNameString;
if (utility::getSymbolKind(varDecl) == SYMBOL_GLOBAL_VARIABLE &&
varDecl->getStorageClass() == clang::SC_Static)
{
// if a global variable is static it is only visible in the current translation unit. Therefore if multiple instances of that global variable
// may be generated (one for each translation unit) we add the name of the translation unit's source file.
// If that global variable definition is const, we add the name of the (maybe header) file that variable is defined in instead. This causes
// different instances of the variable that all MUST contain the same value to be merged into a single node in Sourcetrail.
std::wstring scopeFileName = L"";
// if a global variable is static it is only visible in the current translation unit. Therefore if multiple
// instances of that global variable may be generated (one for each translation unit) we add the name of the
// translation unit's source file. If that global variable definition is const, we add the name of the
// (maybe header) file that variable is defined in instead. This causes different instances of the variable
// that all MUST contain the same value to be merged into a single node in Sourcetrail.
std::wstring scopeFileName;
if (varDecl->getType().isConstQualified())
{
if (varDecl->getType().isConstQualified())
{
scopeFileName = getDeclarationFileName(declaration);
}
else
{
scopeFileName = getTranslationUnitMainFileName(declaration);
}
scopeFileName = getDeclarationFileName(declaration);
}
else
{
scopeFileName = getTranslationUnitMainFileName(declaration);
}
if (!scopeFileName.empty())
{
varName = declNameString + L" (" + scopeFileName + L")";
varName = declNameString + L" (" + scopeFileName + L')';
}
}
@@ -393,20 +391,22 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
}
else if (clang::isa<clang::VarTemplatePartialSpecializationDecl>(declaration))
{
templateParameterNames = getTemplateParameterStringsOfPatrialSpecialitarion(clang::dyn_cast<clang::VarTemplatePartialSpecializationDecl>(declaration));
templateParameterNames = getTemplateParameterStringsOfPartialSpecialization(
clang::dyn_cast<clang::VarTemplatePartialSpecializationDecl>(declaration));
}
else if (clang::isa<clang::VarTemplateSpecializationDecl>(declaration))
{
const clang::VarTemplateSpecializationDecl* templateSpecializationDeclaration = clang::dyn_cast_or_null<clang::VarTemplateSpecializationDecl>(varDecl);
const clang::VarTemplateSpecializationDecl* templateSpecializationDeclaration =
clang::dyn_cast_or_null<clang::VarTemplateSpecializationDecl>(varDecl);
const clang::TemplateArgumentList& templateArgumentList = templateSpecializationDeclaration->getTemplateArgs();
for (size_t i = 0; i < templateArgumentList.size(); i++)
{
const clang::TemplateArgument& templateArgument = templateArgumentList.get(i);
templateParameterNames.push_back(getTemplateArgumentName(templateArgument));
templateParameterNames.push_back(getTemplateArgumentName(templateArgumentList.get(i)));
}
}
return std::make_shared<CxxVariableDeclName>(std::move(varName), std::move(templateParameterNames), typeName, isStatic);
return std::make_unique<CxxVariableDeclName>(
std::move(varName), std::move(templateParameterNames), std::move(typeName), isStatic);
}
}
else if (clang::isa<clang::VarTemplateDecl>(declaration))
@@ -416,17 +416,20 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
}
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
{
return std::make_shared<CxxDeclName>(std::move(declNameString), getTemplateParameterStrings(clang::dyn_cast<clang::TemplateDecl>(declaration)));
return std::make_unique<CxxDeclName>(
std::move(declNameString),
getTemplateParameterStrings(clang::dyn_cast<clang::TemplateDecl>(declaration))
);
}
if (!declNameString.empty())
{
return std::make_shared<CxxDeclName>(std::move(declNameString), std::vector<std::wstring>(), std::shared_ptr<CxxName>());
return std::make_unique<CxxDeclName>(std::move(declNameString));
}
}
// LOG_ERROR("could not resolve name of decl at: " + declaration->getLocation().printToString(sourceManager));
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(L"symbol", declaration), std::vector<std::wstring>());
return std::make_unique<CxxDeclName>(getNameForAnonymousSymbol(L"symbol", declaration));
}
std::wstring CxxDeclNameResolver::getTranslationUnitMainFileName(const clang::Decl* declaration)
@@ -456,7 +459,8 @@ std::wstring CxxDeclNameResolver::getNameForAnonymousSymbol(const std::wstring&
if (presumedBegin.isValid())
{
return L"anonymous " + symbolKindName +
L" (" + getDeclarationFileName(declaration) + L"<" + std::to_wstring(presumedBegin.getLine()) + L":" + std::to_wstring(presumedBegin.getColumn()) + L">)";
L" (" + getDeclarationFileName(declaration) + L'<' + std::to_wstring(presumedBegin.getLine()) + L':' +
std::to_wstring(presumedBegin.getColumn()) + L">)";
}
return L"anonymous " + symbolKindName;
}
@@ -474,7 +478,7 @@ std::vector<std::wstring> CxxDeclNameResolver::getTemplateParameterStrings(const
std::wstring CxxDeclNameResolver::getTemplateParameterString(const clang::NamedDecl* parameter)
{
CxxTemplateParameterStringResolver parameterStringResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
CxxTemplateParameterStringResolver parameterStringResolver(this);
if (clang::isa<clang::TemplateDecl>(m_currentDecl) && clang::dyn_cast<clang::TemplateDecl>(m_currentDecl)->getTemplatedDecl())
{
parameterStringResolver.ignoreContextDecl(clang::dyn_cast<clang::TemplateDecl>(m_currentDecl)->getTemplatedDecl());
@@ -490,8 +494,5 @@ std::wstring CxxDeclNameResolver::getTemplateParameterString(const clang::NamedD
std::wstring CxxDeclNameResolver::getTemplateArgumentName(const clang::TemplateArgument& argument)
{
CxxTemplateArgumentNameResolver resolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
return resolver.getTemplateArgumentName(argument);
return CxxTemplateArgumentNameResolver(this).getTemplateArgumentName(argument);
}
@@ -8,26 +8,24 @@
class CanonicalFilePathCache;
class CxxDeclNameResolver: public CxxNameResolver
class CxxDeclNameResolver
: public CxxNameResolver
{
public:
CxxDeclNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache);
CxxDeclNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
);
CxxDeclNameResolver(CanonicalFilePathCache* canonicalFilePathCache);
CxxDeclNameResolver(const CxxNameResolver* other);
std::shared_ptr<CxxDeclName> getName(const clang::NamedDecl* declaration);
std::unique_ptr<CxxDeclName> getName(const clang::NamedDecl* declaration);
private:
std::shared_ptr<CxxName> getContextName(const clang::DeclContext* declaration);
std::shared_ptr<CxxDeclName> getDeclName(const clang::NamedDecl* declaration);
std::unique_ptr<CxxName> getContextName(const clang::DeclContext* declaration);
std::unique_ptr<CxxDeclName> getDeclName(const clang::NamedDecl* declaration);
std::wstring getTranslationUnitMainFileName(const clang::Decl* declaration);
std::wstring getDeclarationFileName(const clang::Decl* declaration);
std::wstring getNameForAnonymousSymbol(const std::wstring& symbolKindName, const clang::Decl* declaration);
std::vector<std::wstring> getTemplateParameterStrings(const clang::TemplateDecl* templateDecl);
template <typename T>
std::vector<std::wstring> getTemplateParameterStringsOfPatrialSpecialitarion(const T* templateDecl);
std::vector<std::wstring> getTemplateParameterStringsOfPartialSpecialization(const T* templateDecl);
std::wstring getTemplateParameterString(const clang::NamedDecl* parameter);
std::wstring getTemplateArgumentName(const clang::TemplateArgument& argument);
@@ -36,7 +34,7 @@ private:
template <typename T>
std::vector<std::wstring> CxxDeclNameResolver::getTemplateParameterStringsOfPatrialSpecialitarion(const T* partialSpecializationDecl)
std::vector<std::wstring> CxxDeclNameResolver::getTemplateParameterStringsOfPartialSpecialization(const T* partialSpecializationDecl)
{
std::vector<std::wstring> templateParameterNames;
clang::TemplateParameterList* parameterList = partialSpecializationDecl->getTemplateParameters();
@@ -1,11 +1,13 @@
#include "CxxNameResolver.h"
CxxNameResolver::CxxNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
)
CxxNameResolver::CxxNameResolver(CanonicalFilePathCache* canonicalFilePathCache)
: m_canonicalFilePathCache(canonicalFilePathCache)
, m_ignoredContextDecls(ignoredContextDecls)
{
}
CxxNameResolver::CxxNameResolver(const CxxNameResolver* other)
: m_canonicalFilePathCache(other->getCanonicalFilePathCache())
, m_ignoredContextDecls(other->getIgnoredContextDecls())
{
}
@@ -13,17 +15,17 @@ void CxxNameResolver::ignoreContextDecl(const clang::Decl* decl)
{
if (decl)
{
m_ignoredContextDecls.push_back(decl);
m_ignoredContextDecls.emplace_back(decl);
}
}
bool CxxNameResolver::ignoresContext(const clang::Decl* decl)
bool CxxNameResolver::ignoresContext(const clang::Decl* decl) const
{
if (decl)
{
for (size_t i = 0; i < m_ignoredContextDecls.size(); i++)
for (const clang::Decl* ignoredDecl : m_ignoredContextDecls)
{
if (decl == m_ignoredContextDecls[i])
if (decl == ignoredDecl)
{
return true;
}
@@ -32,7 +34,7 @@ bool CxxNameResolver::ignoresContext(const clang::Decl* decl)
return false;
}
bool CxxNameResolver::ignoresContext(const clang::DeclContext* declContext)
bool CxxNameResolver::ignoresContext(const clang::DeclContext* declContext) const
{
if (const clang::Decl* decl = clang::dyn_cast_or_null<clang::Decl>(declContext))
{
@@ -41,12 +43,12 @@ bool CxxNameResolver::ignoresContext(const clang::DeclContext* declContext)
return false;
}
std::shared_ptr<CanonicalFilePathCache> CxxNameResolver::getCanonicalFilePathCache() const
CanonicalFilePathCache* CxxNameResolver::getCanonicalFilePathCache() const
{
return m_canonicalFilePathCache;
}
std::vector<const clang::Decl*> CxxNameResolver::getIgnoredContextDecls() const
const std::vector<const clang::Decl*>& CxxNameResolver::getIgnoredContextDecls() const
{
return m_ignoredContextDecls;
}
@@ -10,22 +10,19 @@ class CanonicalFilePathCache;
class CxxNameResolver
{
public:
CxxNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
);
virtual ~CxxNameResolver() = default;
CxxNameResolver(CanonicalFilePathCache* canonicalFilePathCache);
CxxNameResolver(const CxxNameResolver* other);
void ignoreContextDecl(const clang::Decl* decl);
bool ignoresContext(const clang::Decl* decl);
bool ignoresContext(const clang::DeclContext* declContext);
bool ignoresContext(const clang::Decl* decl) const;
bool ignoresContext(const clang::DeclContext* declContext) const;
protected:
std::shared_ptr<CanonicalFilePathCache> getCanonicalFilePathCache() const;
std::vector<const clang::Decl*> getIgnoredContextDecls() const;
CanonicalFilePathCache* getCanonicalFilePathCache() const;
const std::vector<const clang::Decl*>& getIgnoredContextDecls() const;
private:
std::shared_ptr<CanonicalFilePathCache> m_canonicalFilePathCache;
CanonicalFilePathCache* m_canonicalFilePathCache;
std::vector<const clang::Decl*> m_ignoredContextDecls;
};
@@ -8,23 +8,18 @@
#include "CxxDeclNameResolver.h"
#include "utilityString.h"
CxxSpecifierNameResolver::CxxSpecifierNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache, std::vector<const clang::Decl*>())
CxxSpecifierNameResolver::CxxSpecifierNameResolver(CanonicalFilePathCache* canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache)
{
}
CxxSpecifierNameResolver::CxxSpecifierNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
)
: CxxNameResolver(canonicalFilePathCache, ignoredContextDecls)
CxxSpecifierNameResolver::CxxSpecifierNameResolver(const CxxNameResolver* other)
: CxxNameResolver(other)
{
}
std::shared_ptr<CxxName> CxxSpecifierNameResolver::getName(const clang::NestedNameSpecifier* nestedNameSpecifier)
std::unique_ptr<CxxName> CxxSpecifierNameResolver::getName(const clang::NestedNameSpecifier* nestedNameSpecifier)
{
std::shared_ptr<CxxName> name;
if (nestedNameSpecifier)
{
clang::NestedNameSpecifier::SpecifierKind nnsKind = nestedNameSpecifier->getKind();
@@ -32,50 +27,38 @@ std::shared_ptr<CxxName> CxxSpecifierNameResolver::getName(const clang::NestedNa
{
case clang::NestedNameSpecifier::Identifier:
{
name = std::make_shared<CxxDeclName>(
utility::decodeFromUtf8(nestedNameSpecifier->getAsIdentifier()->getName()), std::vector<std::wstring>()
);
std::unique_ptr<CxxName> name = std::make_unique<CxxDeclName>(utility::decodeFromUtf8(nestedNameSpecifier->getAsIdentifier()->getName()));
if (const clang::NestedNameSpecifier* prefix = nestedNameSpecifier->getPrefix())
{
std::shared_ptr<CxxName> parentName = getName(prefix);
std::unique_ptr<CxxName> parentName = getName(prefix);
if (parentName)
{
name->setParent(parentName);
name->setParent(std::move(parentName));
}
}
return name;
}
break;
case clang::NestedNameSpecifier::Namespace:
{
CxxDeclNameResolver declNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespace());
}
break;
return CxxDeclNameResolver(this).getName(nestedNameSpecifier->getAsNamespace());
case clang::NestedNameSpecifier::NamespaceAlias:
{
CxxDeclNameResolver declNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespaceAlias());
}
break;
return CxxDeclNameResolver(this).getName(nestedNameSpecifier->getAsNamespaceAlias());
case clang::NestedNameSpecifier::TypeSpec:
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
{
CxxTypeNameResolver typeNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
name = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(nestedNameSpecifier->getAsType()));
}
break;
return CxxTypeName::makeUnsolvedIfNull(CxxTypeNameResolver(this).getName(nestedNameSpecifier->getAsType()));
case clang::NestedNameSpecifier::Global:
// no context name hierarchy needed.
break;
case clang::NestedNameSpecifier::Super:
{
CxxDeclNameResolver declNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
name = declNameResolver.getName(nestedNameSpecifier->getAsRecordDecl());
}
break;
return CxxDeclNameResolver(this).getName(nestedNameSpecifier->getAsRecordDecl());
}
}
return name;
return nullptr;
}
@@ -7,16 +7,14 @@
class CxxName;
class CxxSpecifierNameResolver: public CxxNameResolver
class CxxSpecifierNameResolver
: public CxxNameResolver
{
public:
CxxSpecifierNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache);
CxxSpecifierNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
);
CxxSpecifierNameResolver(CanonicalFilePathCache* canonicalFilePathCache);
CxxSpecifierNameResolver(const CxxNameResolver* other);
std::shared_ptr<CxxName> getName(const clang::NestedNameSpecifier* nestedNameSpecifier);
std::unique_ptr<CxxName> getName(const clang::NestedNameSpecifier* nestedNameSpecifier);
};
#endif // CXX_SPECIFIER_NAME_RESOLVER_H
@@ -1,21 +1,20 @@
#include "CxxTemplateArgumentNameResolver.h"
#include <sstream>
#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/DeclTemplate.h>
#include "CxxTypeNameResolver.h"
#include "utilityString.h"
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache, std::vector<const clang::Decl*>())
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver(CanonicalFilePathCache* canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache)
{
}
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
)
: CxxNameResolver(canonicalFilePathCache, ignoredContextDecls)
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver(const CxxNameResolver* other)
: CxxNameResolver(other)
{
}
@@ -28,8 +27,8 @@ std::wstring CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clan
{
case clang::TemplateArgument::Type:
{
CxxTypeNameResolver typeNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(argument.getAsType()));
CxxTypeNameResolver typeNameResolver(this);
std::unique_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(argument.getAsType()));
return typeName->toString();
}
case clang::TemplateArgument::Integral:
@@ -47,25 +46,24 @@ std::wstring CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clan
std::string buf;
llvm::raw_string_ostream os(buf);
argument.print(pp, os);
const std::string typeName = os.str();
return utility::decodeFromUtf8(typeName);
return utility::decodeFromUtf8(os.str());
}
case clang::TemplateArgument::Pack:
{
std::wstring typeName = L"<";
std::wstringstream ss;
ss << L'<';
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)
if (i > 0)
{
typeName += L", ";
ss << L", ";
}
ss << getTemplateArgumentName(pack[i]);
}
typeName += L">";
ss << L'>';
return typeName;
return ss.str();
}
}
@@ -7,14 +7,12 @@
class DataType;
class CxxTemplateArgumentNameResolver: public CxxNameResolver
class CxxTemplateArgumentNameResolver
: public CxxNameResolver
{
public:
CxxTemplateArgumentNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache);
CxxTemplateArgumentNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
);
CxxTemplateArgumentNameResolver(CanonicalFilePathCache* canonicalFilePathCache);
CxxTemplateArgumentNameResolver(const CxxNameResolver* other);
std::wstring getTemplateArgumentName(const clang::TemplateArgument& argument);
};
@@ -1,21 +1,20 @@
#include "CxxTemplateParameterStringResolver.h"
#include <sstream>
#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/DeclTemplate.h>
#include "CxxTypeNameResolver.h"
#include "utilityString.h"
CxxTemplateParameterStringResolver::CxxTemplateParameterStringResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache, std::vector<const clang::Decl*>())
CxxTemplateParameterStringResolver::CxxTemplateParameterStringResolver(CanonicalFilePathCache* canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache)
{
}
CxxTemplateParameterStringResolver::CxxTemplateParameterStringResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
)
: CxxNameResolver(canonicalFilePathCache, ignoredContextDecls)
CxxTemplateParameterStringResolver::CxxTemplateParameterStringResolver(const CxxNameResolver* other)
: CxxNameResolver(other)
{
}
@@ -25,8 +24,6 @@ std::wstring CxxTemplateParameterStringResolver::getTemplateParameterString(cons
if (parameter)
{
const std::wstring parameterName = utility::decodeFromUtf8(parameter->getName());
const clang::Decl::Kind templateParameterKind = parameter->getKind();
switch (templateParameterKind)
{
@@ -44,9 +41,10 @@ std::wstring CxxTemplateParameterStringResolver::getTemplateParameterString(cons
break;
}
const std::wstring parameterName = utility::decodeFromUtf8(parameter->getName());
if (!parameterName.empty())
{
templateParameterTypeString += L" " + parameterName;
templateParameterTypeString += L' ' + parameterName;
}
}
return templateParameterTypeString;
@@ -54,10 +52,8 @@ std::wstring CxxTemplateParameterStringResolver::getTemplateParameterString(cons
std::wstring CxxTemplateParameterStringResolver::getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter)
{
CxxTypeNameResolver typeNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typeNameResolver.getName(parameter->getType()));
std::wstring typeString = typeName->toString();
std::wstring typeString =
CxxTypeName::makeUnsolvedIfNull(CxxTypeNameResolver(this).getName(parameter->getType()))->toString();
if (parameter->isTemplateParameterPack())
{
@@ -81,23 +77,27 @@ std::wstring CxxTemplateParameterStringResolver::getTemplateParameterTypeString(
std::wstring CxxTemplateParameterStringResolver::getTemplateParameterTypeString(const clang::TemplateTemplateParmDecl* parameter)
{
std::wstring templateParameterTypeString = L"template<";
clang::TemplateParameterList* parameterList = parameter->getTemplateParameters();
std::wstringstream ss;
ss << L"template<";
const clang::TemplateParameterList* parameterList = parameter->getTemplateParameters();
for (size_t i = 0; i < parameterList->size(); i++)
{
CxxTemplateParameterStringResolver parameterStringResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
if (i > 0)
{
ss << L", ";
}
CxxTemplateParameterStringResolver parameterStringResolver(this);
parameterStringResolver.ignoreContextDecl(parameterList->getParam(i));
templateParameterTypeString += parameterStringResolver.getTemplateParameterString(parameterList->getParam(i));
templateParameterTypeString += (i < parameterList->size() - 1) ? L", " : L"";
ss << parameterStringResolver.getTemplateParameterString(parameterList->getParam(i));
}
templateParameterTypeString += L">";
templateParameterTypeString += L" typename"; // TODO: what if template template parameter is defined with class keyword?
ss << L"> typename"; // TODO: what if template template parameter is defined with class keyword?
if (parameter->isTemplateParameterPack())
{
templateParameterTypeString += L"...";
ss << L"...";
}
return templateParameterTypeString;
return ss.str();
}
@@ -9,14 +9,12 @@
class DataType;
class CxxTemplateParameterStringResolver: public CxxNameResolver
class CxxTemplateParameterStringResolver
: public CxxNameResolver
{
public:
CxxTemplateParameterStringResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache);
CxxTemplateParameterStringResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
);
CxxTemplateParameterStringResolver(CanonicalFilePathCache* canonicalFilePathCache);
CxxTemplateParameterStringResolver(const CxxNameResolver* other);
std::wstring getTemplateParameterString(const clang::NamedDecl* parameter);
std::wstring getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter);
@@ -10,22 +10,19 @@
#include "logging.h"
#include "utilityString.h"
CxxTypeNameResolver::CxxTypeNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache, std::vector<const clang::Decl*>())
CxxTypeNameResolver::CxxTypeNameResolver(CanonicalFilePathCache* canonicalFilePathCache)
: CxxNameResolver(canonicalFilePathCache)
{
}
CxxTypeNameResolver::CxxTypeNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
)
: CxxNameResolver(canonicalFilePathCache, ignoredContextDecls)
CxxTypeNameResolver::CxxTypeNameResolver(const CxxNameResolver* other)
: CxxNameResolver(other)
{
}
std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::QualType& qualType)
std::unique_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::QualType& qualType)
{
std::shared_ptr<CxxTypeName> typeName = getName(qualType.getTypePtr());
std::unique_ptr<CxxTypeName> typeName = getName(qualType.getTypePtr());
if (typeName && qualType.isConstQualified())
{
typeName->addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
@@ -33,36 +30,31 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::QualType&
return typeName;
}
std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* type)
std::unique_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* type)
{
std::shared_ptr<CxxTypeName> typeName;
if (type)
{
switch (type->getTypeClass())
{
case clang::Type::Paren:
{
typeName = getName(type->getAs<clang::ParenType>()->getInnerType());
break;
return getName(type->getAs<clang::ParenType>()->getInnerType());
}
case clang::Type::Attributed:
{
typeName = getName(type->getAs<clang::AttributedType>()->getModifiedType());
break;
return getName(type->getAs<clang::AttributedType>()->getModifiedType());
}
case clang::Type::InjectedClassName:
{
typeName = getName(type->getAs<clang::InjectedClassNameType>()->getInjectedSpecializationType());
break;
return getName(type->getAs<clang::InjectedClassNameType>()->getInjectedSpecializationType());
}
case clang::Type::Typedef:
{
CxxDeclNameResolver declNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TypedefType>()->getDecl());
std::unique_ptr<CxxDeclName> declName =
CxxDeclNameResolver(this).getName(type->getAs<clang::TypedefType>()->getDecl());
if (declName)
{
typeName = std::make_shared<CxxTypeName>(
return std::make_unique<CxxTypeName>(
declName->getName(),
std::vector<std::wstring>(),
declName->getParent()
@@ -73,56 +65,54 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
case clang::Type::MemberPointer:
case clang::Type::Pointer:
{
typeName = getName(type->getPointeeType());
std::unique_ptr<CxxTypeName> typeName = getName(type->getPointeeType());
if (typeName)
{
typeName->addModifier(CxxTypeName::Modifier(L"*"));
}
break;
return typeName;
}
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());
std::unique_ptr<CxxTypeName> typeName = getName(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
if (typeName)
{
typeName->addModifier(CxxTypeName::Modifier(L"[]"));
}
break;
return typeName;
}
case clang::Type::LValueReference:
{
typeName = getName(type->getPointeeType());
std::unique_ptr<CxxTypeName> typeName = getName(type->getPointeeType());
if (typeName)
{
typeName->addModifier(CxxTypeName::Modifier(L"&"));
}
break;
return typeName;
}
case clang::Type::RValueReference:
{
typeName = getName(type->getPointeeType());
std::unique_ptr<CxxTypeName> typeName = getName(type->getPointeeType());
if (typeName)
{
typeName->addModifier(CxxTypeName::Modifier(L"&&"));
}
break;
return typeName;
}
case clang::Type::Elaborated:
{
typeName = getName(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
break;
return getName(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
}
case clang::Type::Enum:
case clang::Type::Record:
{
CxxDeclNameResolver declNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TagType>()->getDecl());
std::unique_ptr<CxxDeclName> declName = CxxDeclNameResolver(this).getName(type->getAs<clang::TagType>()->getDecl());
if (declName)
{
typeName = std::make_shared<CxxTypeName>(
return std::make_unique<CxxTypeName>(
declName->getName(),
declName->getTemplateParameterNames(), // contains template arguments if decl is a template specialization
declName->getParent()
@@ -136,21 +126,19 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
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>(
return std::make_unique<CxxTypeName>(
utility::decodeFromUtf8(type->getAs<clang::BuiltinType>()->getName(pp)), std::vector<std::wstring>()
);
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(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(tagType->getDecl());
std::unique_ptr<CxxDeclName> declName = CxxDeclNameResolver(this).getName(tagType->getDecl());
if (declName)
{
typeName = std::make_shared<CxxTypeName>(
return std::make_unique<CxxTypeName>(
declName->getName(),
declName->getTemplateParameterNames(),
declName->getParent()
@@ -160,20 +148,20 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
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(getCanonicalFilePathCache(), getIgnoredContextDecls());
const std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(templateSpecializationType->getTemplateName().getAsTemplateDecl());
const std::unique_ptr<CxxDeclName> declName =
CxxDeclNameResolver(this).getName(templateSpecializationType->getTemplateName().getAsTemplateDecl());
if (declName)
{
std::vector<std::wstring> templateArguments;
CxxTemplateArgumentNameResolver resolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
CxxTemplateArgumentNameResolver resolver(this);
resolver.ignoreContextDecl(templateSpecializationType->getTemplateName().getAsTemplateDecl()->getTemplatedDecl());
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
{
templateArguments.push_back(resolver.getTemplateArgumentName(templateSpecializationType->getArg(i)));
}
typeName = std::make_shared<CxxTypeName>(
return std::make_unique<CxxTypeName>(
declName->getName(),
std::move(templateArguments),
declName->getParent()
@@ -188,11 +176,11 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
}
case clang::Type::TemplateTypeParm:
{
CxxDeclNameResolver declNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl());
std::unique_ptr<CxxDeclName> declName =
CxxDeclNameResolver(this).getName(clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl());
if (declName)
{
typeName = std::make_shared<CxxTypeName>(
return std::make_unique<CxxTypeName>(
declName->getName(),
declName->getTemplateParameterNames(),
declName->getParent()
@@ -202,67 +190,53 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
}
case clang::Type::SubstTemplateTypeParm:
{
typeName = getName(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
break;
return getName(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
}
case clang::Type::DependentName:
{
const clang::DependentNameType* dependentType = clang::dyn_cast<clang::DependentNameType>(type);
CxxSpecifierNameResolver specifierNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentType->getQualifier());
typeName = std::make_shared<CxxTypeName>(
utility::decodeFromUtf8(dependentType->getIdentifier()->getName().str()),
std::vector<std::wstring>(),
specifierName
std::unique_ptr<CxxName> specifierName = CxxSpecifierNameResolver(this).getName(dependentType->getQualifier());
return std::make_unique<CxxTypeName>(
utility::decodeFromUtf8(dependentType->getIdentifier()->getName().str()),
std::vector<std::wstring>(),
std::move(specifierName)
);
break;
}
case clang::Type::DependentTemplateSpecialization:
{
const clang::DependentTemplateSpecializationType* dependentType = clang::dyn_cast<clang::DependentTemplateSpecializationType>(type);
CxxSpecifierNameResolver specifierNameResolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentType->getQualifier());
std::unique_ptr<CxxName> specifierName = CxxSpecifierNameResolver(this).getName(dependentType->getQualifier());
std::vector<std::wstring> templateArguments;
CxxTemplateArgumentNameResolver resolver(getCanonicalFilePathCache(), getIgnoredContextDecls());
CxxTemplateArgumentNameResolver resolver(this);
for (size_t i = 0; i < dependentType->getNumArgs(); i++)
{
templateArguments.push_back(resolver.getTemplateArgumentName(dependentType->getArg(i)));
}
typeName = std::make_shared<CxxTypeName>(
utility::decodeFromUtf8(dependentType->getIdentifier()->getName().str()),
std::move(templateArguments),
specifierName
return std::make_unique<CxxTypeName>(
utility::decodeFromUtf8(dependentType->getIdentifier()->getName().str()),
std::move(templateArguments),
std::move(specifierName)
);
break;
}
case clang::Type::PackExpansion:
{
typeName = getName(clang::dyn_cast<clang::PackExpansionType>(type)->getPattern());
break;
return getName(clang::dyn_cast<clang::PackExpansionType>(type)->getPattern());
}
case clang::Type::Auto:
{
clang::QualType deducedType = clang::dyn_cast<clang::AutoType>(type)->getDeducedType();
if (!deducedType.isNull())
{
typeName = getName(deducedType);
return getName(deducedType);
}
else
{
typeName = std::make_shared<CxxTypeName>(
L"auto", std::vector<std::wstring>() // TODO: can we actually resolve this case? would be great!
);
}
break;
return std::make_unique<CxxTypeName>(L"auto"); // TODO: can we actually resolve this case? would be great!
}
case clang::Type::Decltype:
{
typeName = getName(clang::dyn_cast<clang::DecltypeType>(type)->getUnderlyingType());
break;
return getName(clang::dyn_cast<clang::DecltypeType>(type)->getUnderlyingType());
}
case clang::Type::FunctionProto:
{
@@ -279,16 +253,12 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
}
nameString += L")";
typeName = std::make_shared<CxxTypeName>(
std::move(nameString), std::vector<std::wstring>()
);
break;
return std::make_unique<CxxTypeName>(std::move(nameString));
}
case clang::Type::Adjusted:
case clang::Type::Decayed:
{
typeName = getName(type->getAs<clang::AdjustedType>()->getOriginalType());
break;
return getName(type->getAs<clang::AdjustedType>()->getOriginalType());
}
default:
{
@@ -303,12 +273,9 @@ std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* typ
clang::QualType::print(type, clang::Qualifiers(), StrOS, pp, clang::Twine());
std::wstring nameString = utility::decodeFromUtf8(StrOS.str());
typeName = std::make_shared<CxxTypeName>(
std::move(nameString), std::vector<std::wstring>()
);
break;
return std::make_unique<CxxTypeName>(std::move(nameString));
}
}
}
return typeName;
return nullptr;
}
@@ -4,17 +4,15 @@
#include "CxxTypeName.h"
#include "CxxNameResolver.h"
class CxxTypeNameResolver: public CxxNameResolver
class CxxTypeNameResolver
: public CxxNameResolver
{
public:
CxxTypeNameResolver(std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache);
CxxTypeNameResolver(
std::shared_ptr<CanonicalFilePathCache> canonicalFilePathCache,
std::vector<const clang::Decl*> ignoredContextDecls
);
CxxTypeNameResolver(CanonicalFilePathCache* canonicalFilePathCache);
CxxTypeNameResolver(const CxxNameResolver* other);
std::shared_ptr<CxxTypeName> getName(const clang::QualType& qualType);
std::shared_ptr<CxxTypeName> getName(const clang::Type* type);
std::unique_ptr<CxxTypeName> getName(const clang::QualType& qualType);
std::unique_ptr<CxxTypeName> getName(const clang::Type* type);
};
#endif // CXX_TYPE_NAME_RESOLVER_H