Files
Sourcetrail/src/lib/data/parser/cxx/utilityCxx.cpp
T
Eberhard Graether c54c405dd1 logic: fixed warnings, tests and bugs
* fixed clang warnings
* fixed cxxparser tests
* added missing checks for valid location in ASTVisitor callbacks for templates
* removed warning when statusbar view is removed
* made font of activated classes bold
* fixed search box not responding to autocompletion tab or enter press
* fixed search box not updated when active token changes
2014-12-02 00:55:57 +01:00

186 lines
5.9 KiB
C++

#include "data/parser/cxx/utilityCxx.h"
#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/DeclTemplate.h>
#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 "utility/utilityString.h"
#include "utility/logging/logging.h"
namespace utility
{
DataType qualTypeToDataType(clang::QualType qualType)
{
std::vector<std::string> typeNameHerarchy;
DataTypeQualifierList qualifierList;
DataTypeModifierStack modifierStack;
while (true)
{
const clang::Type* type = qualType.getTypePtr();
if (type->getAs<clang::TypedefType>())
{
typeNameHerarchy.push_back(utility::substrAfter(qualType.getAsString(), ' '));
break;
}
else if (type->isPointerType())
{
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierPointer>();
if (qualType.isConstQualified())
{
modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
}
modifierStack.push(modifier);
qualType = type->getPointeeType();
}
else if (type->isArrayType())
{
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();
}
else if (type->isReferenceType())
{
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierReference>();
// references can not be const qualified
modifierStack.push(modifier);
qualType = type->getPointeeType();
}
else
{
const clang::Type* type = qualType.getUnqualifiedType().getTypePtr();
if (clang::isa<clang::TagType>(type))
{
typeNameHerarchy = getDeclNameHierarchy(clang::dyn_cast<clang::TagType>(type)->getDecl());
}
else
{
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);
if (type->isTemplateTypeParmType())
{
clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast<clang::TemplateTypeParmType>(qualType.getUnqualifiedType())->getDecl();
if (templateTypeParmDecl)
{
typeNameHerarchy = getContextNameHierarchy(templateTypeParmDecl->getDeclContext());
typeNameHerarchy.back() += "::" + typeName;
}
}
else
{
typeNameHerarchy.push_back(typeName);
}
}
break;
}
}
if (qualType.isConstQualified())
{
qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
}
return DataType(typeNameHerarchy, qualifierList, modifierStack);
}
std::vector<std::string> getDeclNameHierarchy(clang::Decl* declaration)
{
std::string declName = "";
if (clang::isa<clang::NamedDecl>(declaration))
{
declName = getDeclName(clang::dyn_cast<clang::NamedDecl>(declaration));
}
else
{
LOG_ERROR("unhandled declaration type");
}
std::vector<std::string> contextNameHierarchy = getContextNameHierarchy(declaration->getDeclContext());
contextNameHierarchy.push_back(declName);
return contextNameHierarchy;
}
std::vector<std::string> getContextNameHierarchy(clang::DeclContext* declContext)
{
std::vector<std::string> contextNameHierarchy;
clang::DeclContext* parentContext = declContext->getParent();
if (parentContext)
{
contextNameHierarchy = getContextNameHierarchy(parentContext);
}
if (clang::isa<clang::NamedDecl>(declContext))
{
std::string declName = getDeclName(clang::dyn_cast<clang::NamedDecl>(declContext));
if (declName != "")
{
contextNameHierarchy.push_back(declName);
}
}
return contextNameHierarchy;
}
std::string getDeclName(clang::NamedDecl* declaration)
{
std::string declName = declaration->getNameAsString();
if (clang::isa<clang::CXXRecordDecl>(declaration))
{
clang::ClassTemplateDecl* templateClassDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(declaration)->getDescribedClassTemplate();
if (templateClassDeclaration)
{
declName = getDeclName(templateClassDeclaration);
}
else if (clang::isa<clang::ClassTemplateSpecializationDecl>(declaration))
{
std::string specializedParameterNamePart = "<";
const clang::TemplateArgumentList& templateArgumentList = clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(declaration)->getTemplateArgs();
for (size_t i = 0; i < templateArgumentList.size(); i++)
{
DataType datatype = utility::qualTypeToDataType(templateArgumentList.get(i).getAsType());
specializedParameterNamePart += datatype.getFullTypeName();
specializedParameterNamePart += (i < templateArgumentList.size() - 1) ? ", " : "";
}
specializedParameterNamePart += ">";
declName += specializedParameterNamePart;
}
}
else if (clang::isa<clang::TemplateDecl>(declaration))
{
std::string templateParameterNamePart = "<";
clang::TemplateParameterList* parameterList = clang::dyn_cast<clang::TemplateDecl>(declaration)->getTemplateParameters();
for (size_t i = 0; i < parameterList->size(); i++)
{
clang::NamedDecl* namedDecl = parameterList->getParam(i);
templateParameterNamePart += namedDecl->getNameAsString();
templateParameterNamePart += (i < parameterList->size() - 1) ? ", " : "";
}
templateParameterNamePart += ">";
declName += templateParameterNamePart;
}
else if (clang::isa<clang::NamespaceDecl>(declaration) && clang::dyn_cast<clang::NamespaceDecl>(declaration)->isAnonymousNamespace())
{
declName = "(anonymous namespace)";
}
return declName;
}
}