data: fixed crashed when parsing own code
* fixed test that was expecting a wrong result. * refactored DataType class. * added code to parse dependent type names. * refactored utilityCxx a little.
This commit is contained in:
+1
-1
@@ -2,8 +2,8 @@
|
||||
|
||||
/bin/app/Debug/
|
||||
/bin/app/data/log/
|
||||
/bin/app/data/projects/
|
||||
/bin/app/data/ApplicationSettings.xml
|
||||
/bin/app/data/ProjectSettings.xml
|
||||
/bin/app/data/window_settings.ini
|
||||
/bin/app/Release/
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ConfigManager.cpp ERROR: value path/to/nowhere is not present in config.
|
||||
ConfigManager.cpp WARNING: value path/to/nowhere is not present in config.
|
||||
Storage.cpp INFO: file: input.cc < 0:0 0:0>
|
||||
Storage.cpp INFO: class: A <input.cc 1:7 1:7>
|
||||
Storage.cpp INFO: method: A::A <input.cc 4:2 4:2>
|
||||
@@ -57,20 +57,20 @@ Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined
|
||||
Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined
|
||||
Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined
|
||||
Settings.cpp WARNING: File for Settings not found.
|
||||
ConfigManager.cpp ERROR: value Bool is not present in config.
|
||||
ConfigManager.cpp ERROR: value Int is not present in config.
|
||||
ConfigManager.cpp ERROR: value Float is not present in config.
|
||||
ConfigManager.cpp ERROR: value String is not present in config.
|
||||
ConfigManager.cpp WARNING: value Bool is not present in config.
|
||||
ConfigManager.cpp WARNING: value Int is not present in config.
|
||||
ConfigManager.cpp WARNING: value Float is not present in config.
|
||||
ConfigManager.cpp WARNING: value String is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found.
|
||||
ConfigManager.cpp ERROR: value Bool is not present in config.
|
||||
ConfigManager.cpp ERROR: value Int is not present in config.
|
||||
ConfigManager.cpp ERROR: value Float is not present in config.
|
||||
ConfigManager.cpp ERROR: value String is not present in config.
|
||||
ConfigManager.cpp ERROR: value Bool is not present in config.
|
||||
ConfigManager.cpp ERROR: value Int is not present in config.
|
||||
ConfigManager.cpp ERROR: value Float is not present in config.
|
||||
ConfigManager.cpp ERROR: value String is not present in config.
|
||||
ConfigManager.cpp ERROR: value NewBool is not present in config.
|
||||
ConfigManager.cpp WARNING: value Bool is not present in config.
|
||||
ConfigManager.cpp WARNING: value Int is not present in config.
|
||||
ConfigManager.cpp WARNING: value Float is not present in config.
|
||||
ConfigManager.cpp WARNING: value String is not present in config.
|
||||
ConfigManager.cpp WARNING: value Bool is not present in config.
|
||||
ConfigManager.cpp WARNING: value Int is not present in config.
|
||||
ConfigManager.cpp WARNING: value Float is not present in config.
|
||||
ConfigManager.cpp WARNING: value String is not present in config.
|
||||
ConfigManager.cpp WARNING: value NewBool is not present in config.
|
||||
Graph.cpp ERROR: Can't remove member edge, without removing the child node.
|
||||
Storage.cpp INFO: typedef: type -> int <file.cpp 1:1 1:1>
|
||||
Storage.cpp INFO: class: Class <file.cpp 1:1 1:1>
|
||||
|
||||
+10
-13
@@ -170,21 +170,18 @@ add_files(
|
||||
data/search/SearchResult.cpp
|
||||
data/search/SearchResult.h
|
||||
|
||||
data/type/modifier/DataTypeModifier.cpp
|
||||
data/type/modifier/DataTypeModifier.h
|
||||
data/type/modifier/DataTypeModifierArray.cpp
|
||||
data/type/modifier/DataTypeModifierArray.h
|
||||
data/type/modifier/DataTypeModifierPointer.cpp
|
||||
data/type/modifier/DataTypeModifierPointer.h
|
||||
data/type/modifier/DataTypeModifierReference.cpp
|
||||
data/type/modifier/DataTypeModifierReference.h
|
||||
|
||||
data/type/ArrayModifiedDataType.cpp
|
||||
data/type/ArrayModifiedDataType.h
|
||||
data/type/DataType.cpp
|
||||
data/type/DataType.h
|
||||
data/type/DataTypeModifierStack.cpp
|
||||
data/type/DataTypeModifierStack.h
|
||||
data/type/DataTypeQualifierList.cpp
|
||||
data/type/DataTypeQualifierList.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/Storage.cpp
|
||||
data/Storage.h
|
||||
|
||||
@@ -200,7 +200,7 @@ Id Storage::onTypedefParsed(
|
||||
const ParseLocation& location, const std::vector<std::string>& nameHierarchy, const ParseTypeUsage& underlyingType,
|
||||
AccessType access
|
||||
){
|
||||
log("typedef", utility::join(nameHierarchy, "::") + " -> " + underlyingType.dataType.getFullTypeName(), location);
|
||||
log("typedef", utility::join(nameHierarchy, "::") + " -> " + underlyingType.dataType->getFullTypeName(), location);
|
||||
|
||||
Node* node = addNodeHierarchy(Node::NODE_TYPEDEF, nameHierarchy);
|
||||
addAccess(node, access);
|
||||
@@ -503,7 +503,7 @@ Id Storage::onEnumConstantUsageParsed(
|
||||
|
||||
Id Storage::onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& function)
|
||||
{
|
||||
log("type usage", function.getFullName() + " -> " + type.dataType.getRawTypeName(), type.location);
|
||||
log("type usage", function.getFullName() + " -> " + type.dataType->getRawTypeName(), type.location);
|
||||
|
||||
Node* functionNode = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, function);
|
||||
Edge* edge = addTypeEdge(functionNode, Edge::EDGE_TYPE_USAGE, type);
|
||||
@@ -519,7 +519,7 @@ Id Storage::onTypeUsageParsed(const ParseTypeUsage& type, const ParseFunction& f
|
||||
|
||||
Id Storage::onTypeUsageParsed(const ParseTypeUsage& type, const ParseVariable& variable)
|
||||
{
|
||||
log("type usage", variable.getFullName() + " -> " + type.dataType.getRawTypeName(), type.location);
|
||||
log("type usage", variable.getFullName() + " -> " + type.dataType->getRawTypeName(), type.location);
|
||||
|
||||
Node* variableNode = addNodeHierarchy(Node::NODE_UNDEFINED, variable.nameHierarchy);
|
||||
Edge* edge = addTypeEdge(variableNode, Edge::EDGE_TYPE_USAGE, type);
|
||||
@@ -560,13 +560,13 @@ Id Storage::onTemplateDefaultArgumentTypeParsed(
|
||||
){
|
||||
log(
|
||||
"template default argument",
|
||||
utility::join(defaultArgumentType.dataType.getTypeNameHierarchy(), "::") +
|
||||
utility::join(defaultArgumentType.dataType->getTypeNameHierarchy(), "::") +
|
||||
" -> " + utility::join(templateArgumentTypeNameHierarchy, "::"),
|
||||
defaultArgumentType.location
|
||||
);
|
||||
|
||||
Node* templateDefaultArgumentNode =
|
||||
addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, defaultArgumentType.dataType.getTypeNameHierarchy());
|
||||
addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, defaultArgumentType.dataType->getTypeNameHierarchy());
|
||||
addTokenLocation(templateDefaultArgumentNode, defaultArgumentType.location);
|
||||
|
||||
Node* templateArgumentNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateArgumentTypeNameHierarchy);
|
||||
@@ -1184,7 +1184,7 @@ Edge* Storage::addTypeEdge(Node* node, Edge::EdgeType edgeType, const ParseTypeU
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> nameHierarchy = typeUsage.dataType.getTypeNameHierarchy();
|
||||
std::vector<std::string> nameHierarchy = typeUsage.dataType->getTypeNameHierarchy();
|
||||
|
||||
Node* typeNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, nameHierarchy);
|
||||
if (!typeNode)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
|
||||
ParseTypeUsage::ParseTypeUsage(const ParseLocation& location, const DataType& dataType)
|
||||
ParseTypeUsage::ParseTypeUsage(const ParseLocation& location, const std::shared_ptr<DataType> dataType)
|
||||
: location(location)
|
||||
, dataType(dataType)
|
||||
{
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#ifndef PARSE_TYPE_USAGE_H
|
||||
#define PARSE_TYPE_USAGE_H
|
||||
|
||||
#include <memory>
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
|
||||
struct ParseTypeUsage
|
||||
{
|
||||
ParseTypeUsage(const ParseLocation& location, const DataType& dataType);
|
||||
ParseTypeUsage(const ParseLocation& location, const std::shared_ptr<DataType> dataType);
|
||||
|
||||
const ParseLocation location;
|
||||
const DataType dataType;
|
||||
const std::shared_ptr<DataType> dataType;
|
||||
};
|
||||
|
||||
#endif // PARSE_TYPE_USAGE_H
|
||||
|
||||
@@ -87,7 +87,7 @@ std::string ParserClient::addLocationSuffix(
|
||||
|
||||
std::string ParserClient::variableStr(const ParseVariable& variable)
|
||||
{
|
||||
std::string str = variable.type.dataType.getFullTypeName() + " " + variable.getFullName();
|
||||
std::string str = variable.type.dataType->getFullTypeName() + " " + variable.getFullName();
|
||||
return addStaticPrefix(str, variable.isStatic);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ std::string ParserClient::parameterStr(const std::vector<ParseTypeUsage> paramet
|
||||
std::string str = "(";
|
||||
for (size_t i = 0; i < parameters.size(); i++)
|
||||
{
|
||||
str += parameters[i].dataType.getFullTypeName();
|
||||
str += parameters[i].dataType->getFullTypeName();
|
||||
if (i < parameters.size() - 1)
|
||||
{
|
||||
str += ", ";
|
||||
@@ -108,7 +108,7 @@ std::string ParserClient::parameterStr(const std::vector<ParseTypeUsage> paramet
|
||||
std::string ParserClient::functionStr(const ParseFunction& function)
|
||||
{
|
||||
std::string str =
|
||||
function.returnType.dataType.getFullTypeName() + " " + function.getFullName() + parameterStr(function.parameters);
|
||||
function.returnType.dataType->getFullTypeName() + " " + function.getFullName() + parameterStr(function.parameters);
|
||||
return addConstPrefix(addStaticPrefix(str, function.isStatic), function.isConst, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/NamedDataType.h"
|
||||
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, ParserClient* client, FileRegister* fileRegister)
|
||||
: m_context(context)
|
||||
@@ -79,7 +80,7 @@ bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
|
||||
m_client->onInheritanceParsed(
|
||||
getParseLocation(it.getSourceRange()),
|
||||
utility::getDeclNameHierarchy(declaration),
|
||||
utility::qualTypeToDataType(it.getType()).getTypeNameHierarchy(),
|
||||
utility::qualTypeToDataType(it.getType())->getTypeNameHierarchy(),
|
||||
convertAccessType(it.getAccessSpecifier())
|
||||
);
|
||||
}
|
||||
@@ -299,7 +300,7 @@ bool ASTVisitor::VisitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl *
|
||||
{
|
||||
const clang::TemplateArgumentLoc& defaultArgumentLoc = declaration->getDefaultArgument();
|
||||
clang::SourceRange sr = defaultArgumentLoc.getSourceRange();
|
||||
DataType defaultArgumentDataType(utility::getDeclNameHierarchy(defaultArgumentLoc.getArgument().getAsTemplate().getAsTemplateDecl()));
|
||||
std::shared_ptr<DataType> defaultArgumentDataType = std::make_shared<NamedDataType>(utility::getDeclNameHierarchy(defaultArgumentLoc.getArgument().getAsTemplate().getAsTemplateDecl()));
|
||||
m_client->onTemplateDefaultArgumentTypeParsed(
|
||||
getParseTypeUsage(sr, defaultArgumentDataType),
|
||||
utility::getDeclNameHierarchy(declaration)
|
||||
@@ -353,7 +354,7 @@ bool ASTVisitor::VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration)
|
||||
const clang::TemplateArgumentList &argList = specializationDecl->getTemplateArgs();
|
||||
for (size_t i = 0; i < argList.size(); i++)
|
||||
{
|
||||
std::vector<std::string> argumentNameHierarchy = utility::templateArgumentToDataType(argList.get(i)).getTypeNameHierarchy();
|
||||
std::vector<std::string> argumentNameHierarchy = utility::templateArgumentToDataType(argList.get(i))->getTypeNameHierarchy();
|
||||
|
||||
if (argumentNameHierarchy.size()) // FIXME: Some TemplateArgument kinds are not handled yet.
|
||||
{
|
||||
@@ -403,7 +404,7 @@ bool ASTVisitor::VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplat
|
||||
|
||||
m_client->onTemplateArgumentTypeParsed(
|
||||
getParseLocation(argumentLoc.getSourceRange()),
|
||||
utility::templateArgumentToDataType(argument).getTypeNameHierarchy(),
|
||||
utility::templateArgumentToDataType(argument)->getTypeNameHierarchy(),
|
||||
specializedRecordNameHierarchy);
|
||||
}
|
||||
}
|
||||
@@ -458,7 +459,7 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat
|
||||
|
||||
m_client->onTemplateArgumentTypeParsed(
|
||||
getParseLocation(argumentLoc.getSourceRange()),
|
||||
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
|
||||
utility::qualTypeToDataType(argumentType)->getTypeNameHierarchy(),
|
||||
specializedFunction.nameHierarchy);
|
||||
}
|
||||
}
|
||||
@@ -478,7 +479,7 @@ bool ASTVisitor::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declarat
|
||||
|
||||
m_client->onTemplateArgumentTypeParsed(
|
||||
ParseLocation(specializedFunctionLocation.filePath, 0, 0), // TODO: Find a valid ParseLocation here!
|
||||
utility::qualTypeToDataType(argumentType).getTypeNameHierarchy(),
|
||||
utility::qualTypeToDataType(argumentType)->getTypeNameHierarchy(),
|
||||
specializedFunction.nameHierarchy);
|
||||
}
|
||||
}
|
||||
@@ -794,11 +795,11 @@ ParseLocation ASTVisitor::getParseLocationOfRecordBody(clang::CXXRecordDecl* dec
|
||||
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsage(const clang::TypeLoc& typeLoc, const clang::QualType& type) const
|
||||
{
|
||||
DataType dataType = utility::qualTypeToDataType(type);
|
||||
std::shared_ptr<DataType> dataType = utility::qualTypeToDataType(type);
|
||||
return getParseTypeUsage(typeLoc, dataType);
|
||||
}
|
||||
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsage(const clang::TypeLoc& typeLoc, const DataType& type) const
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsage(const clang::TypeLoc& typeLoc, const std::shared_ptr<DataType> type) const
|
||||
{
|
||||
ParseLocation parseLocation;
|
||||
|
||||
@@ -816,7 +817,7 @@ ParseTypeUsage ASTVisitor::getParseTypeUsage(const clang::TypeLoc& typeLoc, cons
|
||||
return ParseTypeUsage(parseLocation, type);
|
||||
}
|
||||
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsage(const clang::SourceRange& sourceRange, const DataType& type) const
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsage(const clang::SourceRange& sourceRange, const std::shared_ptr<DataType> type) const
|
||||
{
|
||||
ParseLocation parseLocation;
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ private:
|
||||
ParseLocation getParseLocationOfRecordBody(clang::CXXRecordDecl* decl) const;
|
||||
|
||||
ParseTypeUsage getParseTypeUsage(const clang::TypeLoc& typeLoc, const clang::QualType& type) const;
|
||||
ParseTypeUsage getParseTypeUsage(const clang::TypeLoc& typeLoc, const DataType& type) const;
|
||||
ParseTypeUsage getParseTypeUsage(const clang::SourceRange& sourceRange, const DataType& type) const;
|
||||
ParseTypeUsage getParseTypeUsage(const clang::TypeLoc& typeLoc, const std::shared_ptr<DataType> type) const;
|
||||
ParseTypeUsage getParseTypeUsage(const clang::SourceRange& sourceRange, const std::shared_ptr<DataType> type) const;
|
||||
ParseTypeUsage getParseTypeUsageOfReturnType(const clang::FunctionDecl* declaration) const;
|
||||
std::vector<ParseTypeUsage> getParameters(const clang::FunctionDecl* declaration) const;
|
||||
|
||||
|
||||
@@ -5,163 +5,204 @@
|
||||
#include <clang/AST/ASTContext.h>
|
||||
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/modifier/DataTypeModifierArray.h"
|
||||
#include "data/type/modifier/DataTypeModifierPointer.h"
|
||||
#include "data/type/modifier/DataTypeModifierReference.h"
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
#include "data/type/NamedDataType.h"
|
||||
#include "data/type/ArrayModifiedDataType.h"
|
||||
#include "data/type/PointerModifiedDataType.h"
|
||||
#include "data/type/ReferenceModifiedDataType.h"
|
||||
|
||||
#include "utility/utilityString.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
DataType qualTypeToDataType(clang::QualType qualType)
|
||||
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType)
|
||||
{
|
||||
std::vector<std::string> typeNameHerarchy;
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
|
||||
bool needsRefinement = true;
|
||||
|
||||
while (needsRefinement)
|
||||
{
|
||||
const clang::Type* type = qualType.getTypePtr();
|
||||
switch (type->getTypeClass())
|
||||
{
|
||||
case clang::Type::Paren:
|
||||
{
|
||||
qualType = type->getAs<clang::ParenType>()->getInnerType();
|
||||
// what about qualifiers and modifiers
|
||||
break;
|
||||
}
|
||||
case clang::Type::Typedef:
|
||||
{
|
||||
typeNameHerarchy = getDeclNameHierarchy(type->getAs<clang::TypedefType>()->getDecl());
|
||||
needsRefinement = false;
|
||||
break;
|
||||
}
|
||||
case clang::Type::Pointer:
|
||||
{
|
||||
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierPointer>();
|
||||
if (qualType.isConstQualified())
|
||||
{
|
||||
modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
}
|
||||
modifierStack.push(modifier);
|
||||
|
||||
qualType = type->getPointeeType();
|
||||
break;
|
||||
}
|
||||
case clang::Type::ConstantArray:
|
||||
case clang::Type::VariableArray:
|
||||
case clang::Type::DependentSizedArray:
|
||||
case clang::Type::IncompleteArray:
|
||||
{
|
||||
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierArray>();
|
||||
if (qualType.isConstQualified())
|
||||
{
|
||||
modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
}
|
||||
modifierStack.push(modifier);
|
||||
|
||||
qualType = clang::dyn_cast<clang::ArrayType>(type)->getElementType();
|
||||
break;
|
||||
}
|
||||
case clang::Type::LValueReference:
|
||||
case clang::Type::RValueReference:
|
||||
{
|
||||
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierReference>();
|
||||
// references can not be const qualified
|
||||
modifierStack.push(modifier);
|
||||
|
||||
qualType = type->getPointeeType();
|
||||
break;
|
||||
}
|
||||
case clang::Type::Elaborated:
|
||||
{
|
||||
const clang::ElaboratedType* et = clang::dyn_cast<clang::ElaboratedType>(type);
|
||||
qualType = et->getNamedType();
|
||||
break;
|
||||
}
|
||||
case clang::Type::Enum:
|
||||
case clang::Type::Record:
|
||||
{
|
||||
typeNameHerarchy = getDeclNameHierarchy(type->getAs<clang::TagType>()->getDecl());
|
||||
needsRefinement = false;
|
||||
break;
|
||||
}
|
||||
case clang::Type::Builtin:
|
||||
{
|
||||
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
|
||||
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
|
||||
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
|
||||
std::string typeName = qualType.getUnqualifiedType().getAsString(pp);
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
|
||||
needsRefinement = false;
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateSpecialization:
|
||||
{
|
||||
typeNameHerarchy = getDeclNameHierarchy(type->getAs<clang::TagType>()->getDecl());
|
||||
needsRefinement = false;
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateTypeParm:
|
||||
{
|
||||
clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmType>(qualType)->getDecl();
|
||||
std::string typeName = getDeclName(templateTypeParmDecl);
|
||||
|
||||
clang::ASTContext& astContext = templateTypeParmDecl->getASTContext();
|
||||
llvm::ArrayRef<clang::ast_type_traits::DynTypedNode> parents = astContext.getParents<clang::Decl>(*(clang::dyn_cast<clang::Decl>(templateTypeParmDecl)));
|
||||
if (parents.size() > 0) // usually this list contains just one parent node.
|
||||
{
|
||||
const clang::Decl* parentNode = parents[0].get<clang::Decl>(); // use the fist parent node.
|
||||
if (clang::isa<clang::NamedDecl>(parentNode))
|
||||
{
|
||||
const clang::NamedDecl* parentNamedDecl = clang::dyn_cast<clang::NamedDecl>(parentNode);
|
||||
typeNameHerarchy = getDeclNameHierarchy(parentNamedDecl);
|
||||
}
|
||||
}
|
||||
if (typeNameHerarchy.size() == 0)
|
||||
{
|
||||
LOG_ERROR("Unable to resolve type name hierarchy for template parameter \"" + typeName + "\"");
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeNameHerarchy.back() += "::" + typeName;
|
||||
}
|
||||
needsRefinement = false;
|
||||
break;
|
||||
}
|
||||
case clang::Type::SubstTemplateTypeParm:
|
||||
{
|
||||
const clang::SubstTemplateTypeParmType* substType = type->getAs<clang::SubstTemplateTypeParmType>();
|
||||
qualType = substType->getReplacementType();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG_ERROR(std::string("Unhandled kind of type encountered: ") + type->getTypeClassName());
|
||||
clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
|
||||
pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A"
|
||||
pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool"
|
||||
std::string typeName = qualType.getUnqualifiedType().getAsString(pp);
|
||||
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
|
||||
needsRefinement = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::shared_ptr<DataType> dataType = typeToDataType(qualType.getTypePtr());
|
||||
if (qualType.isConstQualified())
|
||||
{
|
||||
qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
dataType->addQualifier(DataType::QUALIFIER_CONST);
|
||||
}
|
||||
return DataType(typeNameHerarchy, qualifierList, modifierStack);
|
||||
return dataType;
|
||||
}
|
||||
|
||||
std::shared_ptr<DataType> typeToDataType(const clang::Type* type)
|
||||
{
|
||||
std::shared_ptr<DataType> dataType;
|
||||
|
||||
switch (type->getTypeClass())
|
||||
{
|
||||
case clang::Type::Paren:
|
||||
{
|
||||
dataType = qualTypeToDataType(type->getAs<clang::ParenType>()->getInnerType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Typedef:
|
||||
{
|
||||
dataType = std::make_shared<NamedDataType>(getDeclNameHierarchy(type->getAs<clang::TypedefType>()->getDecl()));
|
||||
break;
|
||||
}
|
||||
case clang::Type::Pointer:
|
||||
{
|
||||
std::shared_ptr<DataType> innerType = qualTypeToDataType(type->getPointeeType());
|
||||
dataType = std::make_shared<PointerModifiedDataType>(innerType);
|
||||
break;
|
||||
}
|
||||
case clang::Type::ConstantArray:
|
||||
case clang::Type::VariableArray:
|
||||
case clang::Type::DependentSizedArray:
|
||||
case clang::Type::IncompleteArray:
|
||||
{
|
||||
std::shared_ptr<DataType> innerType = qualTypeToDataType(clang::dyn_cast<clang::ArrayType>(type)->getElementType());
|
||||
dataType = std::make_shared<ArrayModifiedDataType>(innerType);
|
||||
break;
|
||||
}
|
||||
case clang::Type::LValueReference:
|
||||
case clang::Type::RValueReference:
|
||||
{
|
||||
std::shared_ptr<DataType> innerType = qualTypeToDataType(type->getPointeeType());
|
||||
dataType = std::make_shared<ReferenceModifiedDataType>(innerType);
|
||||
break;
|
||||
}
|
||||
case clang::Type::Elaborated:
|
||||
{
|
||||
dataType = qualTypeToDataType(clang::dyn_cast<clang::ElaboratedType>(type)->getNamedType());
|
||||
break;
|
||||
}
|
||||
case clang::Type::Enum:
|
||||
case clang::Type::Record:
|
||||
{
|
||||
dataType = std::make_shared<NamedDataType>(getDeclNameHierarchy(type->getAs<clang::TagType>()->getDecl()));
|
||||
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::SmallString<64> Buf;
|
||||
llvm::raw_svector_ostream StrOS(Buf);
|
||||
clang::QualType::print(type, clang::Qualifiers(), StrOS, pp, clang::Twine());
|
||||
std::string typeName = StrOS.str();
|
||||
|
||||
std::vector<std::string> typeNameHerarchy;
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateSpecialization:
|
||||
{
|
||||
std::vector<std::string> typeNameHerarchy;
|
||||
|
||||
const clang::TagType* tagType = type->getAs<clang::TagType>(); // remove this case when NameHierarchy is split into namepart and parameter part
|
||||
if (tagType)
|
||||
{
|
||||
typeNameHerarchy = getDeclNameHierarchy(tagType->getDecl());
|
||||
}
|
||||
else // specialization depends on template template parameter type
|
||||
{
|
||||
const clang::TemplateSpecializationType* templateSpecializationType = type->getAs<clang::TemplateSpecializationType>();
|
||||
typeNameHerarchy = getDeclNameHierarchy(templateSpecializationType->getTemplateName().getAsTemplateDecl());
|
||||
|
||||
if (typeNameHerarchy.size() > 0)
|
||||
{
|
||||
std::string templateArgumentPart = "<";
|
||||
for (int i = 0; i < templateSpecializationType->getNumArgs(); i++)
|
||||
{
|
||||
templateArgumentPart += getTemplateArgumentName(templateSpecializationType->getArg(i));
|
||||
if (i < templateSpecializationType->getNumArgs() - 1)
|
||||
templateArgumentPart += ", ";
|
||||
}
|
||||
templateArgumentPart += ">";
|
||||
|
||||
std::string& declName = typeNameHerarchy.back();
|
||||
declName = declName.substr(0, declName.rfind("<")); // remove template parameters
|
||||
declName += templateArgumentPart; // add template arguments
|
||||
}
|
||||
}
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
case clang::Type::TemplateTypeParm:
|
||||
{
|
||||
clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmType>(type)->getDecl();
|
||||
|
||||
std::string typeName = getDeclName(templateTypeParmDecl);
|
||||
std::vector<std::string> typeNameHerarchy = getContextNameHierarchyOfTemplateParameter(templateTypeParmDecl);
|
||||
|
||||
if (typeNameHerarchy.size() == 0)
|
||||
{
|
||||
LOG_ERROR("Unable to resolve type name hierarchy for template parameter \"" + typeName + "\"");
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeNameHerarchy.back() += "::" + typeName;
|
||||
}
|
||||
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);
|
||||
clang::NestedNameSpecifier* nns = dependentNameType->getQualifier();
|
||||
clang::NestedNameSpecifier::SpecifierKind nnsKind = nns->getKind();
|
||||
std::vector<std::string> typeNameHerarchy;
|
||||
switch (nnsKind)
|
||||
{
|
||||
case clang::NestedNameSpecifier::Identifier:
|
||||
typeNameHerarchy.push_back(nns->getAsIdentifier()->getName());
|
||||
LOG_ERROR("Unable to resolve name of nested name specifier of kind: Identifier"); // this one is not tested yet. tell malte if you get this log error.
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Namespace:
|
||||
typeNameHerarchy = getDeclNameHierarchy(nns->getAsNamespace());
|
||||
break;
|
||||
case clang::NestedNameSpecifier::NamespaceAlias:
|
||||
typeNameHerarchy = getDeclNameHierarchy(nns->getAsNamespaceAlias());
|
||||
break;
|
||||
case clang::NestedNameSpecifier::TypeSpec:
|
||||
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
typeNameHerarchy = typeToDataType(nns->getAsType())->getTypeNameHierarchy();
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Global:
|
||||
// no context name hierarchy needed.
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Super:
|
||||
typeNameHerarchy = getDeclNameHierarchy(nns->getAsRecordDecl());
|
||||
break;
|
||||
}
|
||||
|
||||
typeNameHerarchy.push_back(dependentNameType->getIdentifier()->getName().str());
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG_ERROR(std::string("Unhandled kind of type encountered: ") + type->getTypeClassName());
|
||||
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();
|
||||
|
||||
std::vector<std::string> typeNameHerarchy;
|
||||
typeNameHerarchy.push_back(typeName);
|
||||
|
||||
dataType = std::make_shared<NamedDataType>(typeNameHerarchy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
||||
std::vector<std::string> getDeclNameHierarchy(const clang::Decl* declaration)
|
||||
@@ -181,7 +222,8 @@ namespace utility
|
||||
}
|
||||
contextNameHierarchy = getContextNameHierarchy(declaration->getDeclContext());
|
||||
if (clang::isa<clang::NonTypeTemplateParmDecl>(declaration) ||
|
||||
clang::isa<clang::TemplateTypeParmDecl>(declaration)) // TODO: Handle templatetemplate stuff
|
||||
clang::isa<clang::TemplateTypeParmDecl>(declaration) ||
|
||||
clang::isa<clang::TemplateTemplateParmDecl>(declaration))
|
||||
{
|
||||
contextNameHierarchy.back() += "::" + declName;
|
||||
}
|
||||
@@ -214,9 +256,24 @@ namespace utility
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
std::vector<std::string> getContextNameHierarchyOfTemplateParameter(const clang::NamedDecl* templateParmDecl)
|
||||
{
|
||||
std::vector<std::string> contextNameHierarchy;
|
||||
|
||||
const clang::Decl* parentNode = getAstParentDecl(templateParmDecl);
|
||||
if (parentNode && clang::isa<clang::NamedDecl>(parentNode))
|
||||
{
|
||||
const clang::NamedDecl* parentNamedDecl = clang::dyn_cast<clang::NamedDecl>(parentNode);
|
||||
contextNameHierarchy = getDeclNameHierarchy(parentNamedDecl);
|
||||
}
|
||||
|
||||
return contextNameHierarchy;
|
||||
}
|
||||
|
||||
std::string getDeclName(const clang::NamedDecl* declaration)
|
||||
{
|
||||
std::string declName = declaration->getNameAsString();
|
||||
clang::Decl::Kind kind = declaration->getKind();
|
||||
if (clang::isa<clang::CXXRecordDecl>(declaration))
|
||||
{
|
||||
clang::ClassTemplateDecl* templateClassDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(declaration)->getDescribedClassTemplate();
|
||||
@@ -234,10 +291,10 @@ namespace utility
|
||||
|
||||
std::string specializedParameterNamePart = "<";
|
||||
int templateArgumentCount = partialSpecializationDecl->getTemplateArgs().size();
|
||||
const clang::ASTTemplateArgumentListInfo* templateArgumentListInfo = partialSpecializationDecl->getTemplateArgsAsWritten();
|
||||
const clang::TemplateArgumentList& templateArgumentList = partialSpecializationDecl->getTemplateArgs();
|
||||
for (int i = 0; i < templateArgumentCount; i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentListInfo->getTemplateArgs()[i].getArgument();
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList.get(i);
|
||||
if (templateArgument.isDependent()) // TODO: fix case when arg depends on template parameter of outer template class.
|
||||
{
|
||||
specializedParameterNamePart += getTemplateParameterString(parameterList->getParam(currentParameterIndex));
|
||||
@@ -279,18 +336,14 @@ namespace utility
|
||||
for (size_t i = 0; i < templateArgumentList->size(); i++)
|
||||
{
|
||||
const clang::TemplateArgument& templateArgument = templateArgumentList->get(i);
|
||||
specializedParameterNamePart += templateArgumentToDataType(templateArgument).getFullTypeName();
|
||||
specializedParameterNamePart += templateArgumentToDataType(templateArgument)->getFullTypeName();
|
||||
specializedParameterNamePart += (i < templateArgumentList->size() - 1) ? ", " : "";
|
||||
}
|
||||
specializedParameterNamePart += ">";
|
||||
declName += specializedParameterNamePart;
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::TemplateTemplateParmDecl>(declaration))
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration))
|
||||
else if (clang::isa<clang::TemplateDecl>(declaration)) // also triggers on TemplateTemplateParmDecl
|
||||
{
|
||||
std::string templateParameterNamePart = "<";
|
||||
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
|
||||
@@ -328,7 +381,7 @@ namespace utility
|
||||
return specializationParentNameHierarchy;
|
||||
}
|
||||
|
||||
DataType templateArgumentToDataType(const clang::TemplateArgument& argument) // remove this! this is stupid! agurment is not always a datatype.
|
||||
std::shared_ptr<DataType> templateArgumentToDataType(const clang::TemplateArgument& argument) // remove this! this is stupid! agurment is not always a datatype.
|
||||
{
|
||||
const clang::TemplateArgument::ArgKind kind = argument.getKind();
|
||||
switch (kind)
|
||||
@@ -348,12 +401,15 @@ namespace utility
|
||||
case clang::TemplateArgument::Template:
|
||||
{
|
||||
clang::TemplateName templateName = argument.getAsTemplate();
|
||||
clang::TemplateName::NameKind::Template;
|
||||
switch (templateName.getKind())
|
||||
{
|
||||
case clang::TemplateName::Template:
|
||||
return DataType(getDeclNameHierarchy(templateName.getAsTemplateDecl()));
|
||||
return std::make_shared<NamedDataType>(getDeclNameHierarchy(templateName.getAsTemplateDecl()));
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Type of template argument not handled: Template");
|
||||
}
|
||||
LOG_ERROR("Type of template argument not handled: Template");
|
||||
}
|
||||
break;
|
||||
case clang::TemplateArgument::TemplateExpansion:
|
||||
@@ -368,40 +424,24 @@ namespace utility
|
||||
LOG_ERROR("Type of template argument not handled." + argument.getKind());
|
||||
break;
|
||||
}
|
||||
return DataType(std::vector<std::string>());
|
||||
return std::make_shared<NamedDataType>(std::vector<std::string>());
|
||||
}
|
||||
|
||||
std::string getTemplateParameterString(const clang::NamedDecl* parameter)
|
||||
{
|
||||
std::string templateParameterString = "";
|
||||
|
||||
clang::Decl::Kind templateParameterKind = parameter->getKind();
|
||||
switch (templateParameterKind)
|
||||
{
|
||||
case clang::Decl::NonTypeTemplateParm:
|
||||
{
|
||||
const clang::NonTypeTemplateParmDecl* nonTypeTemplateParmDecl = clang::dyn_cast<clang::NonTypeTemplateParmDecl>(parameter);
|
||||
templateParameterString = qualTypeToDataType(nonTypeTemplateParmDecl->getType()).getFullTypeName();
|
||||
}
|
||||
templateParameterString = getTemplateParameterTypeString(clang::dyn_cast<clang::NonTypeTemplateParmDecl>(parameter));
|
||||
break;
|
||||
case clang::Decl::TemplateTypeParm:
|
||||
{
|
||||
const clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmDecl>(parameter);
|
||||
templateParameterString = templateTypeParmDecl->wasDeclaredWithTypename() ? "typename" : "class";
|
||||
}
|
||||
templateParameterString = getTemplateParameterTypeString(clang::dyn_cast<clang::TemplateTypeParmDecl>(parameter));
|
||||
break;
|
||||
case clang::Decl::TemplateTemplateParm:
|
||||
{
|
||||
const clang::TemplateTemplateParmDecl* templateTemplateParmDecl = clang::dyn_cast<clang::TemplateTemplateParmDecl>(parameter);
|
||||
templateParameterString = "template<";
|
||||
clang::TemplateParameterList* parameterList = templateTemplateParmDecl->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
templateParameterString += getTemplateParameterString(parameterList->getParam(i));
|
||||
templateParameterString += (i < parameterList->size() - 1) ? ", " : "";
|
||||
}
|
||||
templateParameterString += ">";
|
||||
templateParameterString += " typename"; // TODO: what if template template parameter is defined with class keyword?
|
||||
}
|
||||
templateParameterString = getTemplateParameterTypeString(clang::dyn_cast<clang::TemplateTemplateParmDecl>(parameter));
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unhandled kind of template parameter.");
|
||||
@@ -415,13 +455,102 @@ namespace utility
|
||||
return templateParameterString;
|
||||
}
|
||||
|
||||
std::string getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter)
|
||||
{
|
||||
std::string templateParameterTypeString = "";
|
||||
|
||||
const clang::QualType parmeterType = parameter->getType();
|
||||
clang::Type::TypeClass parmeterTypeClass = parmeterType->getTypeClass();
|
||||
if (parmeterTypeClass == clang::Type::TemplateTypeParm)
|
||||
{
|
||||
clang::TemplateTypeParmDecl* parmeterTypeDecl = clang::dyn_cast<clang::TemplateTypeParmType>(parmeterType)->getDecl();
|
||||
if (haveAstAncestorRelation(getAstParentDecl(parameter), parmeterTypeDecl))
|
||||
{
|
||||
templateParameterTypeString = getDeclName(parmeterTypeDecl);
|
||||
}
|
||||
}
|
||||
else if (parmeterTypeClass == clang::Type::DependentName)
|
||||
{
|
||||
clang::NestedNameSpecifier* nns = clang::dyn_cast<clang::DependentNameType>(parmeterType)->getQualifier();
|
||||
clang::NamedDecl* typeParent;
|
||||
switch (nns->getKind())
|
||||
{
|
||||
case clang::NestedNameSpecifier::Identifier:
|
||||
{
|
||||
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"
|
||||
templateParameterTypeString = parmeterType.getAsString(pp);
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Namespace:
|
||||
typeParent = nns->getAsNamespace();
|
||||
break;
|
||||
case clang::NestedNameSpecifier::NamespaceAlias:
|
||||
typeParent = nns->getAsNamespaceAlias();
|
||||
break;
|
||||
case clang::NestedNameSpecifier::TypeSpec:
|
||||
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
{
|
||||
const clang::Type* ssswd = nns->getAsType();
|
||||
clang::Type::TypeClass szz = ssswd->getTypeClass();
|
||||
switch (ssswd->getTypeClass())
|
||||
{
|
||||
case clang::Type::TemplateTypeParm:
|
||||
typeParent = clang::dyn_cast<clang::TemplateTypeParmType>(ssswd)->getDecl();
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("aahhh");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Global:
|
||||
typeParent = nullptr;
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Super:
|
||||
typeParent = nns->getAsRecordDecl();
|
||||
break;
|
||||
}
|
||||
if (typeParent && haveAstAncestorRelation(getAstParentDecl(parameter), typeParent))
|
||||
{
|
||||
templateParameterTypeString = getDeclName(typeParent);
|
||||
templateParameterTypeString += "::" + clang::dyn_cast<clang::DependentNameType>(parmeterType)->getIdentifier()->getName().str();
|
||||
}
|
||||
}
|
||||
|
||||
if (templateParameterTypeString.empty()) // this is the default case
|
||||
{
|
||||
templateParameterTypeString = qualTypeToDataType(parmeterType)->getFullTypeName();
|
||||
}
|
||||
return templateParameterTypeString;
|
||||
}
|
||||
|
||||
std::string getTemplateParameterTypeString(const clang::TemplateTypeParmDecl* parameter)
|
||||
{
|
||||
return (parameter->wasDeclaredWithTypename() ? "typename" : "class");
|
||||
}
|
||||
|
||||
std::string getTemplateParameterTypeString(const clang::TemplateTemplateParmDecl* parameter)
|
||||
{
|
||||
std::string templateParameterTypeString = "template<";
|
||||
clang::TemplateParameterList* parameterList = parameter->getTemplateParameters();
|
||||
for (size_t i = 0; i < parameterList->size(); i++)
|
||||
{
|
||||
templateParameterTypeString += getTemplateParameterString(parameterList->getParam(i));
|
||||
templateParameterTypeString += (i < parameterList->size() - 1) ? ", " : "";
|
||||
}
|
||||
templateParameterTypeString += ">";
|
||||
templateParameterTypeString += " typename"; // TODO: what if template template parameter is defined with class keyword?
|
||||
return templateParameterTypeString;
|
||||
}
|
||||
|
||||
std::string getTemplateArgumentName(const clang::TemplateArgument& argument)
|
||||
{
|
||||
const clang::TemplateArgument::ArgKind kind = argument.getKind();
|
||||
switch (kind)
|
||||
{
|
||||
case clang::TemplateArgument::Type:
|
||||
return utility::qualTypeToDataType(argument.getAsType()).getFullTypeName();
|
||||
return utility::qualTypeToDataType(argument.getAsType())->getFullTypeName();
|
||||
case clang::TemplateArgument::Integral:
|
||||
case clang::TemplateArgument::Null:
|
||||
case clang::TemplateArgument::Declaration:
|
||||
@@ -448,4 +577,33 @@ namespace utility
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
bool haveAstAncestorRelation(const clang::Decl* parent, const clang::Decl* child)
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
while (child)
|
||||
{
|
||||
if (parent == child)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
child = getAstParentDecl(child);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const clang::Decl* getAstParentDecl(const clang::Decl* decl)
|
||||
{
|
||||
clang::ASTContext& astContext = decl->getASTContext();
|
||||
llvm::ArrayRef<clang::ast_type_traits::DynTypedNode> parents = astContext.getParents<clang::Decl>(*(decl));
|
||||
if (parents.size() > 0) // usually this list contains just one parent node.
|
||||
{
|
||||
return parents[0].get<clang::Decl>(); // use the fist parent node.
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,15 +13,23 @@ class DataType;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
DataType qualTypeToDataType(clang::QualType qualType);
|
||||
std::shared_ptr<DataType> qualTypeToDataType(clang::QualType qualType);
|
||||
std::shared_ptr<DataType> typeToDataType(const clang::Type* type);
|
||||
|
||||
std::vector<std::string> getDeclNameHierarchy(const clang::Decl* declaration);
|
||||
std::vector<std::string> getContextNameHierarchy(const clang::DeclContext* declaration);
|
||||
std::vector<std::string> getContextNameHierarchyOfTemplateParameter(const clang::NamedDecl* templateParmDecl);
|
||||
std::string getDeclName(const clang::NamedDecl* declaration);
|
||||
std::vector<std::string> getTemplateSpecializationParentNameHierarchy(clang::ClassTemplateSpecializationDecl* declaration);
|
||||
DataType templateArgumentToDataType(const clang::TemplateArgument& argument);
|
||||
std::shared_ptr<DataType> templateArgumentToDataType(const clang::TemplateArgument& argument);
|
||||
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);
|
||||
|
||||
bool haveAstAncestorRelation(const clang::Decl* parent, const clang::Decl* child);
|
||||
const clang::Decl* getAstParentDecl(const clang::Decl* decl);
|
||||
}
|
||||
|
||||
#endif // UTILITY_CLANG_H
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#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(" []");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#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
|
||||
@@ -1,25 +1,7 @@
|
||||
#include "data/type/DataType.h"
|
||||
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
DataType::DataType(const std::vector<std::string>& typeNameHierarchy)
|
||||
: m_typeNameHierarchy(typeNameHierarchy)
|
||||
{
|
||||
}
|
||||
|
||||
DataType::DataType(const std::vector<std::string>& typeNameHierarchy, const DataTypeQualifierList& qualifierList)
|
||||
: m_typeNameHierarchy(typeNameHierarchy)
|
||||
, m_qualifierList(qualifierList)
|
||||
{
|
||||
}
|
||||
|
||||
DataType::DataType(
|
||||
const std::vector<std::string>& typeNameHierarchy, const DataTypeQualifierList& qualifierList,
|
||||
const DataTypeModifierStack& modifierStack
|
||||
)
|
||||
: m_typeNameHierarchy(typeNameHierarchy)
|
||||
, m_qualifierList(qualifierList)
|
||||
, m_modifierStack(modifierStack)
|
||||
DataType::DataType()
|
||||
: m_qualifiers(QUALIFIER_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,27 +9,25 @@ DataType::~DataType()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeQualifierList DataType::getQualifierList() const
|
||||
void DataType::addQualifier(QualifierType qualifier)
|
||||
{
|
||||
return m_qualifierList;
|
||||
m_qualifiers = m_qualifiers | qualifier;
|
||||
}
|
||||
|
||||
DataTypeModifierStack DataType::getModifierStack() const
|
||||
void DataType::removeQualifier(QualifierType qualifier)
|
||||
{
|
||||
return m_modifierStack;
|
||||
m_qualifiers = m_qualifiers & ~qualifier;
|
||||
}
|
||||
|
||||
std::string DataType::getFullTypeName() const
|
||||
bool DataType::hasQualifier(QualifierType qualifier) const
|
||||
{
|
||||
return m_modifierStack.applyTo(m_qualifierList.applyTo(getRawTypeName()));
|
||||
return (m_qualifiers & qualifier) > 0;
|
||||
}
|
||||
|
||||
std::string DataType::getRawTypeName() const
|
||||
void DataType::applyQualifieres(std::string& typeName) const
|
||||
{
|
||||
return utility::join(m_typeNameHierarchy, "::");
|
||||
}
|
||||
|
||||
const std::vector<std::string>& DataType::getTypeNameHierarchy() const
|
||||
{
|
||||
return m_typeNameHierarchy;
|
||||
}
|
||||
if (hasQualifier(QUALIFIER_CONST))
|
||||
{
|
||||
typeName += " const";
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
#ifndef DATA_TYPE_H
|
||||
#define DATA_TYPE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
#include <vector>
|
||||
|
||||
class DataType
|
||||
{
|
||||
public:
|
||||
DataType(const std::vector<std::string>& typeNameHierarchy);
|
||||
DataType(const std::vector<std::string>& typeNameHierarchy, const DataTypeQualifierList& qualifierList);
|
||||
DataType(
|
||||
const std::vector<std::string>& typeNameHierarchy, const DataTypeQualifierList& qualifierList,
|
||||
const DataTypeModifierStack& modifierStack
|
||||
);
|
||||
~DataType();
|
||||
enum QualifierType
|
||||
{
|
||||
QUALIFIER_NONE = 0,
|
||||
QUALIFIER_CONST = 1
|
||||
};
|
||||
|
||||
DataTypeQualifierList getQualifierList() const;
|
||||
DataTypeModifierStack getModifierStack() const;
|
||||
DataType();
|
||||
virtual ~DataType();
|
||||
|
||||
std::string getFullTypeName() const;
|
||||
std::string getRawTypeName() const;
|
||||
const std::vector<std::string>& getTypeNameHierarchy() const;
|
||||
virtual std::string getFullTypeName() const = 0;
|
||||
virtual std::string getRawTypeName() const = 0;
|
||||
virtual const std::vector<std::string>& getTypeNameHierarchy() const = 0;
|
||||
|
||||
void addQualifier(QualifierType qualifier);
|
||||
void removeQualifier(QualifierType qualifier);
|
||||
bool hasQualifier(QualifierType qualifier) const;
|
||||
|
||||
protected:
|
||||
void applyQualifieres(std::string& typeName) const;
|
||||
|
||||
private:
|
||||
const std::vector<std::string> m_typeNameHierarchy;
|
||||
const DataTypeQualifierList m_qualifierList;
|
||||
const DataTypeModifierStack m_modifierStack;
|
||||
char m_qualifiers;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_H
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
|
||||
DataTypeModifierStack::DataTypeModifierStack()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeModifierStack::DataTypeModifierStack(const DataTypeModifierStack& o)
|
||||
{
|
||||
for (std::shared_ptr<DataTypeModifier> modifier: o.m_modifiers)
|
||||
{
|
||||
m_modifiers.push_back(modifier->copy());
|
||||
}
|
||||
}
|
||||
|
||||
DataTypeModifierStack& DataTypeModifierStack::operator=(const DataTypeModifierStack &o)
|
||||
{
|
||||
if (this != &o)
|
||||
{
|
||||
m_modifiers.clear();
|
||||
for (std::shared_ptr<DataTypeModifier> modifier: o.m_modifiers)
|
||||
{
|
||||
m_modifiers.push_back(modifier->copy());
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
DataTypeModifierStack::~DataTypeModifierStack()
|
||||
{
|
||||
}
|
||||
|
||||
void DataTypeModifierStack::push(std::shared_ptr<DataTypeModifier> modifier)
|
||||
{
|
||||
m_modifiers.push_back(modifier);
|
||||
}
|
||||
|
||||
std::string DataTypeModifierStack::applyTo(const std::string& typeName) const
|
||||
{
|
||||
typedef std::vector<std::shared_ptr<DataTypeModifier>>::const_reverse_iterator StackIterator;
|
||||
std::string modifiedTypeName = typeName;
|
||||
for (StackIterator it = m_modifiers.rbegin(); it != m_modifiers.rend(); it++)
|
||||
{
|
||||
(*it)->applyTo(modifiedTypeName);
|
||||
}
|
||||
return modifiedTypeName;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef DATA_TYPE_MODIFIER_STACK_H
|
||||
#define DATA_TYPE_MODIFIER_STACK_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "data/type/modifier/DataTypeModifier.h"
|
||||
|
||||
class DataTypeModifierStack
|
||||
{
|
||||
public:
|
||||
DataTypeModifierStack();
|
||||
DataTypeModifierStack(const DataTypeModifierStack& o);
|
||||
DataTypeModifierStack& operator=(const DataTypeModifierStack &o);
|
||||
~DataTypeModifierStack();
|
||||
|
||||
|
||||
void push(std::shared_ptr<DataTypeModifier> modifier);
|
||||
|
||||
std::string applyTo(const std::string& typeName) const;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<DataTypeModifier>> m_modifiers;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_MODIFIER_STACK_H
|
||||
@@ -1,35 +0,0 @@
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
|
||||
DataTypeQualifierList::DataTypeQualifierList()
|
||||
: m_qualifiers(QUALIFIER_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeQualifierList::~DataTypeQualifierList()
|
||||
{
|
||||
}
|
||||
|
||||
void DataTypeQualifierList::addQualifier(QualifierType qualifier)
|
||||
{
|
||||
m_qualifiers = m_qualifiers | qualifier;
|
||||
}
|
||||
|
||||
void DataTypeQualifierList::removeQualifier(QualifierType qualifier)
|
||||
{
|
||||
m_qualifiers = m_qualifiers & ~qualifier;
|
||||
}
|
||||
|
||||
bool DataTypeQualifierList::hasQualifier(QualifierType qualifier) const
|
||||
{
|
||||
return (m_qualifiers & qualifier) > 0;
|
||||
}
|
||||
|
||||
std::string DataTypeQualifierList::applyTo(const std::string& typeName) const
|
||||
{
|
||||
std::string qualifiedTypeName = typeName;
|
||||
if (hasQualifier(QUALIFIER_CONST))
|
||||
{
|
||||
qualifiedTypeName += " const";
|
||||
}
|
||||
return qualifiedTypeName;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#ifndef DATA_TYPE_QUALIFIER_H
|
||||
#define DATA_TYPE_QUALIFIER_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class DataTypeQualifierList
|
||||
{
|
||||
public:
|
||||
enum QualifierType
|
||||
{
|
||||
QUALIFIER_NONE = 0,
|
||||
QUALIFIER_CONST = 1
|
||||
};
|
||||
|
||||
DataTypeQualifierList();
|
||||
~DataTypeQualifierList();
|
||||
|
||||
void addQualifier(QualifierType qualifier);
|
||||
void removeQualifier(QualifierType qualifier);
|
||||
bool hasQualifier(QualifierType qualifier) const;
|
||||
|
||||
std::string applyTo(const std::string& typeName) const;
|
||||
|
||||
private:
|
||||
char m_qualifiers;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_H
|
||||
@@ -0,0 +1,28 @@
|
||||
#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 std::vector<std::string>& ModifiedDataType::getTypeNameHierarchy() const
|
||||
{
|
||||
return m_dataType->getTypeNameHierarchy();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#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 std::vector<std::string>& getTypeNameHierarchy() const;
|
||||
|
||||
protected:
|
||||
virtual void applyModifier(std::string& typeName) const = 0;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<DataType> m_dataType;
|
||||
};
|
||||
|
||||
#endif // MODIFIED_DATA_TYPE_H
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "data/type/NamedDataType.h"
|
||||
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
NamedDataType::NamedDataType(const std::vector<std::string>& 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 utility::join(m_nameHierarchy, "::");
|
||||
}
|
||||
|
||||
const std::vector<std::string>& NamedDataType::getTypeNameHierarchy() const
|
||||
{
|
||||
return m_nameHierarchy;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef NAMED_DATA_TYPE_H
|
||||
#define NAMED_DATA_TYPE_H
|
||||
|
||||
#include "DataType.h"
|
||||
|
||||
class NamedDataType: public DataType
|
||||
{
|
||||
public:
|
||||
NamedDataType(const std::vector<std::string>& nameHierarchy);
|
||||
virtual ~NamedDataType();
|
||||
|
||||
virtual std::string getFullTypeName() const;
|
||||
virtual std::string getRawTypeName() const;
|
||||
virtual const std::vector<std::string>& getTypeNameHierarchy() const;
|
||||
|
||||
private:
|
||||
const std::vector<std::string> m_nameHierarchy;
|
||||
};
|
||||
|
||||
#endif // NAMED_DATA_TYPE_H
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#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(" *");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#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
|
||||
@@ -0,0 +1,15 @@
|
||||
#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(" &");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#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
|
||||
@@ -1,37 +0,0 @@
|
||||
#include "data/type/modifier/DataTypeModifier.h"
|
||||
|
||||
DataTypeModifier::DataTypeModifier()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeModifier::~DataTypeModifier()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<DataTypeModifier> DataTypeModifier::copy() const
|
||||
{
|
||||
std::shared_ptr<DataTypeModifier> copy = doCopy();
|
||||
copy->m_qualifierList = m_qualifierList;
|
||||
return copy;
|
||||
}
|
||||
|
||||
void DataTypeModifier::applyTo(std::string& typeName) const
|
||||
{
|
||||
doApplyTo(typeName);
|
||||
typeName = m_qualifierList.applyTo(typeName);
|
||||
}
|
||||
|
||||
void DataTypeModifier::addQualifier(DataTypeQualifierList::QualifierType qualifier)
|
||||
{
|
||||
m_qualifierList.addQualifier(qualifier);
|
||||
}
|
||||
|
||||
void DataTypeModifier::removeQualifier(DataTypeQualifierList::QualifierType qualifier)
|
||||
{
|
||||
m_qualifierList.removeQualifier(qualifier);
|
||||
}
|
||||
|
||||
bool DataTypeModifier::hasQualifier(DataTypeQualifierList::QualifierType qualifier) const
|
||||
{
|
||||
return m_qualifierList.hasQualifier(qualifier);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#ifndef DATA_TYPE_MODIFIER_H
|
||||
#define DATA_TYPE_MODIFIER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
|
||||
class DataTypeModifier
|
||||
{
|
||||
public:
|
||||
DataTypeModifier();
|
||||
virtual ~DataTypeModifier();
|
||||
|
||||
std::shared_ptr<DataTypeModifier> copy() const;
|
||||
|
||||
void applyTo(std::string& typeName) const;
|
||||
|
||||
void addQualifier(DataTypeQualifierList::QualifierType qualifier);
|
||||
void removeQualifier(DataTypeQualifierList::QualifierType qualifier);
|
||||
bool hasQualifier(DataTypeQualifierList::QualifierType qualifier) const;
|
||||
|
||||
private:
|
||||
virtual std::shared_ptr<DataTypeModifier> doCopy() const = 0;
|
||||
virtual void doApplyTo(std::string& typeName) const = 0;
|
||||
|
||||
DataTypeQualifierList m_qualifierList;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_MODIFIER_H
|
||||
@@ -1,19 +0,0 @@
|
||||
#include "data/type/modifier/DataTypeModifierArray.h"
|
||||
|
||||
DataTypeModifierArray::DataTypeModifierArray()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeModifierArray::~DataTypeModifierArray()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<DataTypeModifier> DataTypeModifierArray::doCopy() const
|
||||
{
|
||||
return std::make_shared<DataTypeModifierArray>();
|
||||
}
|
||||
|
||||
void DataTypeModifierArray::doApplyTo(std::string& typeName) const
|
||||
{
|
||||
typeName.append(" []");
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef DATA_TYPE_MODIFIER_ARRAY_H
|
||||
#define DATA_TYPE_MODIFIER_ARRAY_H
|
||||
|
||||
#include "data/type/modifier/DataTypeModifier.h"
|
||||
|
||||
class DataTypeModifierArray: public DataTypeModifier
|
||||
{
|
||||
public:
|
||||
DataTypeModifierArray();
|
||||
virtual ~DataTypeModifierArray();
|
||||
|
||||
private:
|
||||
virtual std::shared_ptr<DataTypeModifier> doCopy() const;
|
||||
virtual void doApplyTo(std::string& typeName) const;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_MODIFIER_ARRAY_H
|
||||
@@ -1,19 +0,0 @@
|
||||
#include "data/type/modifier/DataTypeModifierPointer.h"
|
||||
|
||||
DataTypeModifierPointer::DataTypeModifierPointer()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeModifierPointer::~DataTypeModifierPointer()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<DataTypeModifier> DataTypeModifierPointer::doCopy() const
|
||||
{
|
||||
return std::make_shared<DataTypeModifierPointer>();
|
||||
}
|
||||
|
||||
void DataTypeModifierPointer::doApplyTo(std::string& typeName) const
|
||||
{
|
||||
typeName.append(" *");
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef DATA_TYPE_MODIFIER_POINTER_H
|
||||
#define DATA_TYPE_MODIFIER_POINTER_H
|
||||
|
||||
#include "data/type/modifier/DataTypeModifier.h"
|
||||
|
||||
class DataTypeModifierPointer: public DataTypeModifier
|
||||
{
|
||||
public:
|
||||
DataTypeModifierPointer();
|
||||
virtual ~DataTypeModifierPointer();
|
||||
|
||||
private:
|
||||
virtual std::shared_ptr<DataTypeModifier> doCopy() const;
|
||||
virtual void doApplyTo(std::string& typeName) const;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_MODIFIER_POINTER_H
|
||||
@@ -1,19 +0,0 @@
|
||||
#include "data/type/modifier/DataTypeModifierReference.h"
|
||||
|
||||
DataTypeModifierReference::DataTypeModifierReference()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeModifierReference::~DataTypeModifierReference()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<DataTypeModifier> DataTypeModifierReference::doCopy() const
|
||||
{
|
||||
return std::make_shared<DataTypeModifierReference>();
|
||||
}
|
||||
|
||||
void DataTypeModifierReference::doApplyTo(std::string& typeName) const
|
||||
{
|
||||
typeName.append(" &");
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef DATA_TYPE_MODIFIER_REFERENCE_H
|
||||
#define DATA_TYPE_MODIFIER_REFERENCE_H
|
||||
|
||||
#include "data/type/modifier/DataTypeModifier.h"
|
||||
|
||||
class DataTypeModifierReference: public DataTypeModifier
|
||||
{
|
||||
public:
|
||||
DataTypeModifierReference();
|
||||
virtual ~DataTypeModifierReference();
|
||||
|
||||
private:
|
||||
virtual std::shared_ptr<DataTypeModifier> doCopy() const;
|
||||
virtual void doApplyTo(std::string& typeName) const;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_MODIFIER_REFERENCE_H
|
||||
+120
-10
@@ -1311,9 +1311,119 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A<typename T>::T <1:20 1:20>");
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes[1], "B<template<typename> typename T>::T <4:36 4:36>");
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes[1], "B<template<typename> typename T>::T<typename> <4:36 4:36>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_usage_of_template_template_parameter_of_template_class_specialized_with_concrete_type()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"template <typename T>\n"
|
||||
"class A\n"
|
||||
"{};\n"
|
||||
"template <template<typename> class T>\n"
|
||||
"class B\n"
|
||||
"{\n"
|
||||
" void foo(T<int> parameter)\n"
|
||||
" {}\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->typeUses.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->typeUses[0], "void <7:2 7:5>");
|
||||
TS_ASSERT_EQUALS(client->typeUses[1], "B<template<typename> typename T>::T<int> <7:11 7:16>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_usage_of_template_template_parameter_of_template_class_specialized_with_template_type()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"template <typename T>\n"
|
||||
"class A\n"
|
||||
"{};\n"
|
||||
"template <template<typename> class T>\n"
|
||||
"class B\n"
|
||||
"{\n"
|
||||
" template <typename U> \n"
|
||||
" void foo(T<U> parameter)\n"
|
||||
" {}\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->typeUses.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->typeUses[0], "void <8:2 8:5>");
|
||||
TS_ASSERT_EQUALS(client->typeUses[1], "B<template<typename> typename T>::T<B<template<typename> typename T>::foo<typename U>::U> <8:11 8:14>");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void test_cxx_parser_finds_usage_of_template_template_parameter_of_template_class_specialized_with_template_type00000000000666666666666()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"template <typename T>\n"
|
||||
"class A\n"
|
||||
"{\n"
|
||||
"public:"
|
||||
" typedef T type;\n"
|
||||
"};\n"
|
||||
"template <typename U>\n"
|
||||
"class B\n"
|
||||
"{\n"
|
||||
"public:"
|
||||
" typedef typename A<U>::type type;\n"
|
||||
"};\n"
|
||||
|
||||
"B<int>::type f = 0;\n"
|
||||
|
||||
);
|
||||
TS_ASSERT_EQUALS(client->typedefs.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->typedefs[0], "public A<typename T>::T -> A<typename T>::type <4:19 4:22>");
|
||||
TS_ASSERT_EQUALS(client->typedefs[1], "public A<B<typename U>::U>::type -> B<typename U>::type <9:37 9:40>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_usage_of_template_template_parameter_of_template_class_specialized_with_template_type00ss000666666666666()
|
||||
{
|
||||
int zz1 = 0;
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"template <typename T, T test>\n"
|
||||
"class A\n"
|
||||
"{\n"
|
||||
"};\n"
|
||||
|
||||
);
|
||||
int zz2 = 0;
|
||||
TS_ASSERT_EQUALS(client->classes.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->classes[0], "A<typename T, T test> <2:1 <2:7 2:7> 4:1>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_usage_of_template_template_parameter_of_template_class_specialized_with_template_type00sstt000666666666666()
|
||||
{
|
||||
int zz1 = 0;
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"template <typename T, typename T::type test>\n"
|
||||
"class A\n"
|
||||
"{\n"
|
||||
"};\n"
|
||||
|
||||
);
|
||||
int zz2 = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void test_cxx_parser_finds_type_template_parameters_of_template_class_with_multiple_parameters()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
@@ -1725,8 +1835,8 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<p, P & q>->P <8:9 8:9>");
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[1], "A<p, P & q>->P <8:12 8:12>");
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&p, P & q>->P <8:9 8:9>"); // why reference here?
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[1], "A<&p, P & q>->P <8:12 8:12>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_non_type_nullptr_template_argument_of_explicit_partial_template_specialization()
|
||||
@@ -1764,7 +1874,7 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "B<A, template<typename> typename U>->A<typename T> <8:9 8:9>");
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[1], "B<A, template<typename> typename U>->B<A, template<typename> typename U>::U <8:12 8:12>");
|
||||
TS_ASSERT_EQUALS(client->templateArgumentTypes[1], "B<A, template<typename> typename U>->B<A, template<typename> typename U>::U<typename> <8:12 8:12>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_correct_name_of_explicit_template_specialization()
|
||||
@@ -2033,7 +2143,7 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "A<typename T> -> B<template<typename> typename T>::T <4:40 4:40>");
|
||||
TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "A<typename T> -> B<template<typename> typename T>::T<typename> <4:40 4:40>");
|
||||
}
|
||||
|
||||
|
||||
@@ -2142,7 +2252,7 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A<typename T>::T <1:20 1:20>");
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes[1], "test<template<typename> typename T>::T <4:36 4:36>");
|
||||
TS_ASSERT_EQUALS(client->templateParameterTypes[1], "test<template<typename> typename T>::T<typename> <4:36 4:36>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_implicit_specialization_of_template_function()
|
||||
@@ -2297,7 +2407,7 @@ private:
|
||||
AccessType access
|
||||
)
|
||||
{
|
||||
std::string str = addAccessPrefix(underlyingType.dataType.getFullTypeName() + " -> " + utility::join(nameHierarchy, "::"), access);
|
||||
std::string str = addAccessPrefix(underlyingType.dataType->getFullTypeName() + " -> " + utility::join(nameHierarchy, "::"), access);
|
||||
typedefs.push_back(addLocationSuffix(str, location));
|
||||
return 0;
|
||||
}
|
||||
@@ -2471,7 +2581,7 @@ private:
|
||||
const ParseTypeUsage& defaultArgumentType, const std::vector<std::string>& templateArgumentTypeNameHierarchy)
|
||||
{
|
||||
templateDefaultArgumentTypes.push_back(
|
||||
addLocationSuffix(utility::join(defaultArgumentType.dataType.getTypeNameHierarchy(), "::") + " -> " + utility::join(templateArgumentTypeNameHierarchy, "::"), defaultArgumentType.location)
|
||||
addLocationSuffix(utility::join(defaultArgumentType.dataType->getTypeNameHierarchy(), "::") + " -> " + utility::join(templateArgumentTypeNameHierarchy, "::"), defaultArgumentType.location)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
@@ -2560,7 +2670,7 @@ private:
|
||||
{
|
||||
if (use.location.isValid())
|
||||
{
|
||||
typeUses.push_back(addLocationSuffix(use.dataType.getFullTypeName(), use.location));
|
||||
typeUses.push_back(addLocationSuffix(use.dataType->getFullTypeName(), use.location));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2569,7 +2679,7 @@ private:
|
||||
if (use.location.isValid())
|
||||
{
|
||||
typeUses.push_back(
|
||||
addLocationSuffix(functionStr(func) + " -> " + use.dataType.getFullTypeName(), use.location)
|
||||
addLocationSuffix(functionStr(func) + " -> " + use.dataType->getFullTypeName(), use.location)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,87 +3,69 @@
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/modifier/DataTypeModifierArray.h"
|
||||
#include "data/type/modifier/DataTypeModifierPointer.h"
|
||||
#include "data/type/modifier/DataTypeModifierReference.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()
|
||||
{
|
||||
DataType dataType(utility::splitToVector("int", "::"));
|
||||
TS_ASSERT_EQUALS("int", dataType.getFullTypeName());
|
||||
}
|
||||
|
||||
void test_datatype_created_with_name_and_empty_qualifiers_has_no_qualifiers_or_modifiers()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList);
|
||||
NamedDataType dataType(utility::splitToVector("int", "::"));
|
||||
TS_ASSERT_EQUALS("int", dataType.getFullTypeName());
|
||||
}
|
||||
|
||||
void test_datatype_created_with_name_and_const_qualifier_has_no_modifiers()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList);
|
||||
NamedDataType dataType(utility::splitToVector("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(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
TS_ASSERT_EQUALS("int", dataType.getFullTypeName());
|
||||
}
|
||||
//void __test_datatype_created_with_name_and_empty_modifierstack_has_no_modifiers()
|
||||
//{
|
||||
// DataTypeQualifierList qualifierList;
|
||||
// DataTypeModifierStack modifierStack;
|
||||
// DataType dataType(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
// TS_ASSERT_EQUALS("int", dataType.getFullTypeName());
|
||||
//}
|
||||
|
||||
void test_datatype_created_with_name_and_array_modifier_has_array_modifier()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
modifierStack.push(std::make_shared<DataTypeModifierArray>());
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
TS_ASSERT_EQUALS("int []", dataType.getFullTypeName());
|
||||
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(utility::splitToVector("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()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
modifierStack.push(std::make_shared<DataTypeModifierPointer>());
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
TS_ASSERT_EQUALS("int *", dataType.getFullTypeName());
|
||||
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(utility::splitToVector("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()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
modifierStack.push(std::make_shared<DataTypeModifierReference>());
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
TS_ASSERT_EQUALS("int &", dataType.getFullTypeName());
|
||||
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(utility::splitToVector("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()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierPointer>();
|
||||
modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
modifierStack.push(modifier);
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
TS_ASSERT_EQUALS("int * const", dataType.getFullTypeName());
|
||||
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(utility::splitToVector("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()
|
||||
{
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
modifierStack.push(std::make_shared<DataTypeModifierPointer>());
|
||||
modifierStack.push(std::make_shared<DataTypeModifierPointer>());
|
||||
DataType dataType(utility::splitToVector("int", "::"), qualifierList, modifierStack);
|
||||
TS_ASSERT_EQUALS("int * *", dataType.getFullTypeName());
|
||||
std::shared_ptr<DataType> dataType1 = std::make_shared<NamedDataType>(utility::splitToVector("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());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -802,7 +802,7 @@ private:
|
||||
|
||||
ParseTypeUsage typeUsage(const std::string& typeName) const
|
||||
{
|
||||
return ParseTypeUsage(validLocation(), DataType(utility::splitToVector(typeName, "::")));
|
||||
return ParseTypeUsage(validLocation(), std::make_shared<NamedDataType>(utility::splitToVector(typeName, "::")));
|
||||
}
|
||||
|
||||
std::vector<ParseTypeUsage> parameters(const std::string& param) const
|
||||
|
||||
Reference in New Issue
Block a user