src: refactored name resolvers

* added classes that represent different name kinds
* rewrote NameResolvers to return the new name classes instead of NameElement and NameHierarchy
* removed DataType classes since their functionality moved to the CxxTypeName class.
This commit is contained in:
malte_langkabel
2016-11-16 15:37:02 +01:00
parent a35e8a53de
commit 7873710ba8
42 changed files with 873 additions and 691 deletions
-13
View File
@@ -159,19 +159,6 @@ add_files(
data/search/SearchMatch.cpp
data/search/SearchMatch.h
data/type/ArrayModifiedDataType.cpp
data/type/ArrayModifiedDataType.h
data/type/DataType.cpp
data/type/DataType.h
data/type/ModifiedDataType.cpp
data/type/ModifiedDataType.h
data/type/NamedDataType.cpp
data/type/NamedDataType.h
data/type/PointerModifiedDataType.cpp
data/type/PointerModifiedDataType.h
data/type/ReferenceModifiedDataType.cpp
data/type/ReferenceModifiedDataType.h
data/DefinitionType.cpp
data/DefinitionType.h
data/ErrorCountInfo.h
-1
View File
@@ -25,7 +25,6 @@
#include "data/location/TokenLocationFile.h"
#include "data/location/TokenLocationLine.h"
#include "data/parser/ParseLocation.h"
#include "data/type/DataType.h"
PersistentStorage::PersistentStorage(const FilePath& dbPath)
: m_sqliteStorage(dbPath)
+1 -1
View File
@@ -38,7 +38,7 @@ std::string NameElement::Signature::qualifyName(const std::string& name) const
}
std::string qualifiedName = m_prefix;
if (name.size() > 0)
if (!name.empty())
{
if (!m_prefix.empty())
{
-1
View File
@@ -3,7 +3,6 @@
#include <sstream>
#include "data/parser/ParseLocation.h"
#include "data/type/DataType.h"
#include "utility/utilityString.h"
std::string ParserClient::addAccessPrefix(const std::string& str, AccessKind access)
@@ -1,15 +0,0 @@
#include "data/type/ArrayModifiedDataType.h"
ArrayModifiedDataType::ArrayModifiedDataType(std::shared_ptr<DataType> dataType)
: ModifiedDataType(dataType)
{
}
ArrayModifiedDataType::~ArrayModifiedDataType()
{
}
void ArrayModifiedDataType::applyModifier(std::string& typeName) const
{
typeName.append(" []");
}
-16
View File
@@ -1,16 +0,0 @@
#ifndef ARRAY_MODIFIED_DATA_TYPE_H
#define ARRAY_MODIFIED_DATA_TYPE_H
#include "ModifiedDataType.h"
class ArrayModifiedDataType: public ModifiedDataType
{
public:
ArrayModifiedDataType(std::shared_ptr<DataType> dataType);
virtual ~ArrayModifiedDataType();
protected:
virtual void applyModifier(std::string& typeName) const;
};
#endif // ARRAY_MODIFIED_DATA_TYPE_H
-33
View File
@@ -1,33 +0,0 @@
#include "data/type/DataType.h"
DataType::DataType()
: m_qualifiers(QUALIFIER_NONE)
{
}
DataType::~DataType()
{
}
void DataType::addQualifier(QualifierType qualifier)
{
m_qualifiers = m_qualifiers | qualifier;
}
void DataType::removeQualifier(QualifierType qualifier)
{
m_qualifiers = m_qualifiers & ~qualifier;
}
bool DataType::hasQualifier(QualifierType qualifier) const
{
return (m_qualifiers & qualifier) > 0;
}
void DataType::applyQualifieres(std::string& typeName) const
{
if (hasQualifier(QUALIFIER_CONST))
{
typeName += " const";
}
}
-35
View File
@@ -1,35 +0,0 @@
#ifndef DATA_TYPE_H
#define DATA_TYPE_H
#include <string>
#include "data/name/NameHierarchy.h"
class DataType
{
public:
enum QualifierType
{
QUALIFIER_NONE = 0,
QUALIFIER_CONST = 1
};
DataType();
virtual ~DataType();
virtual std::string getFullTypeName() const = 0;
virtual std::string getRawTypeName() const = 0;
virtual const NameHierarchy& getTypeNameHierarchy() const = 0;
void addQualifier(QualifierType qualifier);
void removeQualifier(QualifierType qualifier);
bool hasQualifier(QualifierType qualifier) const;
protected:
void applyQualifieres(std::string& typeName) const;
private:
char m_qualifiers;
};
#endif // DATA_TYPE_H
-28
View File
@@ -1,28 +0,0 @@
#include "data/type/ModifiedDataType.h"
ModifiedDataType::ModifiedDataType(std::shared_ptr<DataType> dataType)
: m_dataType(dataType)
{
}
ModifiedDataType::~ModifiedDataType()
{
}
std::string ModifiedDataType::getFullTypeName() const
{
std::string fullTypeName = m_dataType->getFullTypeName();
applyModifier(fullTypeName);
applyQualifieres(fullTypeName);
return fullTypeName;
}
std::string ModifiedDataType::getRawTypeName() const
{
return m_dataType->getRawTypeName();
}
const NameHierarchy& ModifiedDataType::getTypeNameHierarchy() const
{
return m_dataType->getTypeNameHierarchy();
}
-25
View File
@@ -1,25 +0,0 @@
#ifndef MODIFIED_DATA_TYPE_H
#define MODIFIED_DATA_TYPE_H
#include <memory>
#include "DataType.h"
class ModifiedDataType: public DataType
{
public:
ModifiedDataType(std::shared_ptr<DataType> dataType);
virtual ~ModifiedDataType();
virtual std::string getFullTypeName() const;
virtual std::string getRawTypeName() const;
virtual const NameHierarchy& getTypeNameHierarchy() const;
protected:
virtual void applyModifier(std::string& typeName) const = 0;
private:
const std::shared_ptr<DataType> m_dataType;
};
#endif // MODIFIED_DATA_TYPE_H
-29
View File
@@ -1,29 +0,0 @@
#include "data/type/NamedDataType.h"
#include "utility/utilityString.h"
NamedDataType::NamedDataType(const NameHierarchy& nameHierarchy)
: m_nameHierarchy(nameHierarchy)
{
}
NamedDataType::~NamedDataType()
{
}
std::string NamedDataType::getFullTypeName() const
{
std::string fullTypeName = getRawTypeName();
applyQualifieres(fullTypeName);
return fullTypeName;
}
std::string NamedDataType::getRawTypeName() const
{
return m_nameHierarchy.getQualifiedNameWithSignature();
}
const NameHierarchy& NamedDataType::getTypeNameHierarchy() const
{
return m_nameHierarchy;
}
-21
View File
@@ -1,21 +0,0 @@
#ifndef NAMED_DATA_TYPE_H
#define NAMED_DATA_TYPE_H
#include "data/type/DataType.h"
class NamedDataType: public DataType
{
public:
NamedDataType(const NameHierarchy& nameHierarchy);
virtual ~NamedDataType();
virtual std::string getFullTypeName() const;
virtual std::string getRawTypeName() const;
virtual const NameHierarchy& getTypeNameHierarchy() const;
private:
const NameHierarchy m_nameHierarchy;
};
#endif // NAMED_DATA_TYPE_H
@@ -1,15 +0,0 @@
#include "data/type/PointerModifiedDataType.h"
PointerModifiedDataType::PointerModifiedDataType(std::shared_ptr<DataType> dataType)
: ModifiedDataType(dataType)
{
}
PointerModifiedDataType::~PointerModifiedDataType()
{
}
void PointerModifiedDataType::applyModifier(std::string& typeName) const
{
typeName.append(" *");
}
@@ -1,16 +0,0 @@
#ifndef POINTER_MODIFIED_DATA_TYPE_H
#define POINTER_MODIFIED_DATA_TYPE_H
#include "ModifiedDataType.h"
class PointerModifiedDataType: public ModifiedDataType
{
public:
PointerModifiedDataType(std::shared_ptr<DataType> dataType);
virtual ~PointerModifiedDataType();
protected:
virtual void applyModifier(std::string& typeName) const;
};
#endif // POINTER_MODIFIED_DATA_TYPE_H
@@ -1,15 +0,0 @@
#include "data/type/ReferenceModifiedDataType.h"
ReferenceModifiedDataType::ReferenceModifiedDataType(std::shared_ptr<DataType> dataType)
: ModifiedDataType(dataType)
{
}
ReferenceModifiedDataType::~ReferenceModifiedDataType()
{
}
void ReferenceModifiedDataType::applyModifier(std::string& typeName) const
{
typeName.append(" &");
}
@@ -1,16 +0,0 @@
#ifndef REFERENCE_MODIFIED_DATA_TYPE_H
#define REFERENCE_MODIFIED_DATA_TYPE_H
#include "ModifiedDataType.h"
class ReferenceModifiedDataType: public ModifiedDataType
{
public:
ReferenceModifiedDataType(std::shared_ptr<DataType> dataType);
virtual ~ReferenceModifiedDataType();
protected:
virtual void applyModifier(std::string& typeName) const;
};
#endif // REFERENCE_MODIFIED_DATA_TYPE_H
+11
View File
@@ -2,6 +2,17 @@
add_files(
CLANG_FILES
data/parser/cxx/name/CxxDeclName.cpp
data/parser/cxx/name/CxxDeclName.h
data/parser/cxx/name/CxxFunctionDeclName.cpp
data/parser/cxx/name/CxxFunctionDeclName.h
data/parser/cxx/name/CxxName.cpp
data/parser/cxx/name/CxxName.h
data/parser/cxx/name/CxxQualifierFlags.cpp
data/parser/cxx/name/CxxQualifierFlags.h
data/parser/cxx/name/CxxTypeName.cpp
data/parser/cxx/name/CxxTypeName.h
data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp
data/parser/cxx/name_resolver/CxxDeclNameResolver.h
data/parser/cxx/name_resolver/CxxNameResolver.cpp
@@ -25,8 +25,11 @@ CxxAstVisitor::CxxAstVisitor(clang::ASTContext* astContext, clang::Preprocessor*
{
if (decl)
{
CxxDeclNameResolver resolver(decl);
return resolver.getDeclNameHierarchy();
CxxDeclNameResolver resolver;
if (std::shared_ptr<CxxDeclName> declName = resolver.getName(decl))
{
return declName->toNameHierarchy();
}
}
return NameHierarchy("global");
});
@@ -35,7 +38,10 @@ CxxAstVisitor::CxxAstVisitor(clang::ASTContext* astContext, clang::Preprocessor*
if (type)
{
CxxTypeNameResolver resolver;
return resolver.getTypeNameHierarchy(type);
if (std::shared_ptr<CxxTypeName> typeName = resolver.getName(type))
{
return typeName->toNameHierarchy();
}
}
return NameHierarchy("global");
});
@@ -0,0 +1,55 @@
#include "data/parser/cxx/name/CxxDeclName.h"
CxxDeclName::CxxDeclName(std::string name, std::vector<std::string> templateParameterNames)
: m_name(name)
, m_templateParameterNames(templateParameterNames)
{
}
CxxDeclName::CxxDeclName(
std::string name,
std::vector<std::string> templateParameterNames,
std::shared_ptr<CxxName> parent
)
: CxxName(parent)
, m_name(name)
, m_templateParameterNames(templateParameterNames)
{
}
CxxDeclName::~CxxDeclName()
{
}
NameHierarchy CxxDeclName::toNameHierarchy() const
{
std::string nameString = m_name;
if (!m_templateParameterNames.empty())
{
nameString += "<";
for (size_t i = 0; i < m_templateParameterNames.size(); i++)
{
if (i != 0)
{
nameString += ", ";
}
nameString += m_templateParameterNames[i];
}
nameString += ">";
}
NameHierarchy ret = getParent() ? getParent()->toNameHierarchy(): NameHierarchy();
ret.push(std::make_shared<NameElement>(nameString));
return ret;
}
std::string CxxDeclName::getName() const
{
return m_name;
}
std::vector<std::string> CxxDeclName::getTemplateParameterNames() const
{
return m_templateParameterNames;
}
@@ -0,0 +1,36 @@
#ifndef CXX_DECL_NAME_H
#define CXX_DECL_NAME_H
#include <memory>
#include <string>
#include <vector>
#include "data/name/NameHierarchy.h"
#include "data/parser/cxx/name/CxxName.h"
class CxxDeclName: public CxxName
{
public:
CxxDeclName(
std::string name,
std::vector<std::string> templateParameterNames
);
CxxDeclName(
std::string name,
std::vector<std::string> templateParameterNames,
std::shared_ptr<CxxName> parent
);
virtual ~CxxDeclName();
virtual NameHierarchy toNameHierarchy() const;
std::string getName() const;
std::vector<std::string> getTemplateParameterNames() const;
private:
std::string m_name;
std::vector<std::string> m_templateParameterNames;
};
#endif // CXX_DECL_NAME_H
@@ -0,0 +1,74 @@
#include "data/parser/cxx/name/CxxFunctionDeclName.h"
CxxFunctionDeclName::CxxFunctionDeclName(
std::string name,
std::vector<std::string> templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames,
bool isConst,
bool isStatic
)
: CxxDeclName(name, templateParameterNames)
, m_returnTypeName(returnTypeName)
, m_parameterTypeNames(parameterTypeNames)
, m_isConst(isConst)
, m_isStatic(isStatic)
{
}
CxxFunctionDeclName::CxxFunctionDeclName(
std::string name,
std::vector<std::string> templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames,
bool isConst,
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()
{
}
NameHierarchy CxxFunctionDeclName::toNameHierarchy() const
{
std::string signaturePrefix = "";
if (m_isStatic)
{
signaturePrefix += "static ";
}
signaturePrefix += m_returnTypeName->toString();
std::string signaturePostfix = "(";
for (size_t i = 0; i < m_parameterTypeNames.size(); i++)
{
if (i != 0)
{
signaturePostfix += ", ";
}
signaturePostfix += m_parameterTypeNames[i]->toString();
}
signaturePostfix += ")";
if (m_isConst)
{
signaturePostfix += " const";
}
NameHierarchy ret = CxxDeclName::toNameHierarchy();
std::shared_ptr<NameElement> nameElement = std::make_shared<NameElement>(
ret.back()->getName(),
NameElement::Signature(signaturePrefix, signaturePostfix)
);
ret.pop();
ret.push(nameElement);
return ret;
}
@@ -0,0 +1,43 @@
#ifndef CXX_FUNCTION_DECL_NAME_H
#define CXX_FUNCTION_DECL_NAME_H
#include <memory>
#include <vector>
#include "data/parser/cxx/name/CxxDeclName.h"
#include "data/parser/cxx/name/CxxTypeName.h"
class CxxFunctionDeclName: public CxxDeclName
{
public:
CxxFunctionDeclName(
std::string name,
std::vector<std::string> templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames,
bool isConst,
bool isStatic
);
CxxFunctionDeclName(
std::string name,
std::vector<std::string> templateParameterNames,
std::shared_ptr<CxxTypeName> returnTypeName,
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames,
bool isConst,
bool isStatic,
std::shared_ptr<CxxName> parent
);
virtual ~CxxFunctionDeclName();
virtual NameHierarchy toNameHierarchy() const;
private:
std::shared_ptr<CxxTypeName> m_returnTypeName;
std::vector<std::shared_ptr<CxxTypeName>> m_parameterTypeNames;
bool m_isConst;
bool m_isStatic;
};
#endif // CXX_FUNCTION_DECL_NAME_H
@@ -0,0 +1,25 @@
#include "data/parser/cxx/name/CxxName.h"
CxxName::CxxName()
{
}
CxxName::CxxName(std::shared_ptr<CxxName> parent)
: m_parent(parent)
{
}
CxxName::~CxxName()
{
}
void CxxName::setParent(std::shared_ptr<CxxName> parent)
{
m_parent = parent;
}
std::shared_ptr<CxxName> CxxName::getParent() const
{
return m_parent;
}
@@ -0,0 +1,27 @@
#ifndef CXX_NAME_H
#define CXX_NAME_H
#include <memory>
#include <string>
#include <vector>
#include "data/name/NameHierarchy.h"
class CxxName
{
public:
CxxName();
CxxName(std::shared_ptr<CxxName> parent);
virtual ~CxxName();
void setParent(std::shared_ptr<CxxName> parent);
std::shared_ptr<CxxName> getParent() const;
virtual NameHierarchy toNameHierarchy() const = 0;
private:
std::shared_ptr<CxxName> m_parent;
};
#endif // CXX_NAME_H
@@ -0,0 +1,37 @@
#include "data/parser/cxx/name/CxxQualifierFlags.h"
CxxQualifierFlags::CxxQualifierFlags()
: m_flags(QUALIFIER_NONE)
{
}
CxxQualifierFlags::CxxQualifierFlags(const char flags)
: m_flags(flags)
{
}
void CxxQualifierFlags::addQualifier(QualifierType qualifier)
{
m_flags = m_flags | qualifier;
}
void CxxQualifierFlags::removeQualifier(QualifierType qualifier)
{
m_flags = m_flags & ~qualifier;
}
bool CxxQualifierFlags::empty() const
{
return m_flags == QUALIFIER_NONE;
}
std::string CxxQualifierFlags::toString() const
{
std::string ret = "";
if (m_flags & QUALIFIER_CONST)
{
ret += "const";
}
return ret;
}
@@ -0,0 +1,28 @@
#ifndef CXX_QUALIFIER_FLAGS_H
#define CXX_QUALIFIER_FLAGS_H
#include <string>
class CxxQualifierFlags
{
public:
enum QualifierType
{
QUALIFIER_NONE = 0,
QUALIFIER_CONST = 1
};
CxxQualifierFlags();
CxxQualifierFlags(const char flags);
void addQualifier(QualifierType qualifier);
void removeQualifier(QualifierType qualifier);
bool empty() const;
std::string toString() const;
private:
char m_flags;
};
#endif // CXX_QUALIFIER_FLAGS_H
@@ -0,0 +1,90 @@
#include "data/parser/cxx/name/CxxTypeName.h"
CxxTypeName::Modifier::Modifier(std::string symbol)
: symbol(symbol)
{
}
CxxTypeName::CxxTypeName(std::string name, std::vector<std::string> templateArguments)
: m_name(name)
, m_templateArguments(templateArguments)
{
}
CxxTypeName::CxxTypeName(
std::string name,
std::vector<std::string> templateArguments,
std::shared_ptr<CxxName> parent
)
: CxxName(parent)
, m_name(name)
, m_templateArguments(templateArguments)
{
}
CxxTypeName::~CxxTypeName()
{
}
NameHierarchy CxxTypeName::toNameHierarchy() const
{
NameHierarchy ret = getParent() ? getParent()->toNameHierarchy(): NameHierarchy();
ret.push(std::make_shared<NameElement>(getTypeNameString()));
return ret;
}
void CxxTypeName::addQualifier(const CxxQualifierFlags::QualifierType qualifier)
{
if (m_modifiers.empty())
{
m_qualifierFlags.addQualifier(qualifier);
}
else
{
m_modifiers.back().qualifierFlags.addQualifier(qualifier);
}
}
void CxxTypeName::addModifier(const Modifier& modifier)
{
m_modifiers.push_back(modifier);
}
std::string CxxTypeName::toString() const
{
std::string ret = "";
if (!m_qualifierFlags.empty())
{
ret += m_qualifierFlags.toString() + " ";
}
ret += toNameHierarchy().getQualifiedName();
for (Modifier modifier: m_modifiers)
{
ret += " " + modifier.symbol;
if (!modifier.qualifierFlags.empty())
{
ret += " " + modifier.qualifierFlags.toString();
}
}
return ret;
}
std::string CxxTypeName::getTypeNameString() const
{
std::string ret = m_name;
if (!m_templateArguments.empty())
{
ret += "<";
for (size_t i = 0; i < m_templateArguments.size(); i++)
{
if (i != 0)
{
ret += ", ";
}
ret += m_templateArguments[i];
}
ret += ">";
}
return ret;
}
@@ -0,0 +1,52 @@
#ifndef CXX_TYPE_NAME_H
#define CXX_TYPE_NAME_H
#include <memory>
#include <string>
#include <vector>
#include "data/name/NameHierarchy.h"
#include "data/parser/cxx/name/CxxName.h"
#include "data/parser/cxx/name/CxxDeclName.h"
#include "data/parser/cxx/name/CxxQualifierFlags.h"
class CxxTypeName: public CxxName
{
public:
struct Modifier
{
Modifier(std::string symbol);
std::string symbol;
CxxQualifierFlags qualifierFlags;
};
CxxTypeName(
std::string name,
std::vector<std::string> templateArguments
);
CxxTypeName(
std::string name,
std::vector<std::string> templateArguments,
std::shared_ptr<CxxName> parent
);
virtual ~CxxTypeName();
virtual NameHierarchy toNameHierarchy() const;
void addQualifier(const CxxQualifierFlags::QualifierType qualifier);
void addModifier(const Modifier& modifier);
std::string toString() const;
private:
std::string getTypeNameString() const;
std::string m_name;
std::vector<std::string> m_templateArguments;
CxxQualifierFlags m_qualifierFlags;
std::vector<Modifier> m_modifiers;
};
#endif // CXX_TYPE_NAME_H
@@ -0,0 +1,27 @@
#ifndef CXX_DECL_NAME_H
#define CXX_DECL_NAME_H
#include <memory>
#include <string>
#include <vector>
struct CxxDeclName
{
std::string m_name;
std::shared_ptr<CxxDeclName> m_parent;
std::vector<std::string> m_templateParameterNames;
private JavaDeclName m_parent = null;
private String m_name = "";
private List<String> m_typeParameterNames = null;
private JavaTypeName m_returnTypeName = null;
private List<JavaTypeName> m_parameterNames = null;
};
struct CxxFunctionDeclName: public CxxDeclName
{
};
#endif // CXX_DECL_NAME_H
@@ -3,99 +3,88 @@
#include <clang/AST/DeclTemplate.h>
#include <clang/AST/ASTContext.h>
#include "data/parser/cxx/name/CxxFunctionDeclName.h"
#include "data/parser/cxx/name_resolver/CxxSpecifierNameResolver.h"
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
#include "utility/file/FilePath.h"
#include "utility/logging/logging.h"
#include "utility/ScopedSwitcher.h"
CxxDeclNameResolver::CxxDeclNameResolver(const clang::Decl* declaration)
CxxDeclNameResolver::CxxDeclNameResolver()
: CxxNameResolver(std::vector<const clang::Decl*>())
, m_currentDecl(nullptr)
{
const clang::Decl* prev = declaration;
while (prev)
{
m_declaration = prev;
prev = prev->getPreviousDecl();
}
}
CxxDeclNameResolver::CxxDeclNameResolver(const clang::Decl* declaration, std::vector<const clang::Decl*> ignoredContextDecls)
CxxDeclNameResolver::CxxDeclNameResolver(std::vector<const clang::Decl*> ignoredContextDecls)
: CxxNameResolver(ignoredContextDecls)
, m_currentDecl(nullptr)
{
const clang::Decl* prev = declaration;
while (prev)
{
m_declaration = prev;
prev = prev->getPreviousDecl();
}
}
CxxDeclNameResolver::~CxxDeclNameResolver()
{
}
NameHierarchy CxxDeclNameResolver::getDeclNameHierarchy()
std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getName(const clang::NamedDecl* declaration)
{
NameHierarchy contextNameHierarchy;
if (m_declaration)
{
std::shared_ptr<NameElement> declName;
const clang::Decl* prev = declaration;
while (prev)
{
declaration = clang::dyn_cast_or_null<clang::NamedDecl>(prev);
prev = prev->getPreviousDecl();
}
}
if (clang::isa<clang::NamedDecl>(m_declaration))
{
declName = getDeclName(clang::dyn_cast<const clang::NamedDecl>(m_declaration));
}
else
{
// LOG_ERROR("unhandled declaration type: " + std::string(m_declaration->getDeclKindName()));
}
if (const clang::UsingDecl* usingDecl = clang::dyn_cast_or_null<clang::UsingDecl>(m_declaration))
{
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
contextNameHierarchy = specifierNameResolver.getNameHierarchy(usingDecl->getQualifier());
}
else
{
contextNameHierarchy = getContextNameHierarchy(m_declaration->getDeclContext());
}
std::shared_ptr<CxxDeclName> declName;
if (declaration)
{
declName = getDeclName(clang::dyn_cast<const clang::NamedDecl>(declaration));
if (declName)
{
contextNameHierarchy.push(declName);
}
}
return contextNameHierarchy;
}
NameHierarchy CxxDeclNameResolver::getContextNameHierarchy(const clang::DeclContext* declContext)
{
NameHierarchy contextNameHierarchy;
if (declContext && !ignoresContext(declContext))
{
const clang::DeclContext* parentContext = declContext->getParent();
if (parentContext)
{
contextNameHierarchy = getContextNameHierarchy(parentContext);
}
if (const clang::NamedDecl* contextNamedDecl = clang::dyn_cast_or_null<clang::NamedDecl>(declContext))
{
std::shared_ptr<NameElement> declName = getDeclName(contextNamedDecl);
if (declName)
if (const clang::UsingDecl* usingDecl = clang::dyn_cast_or_null<clang::UsingDecl>(declaration))
{
contextNameHierarchy.push(declName);
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
declName->setParent(specifierNameResolver.getName(usingDecl->getQualifier()));
}
else
{
declName->setParent(getContextName(declaration->getDeclContext()));
}
}
}
return contextNameHierarchy;
return declName;
}
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
std::shared_ptr<CxxName> CxxDeclNameResolver::getContextName(const clang::DeclContext* declContext)
{
const clang::NamedDecl* declaration = clang::dyn_cast<clang::NamedDecl>(m_declaration);
std::shared_ptr<CxxName> contextDeclName;
if (declContext && !ignoresContext(declContext))
{
if (const clang::NamedDecl* contextNamedDecl = clang::dyn_cast_or_null<clang::NamedDecl>(declContext))
{
contextDeclName = getDeclName(contextNamedDecl);
if (contextDeclName)
{
contextDeclName->setParent(getContextName(declContext->getParent()));
}
else
{
contextDeclName = getContextName(declContext->getParent());
}
}
}
return contextDeclName;
}
std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
{
ScopedSwitcher<const clang::NamedDecl*> switcher(m_currentDecl, declaration);
std::string declNameString = declaration->getNameAsString();
if (const clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast_or_null<clang::TypeAliasDecl>(declaration))
{
@@ -120,9 +109,9 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
clang::TemplateParameterList* parameterList = partialSpecializationDecl->getTemplateParameters();
unsigned int currentParameterIndex = 0;
std::string specializedParameterNamePart = "<";
int templateArgumentCount = partialSpecializationDecl->getTemplateArgs().size();
std::vector<std::string> templateParameters;
const clang::TemplateArgumentList& templateArgumentList = partialSpecializationDecl->getTemplateArgs();
const int templateArgumentCount = templateArgumentList.size();
for (int i = 0; i < templateArgumentCount; i++)
{
const clang::TemplateArgument& templateArgument = templateArgumentList.get(i);
@@ -130,7 +119,7 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
{
if(currentParameterIndex < parameterList->size())
{
specializedParameterNamePart += getTemplateParameterString(parameterList->getParam(currentParameterIndex));
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(currentParameterIndex)));
}
else
{
@@ -142,38 +131,34 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
}
else
{
specializedParameterNamePart += getTemplateArgumentName(templateArgument);
templateParameters.push_back(getTemplateArgumentName(templateArgument));
}
specializedParameterNamePart += (i < templateArgumentCount - 1) ? ", " : "";
}
specializedParameterNamePart += ">";
return std::make_shared<NameElement>(declNameString + specializedParameterNamePart);
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
}
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
{
std::string templateArgumentNamePart = "<";
std::vector<std::string> templateArguments;
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
for (size_t i = 0; i < templateArgumentList.size(); i++)
{
templateArgumentNamePart += getTemplateArgumentName(templateArgumentList.get(i));
templateArgumentNamePart += (i < templateArgumentList.size() - 1) ? ", " : "";
templateArguments.push_back(getTemplateArgumentName(templateArgumentList.get(i)));
}
templateArgumentNamePart += ">";
return std::make_shared<NameElement>(declNameString + templateArgumentNamePart);
return std::make_shared<CxxDeclName>(declNameString, templateArguments);
}
else if (recordDecl->isLambda())
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(recordDecl->getLocStart());
std::string lambdaName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
return std::make_shared<NameElement>(lambdaName, NameElement::Signature("void", "()"));
// we skip this node because its child (the lambda call operator) has already been recorded.
return std::shared_ptr<CxxDeclName>();
}
else if (declNameString.size() == 0)
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
const std::string symbolKindName = (recordDecl->isStruct() ? "struct" : "class");
return getNameForAnonymousSymbol(symbolKindName, presumedBegin);
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol(symbolKindName, presumedBegin), std::vector<std::string>());
// TODO: TESt what if this one has template params??
}
}
else if (clang::isa<clang::FunctionDecl>(declaration))
@@ -182,33 +167,41 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
{
if (methodDecl->getParent()->isLambda())
{
// return empty pointer since lambdas will be handled at the level of the parent class... not optimal.
return std::shared_ptr<NameElement>();
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(methodDecl->getParent()->getLocStart());
std::string lambdaName = "lambda at " + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn());
return std::make_shared<CxxFunctionDeclName>(
lambdaName,
std::vector<std::string>(),
std::make_shared<CxxTypeName>("void", std::vector<std::string>(), std::shared_ptr<CxxName>()), // TODO: check signature!
std::vector<std::shared_ptr<CxxTypeName>>(),
false,
false
);
}
}
std::string functionName;
std::string functionName = declNameString;
std::vector<std::string> templateArguments;
const clang::FunctionDecl* functionDecl = clang::dyn_cast<clang::FunctionDecl>(declaration);
if (clang::FunctionTemplateDecl* templateFunctionDeclaration = functionDecl->getDescribedFunctionTemplate())
{
functionName = getDeclName(templateFunctionDeclaration)->getName();
std::shared_ptr<CxxDeclName> templateDeclName = getDeclName(templateFunctionDeclaration);
functionName = templateDeclName->getName();
templateArguments = templateDeclName->getTemplateParameterNames();
}
else
{
functionName = declNameString;
if (functionDecl->isFunctionTemplateSpecialization())
{
std::string templateArgumentNamePart = "<";
const clang::TemplateArgumentList* templateArgumentList = functionDecl->getTemplateSpecializationArgs();
for (size_t i = 0; i < templateArgumentList->size(); i++)
{
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
templateArgumentNamePart += getTemplateArgumentName(templateArgument);
templateArgumentNamePart += (i < templateArgumentList->size() - 1) ? ", " : "";
templateArguments.push_back(getTemplateArgumentName(templateArgument));
}
templateArgumentNamePart += ">";
functionName += templateArgumentNamePart;
}
}
@@ -228,46 +221,44 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
CxxTypeNameResolver typenNameResolver(getIgnoredContextDecls());
typenNameResolver.ignoreContextDecl(functionDecl);
std::string returnTypeString = typenNameResolver.qualTypeToDataType(functionDecl->getReturnType())->getFullTypeName();
std::shared_ptr<CxxTypeName> returnTypeName = typenNameResolver.getName(functionDecl->getReturnType());
std::string parameterString = "(";
std::vector<std::shared_ptr<CxxTypeName>> parameterTypeNames;
for (unsigned int i = 0; i < functionDecl->param_size(); i++)
{
if (i > 0)
{
parameterString += ", ";
}
parameterString += typenNameResolver.qualTypeToDataType(functionDecl->parameters()[i]->getType())->getFullTypeName();
parameterTypeNames.push_back(typenNameResolver.getName(functionDecl->parameters()[i]->getType()));
}
parameterString += ")";
return std::make_shared<NameElement>(
return std::make_shared<CxxFunctionDeclName>(
functionName,
NameElement::Signature((isStatic ? "static " : "") + returnTypeString, parameterString + (isConst ? " const" : "")));
templateArguments,
returnTypeName,
parameterTypeNames,
isConst,
isStatic
);
}
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
{
std::string templateParameterNamePart = "<";
std::vector<std::string> templateParameters;
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
for (size_t i = 0; i < parameterList->size(); i++)
{
templateParameterNamePart += getTemplateParameterString(parameterList->getParam(i));
templateParameterNamePart += (i < parameterList->size() - 1) ? ", " : "";
templateParameters.push_back(getTemplateParameterString(parameterList->getParam(i)));
}
templateParameterNamePart += ">";
return std::make_shared<NameElement>(declNameString + templateParameterNamePart);
return std::make_shared<CxxDeclName>(declNameString, templateParameters);
}
else if (clang::isa<clang::NamespaceDecl>(declaration) && clang::dyn_cast<clang::NamespaceDecl>(declaration)->isAnonymousNamespace())
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
return getNameForAnonymousSymbol("namespace", presumedBegin);
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("namespace", presumedBegin), std::vector<std::string>());
}
else if (clang::isa<clang::EnumDecl>(declaration) && declNameString.size() == 0)
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
return getNameForAnonymousSymbol("enum", presumedBegin);
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("enum", presumedBegin), std::vector<std::string>());
}
else if (
(
@@ -278,37 +269,30 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
return getNameForAnonymousSymbol("template parameter", presumedBegin);
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("template parameter", presumedBegin), std::vector<std::string>());
}
else if (clang::isa<clang::ParmVarDecl>(declaration) && declNameString.size() == 0)
{
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
return getNameForAnonymousSymbol("parameter", presumedBegin);
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("parameter", presumedBegin), std::vector<std::string>());
}
if (declNameString.size() > 0)
{
return std::make_shared<NameElement>(declNameString);
return std::make_shared<CxxDeclName>(declNameString, std::vector<std::string>(), std::shared_ptr<CxxName>());
}
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
// LOG_ERROR("could not resolve name of decl at: " + declaration->getLocation().printToString(sourceManager));
return getNameForAnonymousSymbol("symbol", presumedBegin);
return std::make_shared<CxxDeclName>(getNameForAnonymousSymbol("symbol", presumedBegin), std::vector<std::string>());
}
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
std::string CxxDeclNameResolver::getNameForAnonymousSymbol(const std::string& symbolKindName, const clang::PresumedLoc& presumedBegin)
{
CxxDeclNameResolver resolver(declaration);
return resolver.getDeclName();
}
std::shared_ptr<NameElement> CxxDeclNameResolver::getNameForAnonymousSymbol(const std::string& symbolKindName, const clang::PresumedLoc& presumedBegin)
{
return std::make_shared<NameElement>("anonymous " + symbolKindName +
" (" + FilePath(presumedBegin.getFilename()).fileName() + "<" + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn()) + ">)"
);
return "anonymous " + symbolKindName +
" (" + FilePath(presumedBegin.getFilename()).fileName() + "<" + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn()) + ">)";
}
std::string CxxDeclNameResolver::getTemplateParameterString(const clang::NamedDecl* parameter)
@@ -344,16 +328,16 @@ std::string CxxDeclNameResolver::getTemplateParameterTypeString(const clang::Non
{
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
if (clang::isa<clang::TemplateDecl>(m_declaration))
if (clang::isa<clang::TemplateDecl>(m_currentDecl))
{
typeNameResolver.ignoreContextDecl(clang::dyn_cast<clang::TemplateDecl>(m_declaration)->getTemplatedDecl());
typeNameResolver.ignoreContextDecl(clang::dyn_cast<clang::TemplateDecl>(m_currentDecl)->getTemplatedDecl());
}
else // works for partial template specializations
{
typeNameResolver.ignoreContextDecl(m_declaration);
typeNameResolver.ignoreContextDecl(m_currentDecl);
}
std::string typeString = typeNameResolver.qualTypeToDataType(parameter->getType())->getFullTypeName();
std::string typeString = typeNameResolver.getName(parameter->getType())->toString();
if (parameter->isTemplateParameterPack())
{
@@ -2,30 +2,29 @@
#define CXX_DECL_NAME_RESOLVER_H
#include "data/name/NameHierarchy.h"
#include "data/parser/cxx/name/CxxDeclName.h"
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
class CxxDeclNameResolver: public CxxNameResolver
{
public:
CxxDeclNameResolver(const clang::Decl* declaration);
CxxDeclNameResolver(const clang::Decl* declaration, std::vector<const clang::Decl*> ignoredContextDecls);
CxxDeclNameResolver();
CxxDeclNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
virtual ~CxxDeclNameResolver();
NameHierarchy getDeclNameHierarchy();
std::shared_ptr<NameElement> getDeclName();
std::shared_ptr<CxxDeclName> getName(const clang::NamedDecl* declaration);
private:
NameHierarchy getContextNameHierarchy(const clang::DeclContext* declaration);
NameHierarchy getContextNameHierarchy(const clang::NestedNameSpecifier* specifier);
std::shared_ptr<NameElement> getDeclName(const clang::NamedDecl* declaration);
std::shared_ptr<NameElement> getNameForAnonymousSymbol(const std::string& symbolKindName, const clang::PresumedLoc& presumedBegin);
std::shared_ptr<CxxName> getContextName(const clang::DeclContext* declaration);
std::shared_ptr<CxxDeclName> getDeclName(const clang::NamedDecl* declaration);
std::string getNameForAnonymousSymbol(const std::string& symbolKindName, const clang::PresumedLoc& presumedBegin);
std::string getTemplateParameterString(const clang::NamedDecl* parameter);
std::string getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter);
std::string getTemplateParameterTypeString(const clang::TemplateTypeParmDecl* parameter);
std::string getTemplateParameterTypeString(const clang::TemplateTemplateParmDecl* parameter);
std::string getTemplateArgumentName(const clang::TemplateArgument& argument);
const clang::Decl* m_declaration;
const clang::NamedDecl* m_currentDecl;
};
#endif // CXX_DECL_NAME_RESOLVER_H
@@ -21,39 +21,45 @@ CxxSpecifierNameResolver::~CxxSpecifierNameResolver()
{
}
NameHierarchy CxxSpecifierNameResolver::getNameHierarchy(const clang::NestedNameSpecifier* nestedNameSpecifier)
std::shared_ptr<CxxName> CxxSpecifierNameResolver::getName(const clang::NestedNameSpecifier* nestedNameSpecifier)
{
clang::NestedNameSpecifier::SpecifierKind nnsKind = nestedNameSpecifier->getKind();
NameHierarchy typeNameHerarchy;
std::shared_ptr<CxxName> name;
switch (nnsKind)
{
case clang::NestedNameSpecifier::Identifier:
{
const clang::NestedNameSpecifier* prefix = nestedNameSpecifier->getPrefix();
if (prefix)
name = std::make_shared<CxxDeclName>(
nestedNameSpecifier->getAsIdentifier()->getName(), std::vector<std::string>()
);
if (const clang::NestedNameSpecifier* prefix = nestedNameSpecifier->getPrefix())
{
typeNameHerarchy = getNameHierarchy(prefix);
std::shared_ptr<CxxName> parentName = getName(prefix);
if (parentName)
{
name->setParent(parentName);
}
}
typeNameHerarchy.push(std::make_shared<NameElement>(nestedNameSpecifier->getAsIdentifier()->getName()));
}
break;
case clang::NestedNameSpecifier::Namespace:
{
CxxDeclNameResolver declNameResolver(nestedNameSpecifier->getAsNamespace(), getIgnoredContextDecls());
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespace());
}
break;
case clang::NestedNameSpecifier::NamespaceAlias:
{
CxxDeclNameResolver declNameResolver(nestedNameSpecifier->getAsNamespaceAlias(), getIgnoredContextDecls());
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
name = declNameResolver.getName(nestedNameSpecifier->getAsNamespaceAlias());
}
break;
case clang::NestedNameSpecifier::TypeSpec:
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
{
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
typeNameHerarchy = typeNameResolver.getTypeNameHierarchy(nestedNameSpecifier->getAsType());
name = typeNameResolver.getName(nestedNameSpecifier->getAsType());
}
break;
case clang::NestedNameSpecifier::Global:
@@ -61,10 +67,10 @@ NameHierarchy CxxSpecifierNameResolver::getNameHierarchy(const clang::NestedName
break;
case clang::NestedNameSpecifier::Super:
{
CxxDeclNameResolver declNameResolver(nestedNameSpecifier->getAsRecordDecl(), getIgnoredContextDecls());
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
name = declNameResolver.getName(nestedNameSpecifier->getAsRecordDecl());
}
break;
}
return typeNameHerarchy;
return name;
}
@@ -1,8 +1,10 @@
#ifndef CXX_SPECIFIER_NAME_RESOLVER_H
#define CXX_SPECIFIER_NAME_RESOLVER_H
#include <memory>
#include "data/parser/cxx/name/CxxDeclName.h"
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
#include "data/type/DataType.h"
class CxxSpecifierNameResolver: public CxxNameResolver
{
@@ -11,7 +13,7 @@ public:
CxxSpecifierNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
virtual ~CxxSpecifierNameResolver();
NameHierarchy getNameHierarchy(const clang::NestedNameSpecifier* nestedNameSpecifier);
std::shared_ptr<CxxName> getName(const clang::NestedNameSpecifier* nestedNameSpecifier);
};
#endif // CXX_SPECIFIER_NAME_RESOLVER_H
@@ -4,7 +4,6 @@
#include <clang/AST/DeclTemplate.h>
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
#include "data/type/NamedDataType.h"
#include "utility/logging/logging.h"
CxxTemplateArgumentNameResolver::CxxTemplateArgumentNameResolver()
@@ -23,7 +22,7 @@ CxxTemplateArgumentNameResolver::~CxxTemplateArgumentNameResolver()
std::string CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clang::TemplateArgument& argument)
{
// This doesn't work correctly if the template argument is dependent.
// This doesn't work correctly if the template argument is dependent.
// If that's required: build name from depth and index of template arg.
const clang::TemplateArgument::ArgKind kind = argument.getKind();
switch (kind)
@@ -31,7 +30,7 @@ std::string CxxTemplateArgumentNameResolver::getTemplateArgumentName(const clang
case clang::TemplateArgument::Type:
{
CxxTypeNameResolver typeNameResolver(getIgnoredContextDecls());
return typeNameResolver.qualTypeToDataType(argument.getAsType())->getFullTypeName();
return typeNameResolver.getName(argument.getAsType())->toString();
}
case clang::TemplateArgument::Integral:
case clang::TemplateArgument::Null:
@@ -7,11 +7,6 @@
#include "data/parser/cxx/name_resolver/CxxDeclNameResolver.h"
#include "data/parser/cxx/name_resolver/CxxSpecifierNameResolver.h"
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
#include "data/type/DataType.h"
#include "data/type/NamedDataType.h"
#include "data/type/ArrayModifiedDataType.h"
#include "data/type/PointerModifiedDataType.h"
#include "data/type/ReferenceModifiedDataType.h"
#include "utility/logging/logging.h"
CxxTypeNameResolver::CxxTypeNameResolver()
@@ -28,200 +23,207 @@ CxxTypeNameResolver::~CxxTypeNameResolver()
{
}
std::shared_ptr<DataType> CxxTypeNameResolver::qualTypeToDataType(clang::QualType qualType)
std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::QualType& qualType)
{
std::shared_ptr<DataType> dataType = typeToDataType(qualType.getTypePtr());
std::shared_ptr<CxxTypeName> typeName = getName(qualType.getTypePtr());
if (qualType.isConstQualified())
{
dataType->addQualifier(DataType::QUALIFIER_CONST);
typeName->addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
}
return dataType;
return typeName;
}
std::shared_ptr<DataType> CxxTypeNameResolver::typeToDataType(const clang::Type* type)
std::shared_ptr<CxxTypeName> CxxTypeNameResolver::getName(const clang::Type* type)
{
std::shared_ptr<DataType> dataType;
std::shared_ptr<CxxTypeName> typeName;
switch (type->getTypeClass())
{
case clang::Type::Paren:
{
dataType = qualTypeToDataType(type->getAs<clang::ParenType>()->getInnerType());
break;
}
{
typeName = getName(type->getAs<clang::ParenType>()->getInnerType());
break;
}
case clang::Type::Typedef:
{
CxxDeclNameResolver declNameResolver(type->getAs<clang::TypedefType>()->getDecl(), getIgnoredContextDecls());
dataType = std::make_shared<NamedDataType>(declNameResolver.getDeclNameHierarchy());
break;
}
{
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TypedefType>()->getDecl());
typeName = std::make_shared<CxxTypeName>(
declName->getName(),
std::vector<std::string>(),
declName->getParent()
);
break;
}
case clang::Type::MemberPointer:
{
// test this case!
}
{
// test this case!
}
case clang::Type::Pointer:
{
std::shared_ptr<DataType> innerType = qualTypeToDataType(type->getPointeeType());
dataType = std::make_shared<PointerModifiedDataType>(innerType);
break;
}
{
typeName = getName(type->getPointeeType());
typeName->addModifier(CxxTypeName::Modifier("*"));
break;
}
case clang::Type::ConstantArray:
case clang::Type::DependentSizedArray:
case clang::Type::IncompleteArray:
case clang::Type::VariableArray:
{
std::shared_ptr<DataType> innerType = qualTypeToDataType(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
dataType = std::make_shared<ArrayModifiedDataType>(innerType);
break;
}
{
typeName = getName(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
typeName->addModifier(CxxTypeName::Modifier("[]"));
break;
}
case clang::Type::LValueReference:
case clang::Type::RValueReference:
{
std::shared_ptr<DataType> innerType = qualTypeToDataType(type->getPointeeType());
dataType = std::make_shared<ReferenceModifiedDataType>(innerType);
break;
}
{
typeName = getName(type->getPointeeType());
typeName->addModifier(CxxTypeName::Modifier("&"));
break;
}
case clang::Type::Elaborated:
{
dataType = qualTypeToDataType(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
break;
}
{
typeName = getName(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
break;
}
case clang::Type::Enum:
case clang::Type::Record:
{
CxxDeclNameResolver declNameResolver(type->getAs<clang::TagType>()->getDecl(), getIgnoredContextDecls());
dataType = std::make_shared<NamedDataType>(declNameResolver.getDeclNameHierarchy());
break;
}
{
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(type->getAs<clang::TagType>()->getDecl());
typeName = std::make_shared<CxxTypeName>(
declName->getName(),
std::vector<std::string>(),
declName->getParent()
);
break;
}
case clang::Type::Builtin:
{
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
{
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
std::string typeName = type->getAs<clang::BuiltinType>()->getName(pp);
NameHierarchy typeNameHerarchy;
typeNameHerarchy.push(std::make_shared<NameElement>(typeName));
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
break;
}
typeName = std::make_shared<CxxTypeName>(
type->getAs<clang::BuiltinType>()->getName(pp), std::vector<std::string>()
);
break;
}
case clang::Type::TemplateSpecialization:
{
const clang::TagType* tagType = type->getAs<clang::TagType>(); // remove this case when NameHierarchy is split into namepart and parameter part
if (tagType)
{
NameHierarchy typeNameHerarchy;
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(tagType->getDecl());
const clang::TagType* tagType = type->getAs<clang::TagType>(); // remove this case when NameHierarchy is split into namepart and parameter part
if (tagType)
{
CxxDeclNameResolver declNameResolver(tagType->getDecl(), getIgnoredContextDecls());
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
}
else // specialization of a template template parameter (no concrete class) important, may help: has no underlying decl!
{
const clang::TemplateSpecializationType* templateSpecializationType = type->getAs<clang::TemplateSpecializationType>();
CxxDeclNameResolver declNameResolver(templateSpecializationType->getTemplateName().getAsTemplateDecl(), getIgnoredContextDecls());
typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
typeName = std::make_shared<CxxTypeName>(
declName->getName(),
declName->getTemplateParameterNames(),
declName->getParent()
);
}
else // specialization of a template template parameter (no concrete class) important, may help: has no underlying decl!
{
const clang::TemplateSpecializationType* templateSpecializationType = type->getAs<clang::TemplateSpecializationType>();
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
const std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(templateSpecializationType->getTemplateName().getAsTemplateDecl());
if (typeNameHerarchy.size() > 0)
if (declName)
{
std::vector<std::string> templateArguments;
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
{
std::string templateArgumentNamePart = "<";
CxxTemplateArgumentNameResolver resolver(getIgnoredContextDecls());
for (size_t i = 0; i < templateSpecializationType->getNumArgs(); i++)
{
templateArgumentNamePart += resolver.getTemplateArgumentName(templateSpecializationType->getArg(i));
if (i + 1 < templateSpecializationType->getNumArgs())
templateArgumentNamePart += ", ";
}
templateArgumentNamePart += ">";
std::string declName = typeNameHerarchy.back()->getName();
declName = declName.substr(0, declName.rfind("<")); // remove template parameters
declName += templateArgumentNamePart; // add template arguments
typeNameHerarchy.pop();
typeNameHerarchy.push(std::make_shared<NameElement>(declName)); // templateSpecialization has no signature.
templateArguments.push_back(resolver.getTemplateArgumentName(templateSpecializationType->getArg(i)));
}
}
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
break;
}
case clang::Type::TemplateTypeParm:
{
clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl();
CxxDeclNameResolver declNameResolver(templateTypeParmDecl, getIgnoredContextDecls());
NameHierarchy typeNameHerarchy = declNameResolver.getDeclNameHierarchy();
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
break;
}
case clang::Type::SubstTemplateTypeParm:
{
dataType = qualTypeToDataType(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
break;
}
case clang::Type::DependentName:
{
const clang::DependentNameType* dependentNameType = clang::dyn_cast<clang::DependentNameType>(type);
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
NameHierarchy typeNameHerarchy = specifierNameResolver.getNameHierarchy(dependentNameType->getQualifier());
typeNameHerarchy.push(std::make_shared<NameElement>(dependentNameType->getIdentifier()->getName().str()));
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
break;
}
case clang::Type::PackExpansion:
{
const clang::PackExpansionType* packExpansionType = clang::dyn_cast<clang::PackExpansionType>(type);
dataType = qualTypeToDataType(packExpansionType->getPattern());
break;
}
case clang::Type::Auto:
{
clang::QualType deducedType = clang::dyn_cast<clang::AutoType>(type)->getDeducedType();
if (!deducedType.isNull())
{
dataType = qualTypeToDataType(deducedType);
typeName = std::make_shared<CxxTypeName>(
declName->getName(), templateArguments, declName->getParent()
);
}
else
{
NameHierarchy typeNameHerarchy;
typeNameHerarchy.push(std::make_shared<NameElement>("auto"));
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
LOG_WARNING("no decl found");
}
break;
}
case clang::Type::Decltype:
{
const clang::DecltypeType* decltypeType = clang::dyn_cast<clang::DecltypeType>(type);
dataType = qualTypeToDataType(decltypeType->getUnderlyingType());
break;
}
default:
{
std::string typeClassName = type->getTypeClassName();
LOG_INFO(std::string("Unhandled kind of type encountered: ") + typeClassName);
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
clang::SmallString<64> Buf;
llvm::raw_svector_ostream StrOS(Buf);
clang::QualType::print(type, clang::Qualifiers(), StrOS, pp, clang::Twine());
std::string typeName = StrOS.str();
NameHierarchy typeNameHerarchy;
typeNameHerarchy.push(std::make_shared<NameElement>(typeName));
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
break;
}
break;
}
return dataType;
}
case clang::Type::TemplateTypeParm:
{
CxxDeclNameResolver declNameResolver(getIgnoredContextDecls());
std::shared_ptr<CxxDeclName> declName = declNameResolver.getName(clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl());
NameHierarchy CxxTypeNameResolver::getTypeNameHierarchy(const clang::Type* type)
{
return typeToDataType(type)->getTypeNameHierarchy();
typeName = std::make_shared<CxxTypeName>(
declName->getName(),
declName->getTemplateParameterNames(),
declName->getParent()
);
break;
}
case clang::Type::SubstTemplateTypeParm:
{
typeName = getName(type->getAs<clang::SubstTemplateTypeParmType>()->getReplacementType());
break;
}
case clang::Type::DependentName:
{
const clang::DependentNameType* dependentNameType = clang::dyn_cast<clang::DependentNameType>(type);
CxxSpecifierNameResolver specifierNameResolver(getIgnoredContextDecls());
std::shared_ptr<CxxName> specifierName = specifierNameResolver.getName(dependentNameType->getQualifier());
// TODO: TEst what if this one has template args?
typeName = std::make_shared<CxxTypeName>(
dependentNameType->getIdentifier()->getName().str(), std::vector<std::string>(), specifierName
);
break;
}
case clang::Type::PackExpansion:
{
typeName = getName(clang::dyn_cast<clang::PackExpansionType>(type)->getPattern());
break;
}
case clang::Type::Auto:
{
clang::QualType deducedType = clang::dyn_cast<clang::AutoType>(type)->getDeducedType();
if (!deducedType.isNull())
{
typeName = getName(deducedType);
}
else
{
typeName = std::make_shared<CxxTypeName>(
"auto", std::vector<std::string>()
);
}
break;
}
case clang::Type::Decltype:
{
typeName = getName(clang::dyn_cast<clang::DecltypeType>(type)->getUnderlyingType());
break;
}
default:
{
std::string typeClassName = type->getTypeClassName();
LOG_INFO(std::string("Unhandled kind of type encountered: ") + typeClassName);
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
clang::SmallString<64> Buf;
llvm::raw_svector_ostream StrOS(Buf);
clang::QualType::print(type, clang::Qualifiers(), StrOS, pp, clang::Twine());
std::string nameString = StrOS.str();
typeName = std::make_shared<CxxTypeName>(
nameString, std::vector<std::string>()
);
break;
}
}
return typeName;
}
@@ -1,8 +1,8 @@
#ifndef CXX_TYPE_NAME_RESOLVER_H
#define CXX_TYPE_NAME_RESOLVER_H
#include "data/parser/cxx/name/CxxTypeName.h"
#include "data/parser/cxx/name_resolver/CxxNameResolver.h"
#include "data/type/DataType.h"
class CxxTypeNameResolver: public CxxNameResolver
{
@@ -11,11 +11,8 @@ public:
CxxTypeNameResolver(std::vector<const clang::Decl*> ignoredContextDecls);
virtual ~CxxTypeNameResolver();
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType);
NameHierarchy getTypeNameHierarchy(const clang::Type* type);
private:
std::shared_ptr<DataType> typeToDataType(const clang::Type* type);
std::shared_ptr<CxxTypeName> getName(const clang::QualType& qualType);
std::shared_ptr<CxxTypeName> getName(const clang::Type* type);
};
#endif // CXX_TYPE_NAME_RESOLVER_H
+2 -1
View File
@@ -2,11 +2,11 @@
#include "data/parser/cxx/name_resolver/CxxDeclNameResolver.h"
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
#include "data/type/NamedDataType.h"
#include "utility/logging/logging.h"
namespace utility
{
/*
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType)
{
CxxTypeNameResolver resolver;
@@ -94,4 +94,5 @@ namespace utility
}
return std::make_shared<NamedDataType>(NameHierarchy());
}
*/
}
+1 -1
View File
@@ -10,7 +10,7 @@ add_files(
ConfigManagerTestSuite.h
CxxParserTestSuite.h
DataTypeTestSuite.h
CxxTypeNameTestSuite.h
FileManagerTestSuite.h
FilePathTestSuite.h
FileSystemTestSuite.h
+2 -2
View File
@@ -185,7 +185,7 @@ public:
TS_ASSERT_EQUALS(client->methods.size(), 4);
TS_ASSERT_EQUALS(client->methods[0], "public void B::B() <4:2 4:2>");
TS_ASSERT_EQUALS(client->methods[1], "public void B::B(B const &) <1:7 1:7>");
TS_ASSERT_EQUALS(client->methods[1], "public void B::B(const B &) <1:7 1:7>");
TS_ASSERT_EQUALS(client->methods[2], "public void B::B(B &) <1:7 1:7>");
TS_ASSERT_EQUALS(client->methods[3], "public void B::B() <6:1 <6:4 6:4> 8:1>");
}
@@ -1708,7 +1708,7 @@ public:
TS_ASSERT_EQUALS(client->calls.size(), 2);
TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <9:6 9:8>");
TS_ASSERT_EQUALS(client->calls[1], "int main() -> void App::App(App const &) <10:6 10:9>");
TS_ASSERT_EQUALS(client->calls[1], "int main() -> void App::App(const App &) <10:6 10:9>");
}
void test_cxx_parser_finds_global_variable_constructor_call()
+44
View File
@@ -0,0 +1,44 @@
#include "cxxtest/TestSuite.h"
#include "utility/utilityString.h"
#include "data/parser/cxx/name/CxxTypeName.h"
class CxxTypeNameTestSuite: public CxxTest::TestSuite
{
public:
void test_type_name_created_with_name_has_no_qualifiers_or_modifiers()
{
CxxTypeName typeName("int", std::vector<std::string>(), std::shared_ptr<CxxName>());
TS_ASSERT_EQUALS("int", typeName.toString());
}
void test_type_name_created_with_name_and_const_qualifier_has_no_modifiers()
{
CxxTypeName typeName("int", std::vector<std::string>(), std::shared_ptr<CxxName>());
typeName.addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
TS_ASSERT_EQUALS("const int", typeName.toString());
}
void test_type_name_created_with_name_and_array_modifier_has_array_modifier()
{
CxxTypeName typeName("int", std::vector<std::string>(), std::shared_ptr<CxxName>());
typeName.addModifier(CxxTypeName::Modifier("[]"));
TS_ASSERT_EQUALS("int []", typeName.toString());
}
void test_type_name_created_with_name_and_const_pointer_modifier_has_const_pointer_modifier()
{
CxxTypeName typeName("int", std::vector<std::string>(), std::shared_ptr<CxxName>());
typeName.addModifier(CxxTypeName::Modifier("*"));
typeName.addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
TS_ASSERT_EQUALS("int * const", typeName.toString());
}
void test_type_name_created_with_name_and_pointer_pointer_modifier_has_pointer_pointer_modifier()
{
CxxTypeName typeName("int", std::vector<std::string>(), std::shared_ptr<CxxName>());
typeName.addModifier(CxxTypeName::Modifier("*"));
typeName.addModifier(CxxTypeName::Modifier("*"));
TS_ASSERT_EQUALS("int * *", typeName.toString());
}
};
-82
View File
@@ -1,82 +0,0 @@
#include "cxxtest/TestSuite.h"
#include "utility/utilityString.h"
#include "data/type/DataType.h"
#include "data/type/NamedDataType.h"
#include "data/type/ArrayModifiedDataType.h"
#include "data/type/PointerModifiedDataType.h"
#include "data/type/ReferenceModifiedDataType.h"
class DataTypeTestSuite: public CxxTest::TestSuite
{
public:
void test_datatype_created_with_name_has_no_qualifiers_or_modifiers()
{
NamedDataType dataType(createNameHierarchy("int"));
TS_ASSERT_EQUALS("int", dataType.getFullTypeName());
}
void test_datatype_created_with_name_and_const_qualifier_has_no_modifiers()
{
NamedDataType dataType(createNameHierarchy("int"));
dataType.addQualifier(DataType::QUALIFIER_CONST);
TS_ASSERT_EQUALS("int const", dataType.getFullTypeName());
}
//void __test_datatype_created_with_name_and_empty_modifierstack_has_no_modifiers()
//{
// DataTypeQualifierList qualifierList;
// DataTypeModifierStack modifierStack;
// DataType dataType(createNameHierarchy("int"), qualifierList, modifierStack);
// TS_ASSERT_EQUALS("int", dataType.getFullTypeName());
//}
void test_datatype_created_with_name_and_array_modifier_has_array_modifier()
{
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(createNameHierarchy("int"));
std::shared_ptr<DataType> dataType2 = std::make_shared<ArrayModifiedDataType>(dataType1);
TS_ASSERT_EQUALS("int []", dataType2->getFullTypeName());
}
void test_datatype_created_with_name_and_pointer_modifier_has_pointer_modifier()
{
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(createNameHierarchy("int"));
std::shared_ptr<DataType> dataType2 = std::make_shared<PointerModifiedDataType>(dataType1);
TS_ASSERT_EQUALS("int *", dataType2->getFullTypeName());
}
void test_datatype_created_with_name_and_reference_modifier_has_reference_modifier()
{
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(createNameHierarchy("int"));
std::shared_ptr<DataType> dataType2 = std::make_shared<ReferenceModifiedDataType>(dataType1);
TS_ASSERT_EQUALS("int &", dataType2->getFullTypeName());
}
void test_datatype_created_with_name_and_const_pointer_modifier_has_const_pointer_modifier()
{
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(createNameHierarchy("int"));
std::shared_ptr<DataType> dataType2 = std::make_shared<PointerModifiedDataType>(dataType1);
dataType2->addQualifier(DataType::QUALIFIER_CONST);
TS_ASSERT_EQUALS("int * const", dataType2->getFullTypeName());
}
void test_datatype_created_with_name_and_pointer_pointer_modifier_has_pointer_pointer_modifier()
{
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(createNameHierarchy("int"));
std::shared_ptr<DataType> dataType2 = std::make_shared<PointerModifiedDataType>(dataType1);
std::shared_ptr<DataType> dataType3 = std::make_shared<PointerModifiedDataType>(dataType2);
TS_ASSERT_EQUALS("int * *", dataType3->getFullTypeName());
}
private:
NameHierarchy createNameHierarchy(std::string s) const
{
NameHierarchy nameHierarchy;
for (std::string element: utility::splitToVector(s, "::"))
{
nameHierarchy.push(std::make_shared<NameElement>(element));
}
return nameHierarchy;
}
};
-2
View File
@@ -8,8 +8,6 @@
#include "data/location/TokenLocation.h"
#include "data/parser/ParseLocation.h"
#include "data/PersistentStorage.h"
#include "data/type/DataType.h"
#include "data/type/NamedDataType.h"
class StorageTestSuite: public CxxTest::TestSuite
{