Skip to content

Commit

Permalink
[v0.0.7] Added more information about TypeStatement (TypeBaseInfo). A…
Browse files Browse the repository at this point in the history
…dded tests.
  • Loading branch information
DronCode committed Apr 8, 2024
1 parent ae14be6 commit 0255e15
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 18 deletions.
29 changes: 29 additions & 0 deletions Cpp/include/RG3/Cpp/TypeBaseInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <RG3/Cpp/DefinitionLocation.h>
#include <RG3/Cpp/CppNamespace.h>
#include <RG3/Cpp/TypeKind.h>

#include <string>


namespace rg3::cpp
{
/**
* Base information about type (what kind, name, pretty name, namespace, where defined)
*/
struct TypeBaseInfo
{
cpp::TypeKind eKind {};
std::string sName {};
std::string sPrettyName {};
cpp::CppNamespace sNameSpace {};
cpp::DefinitionLocation sDefLocation {};

TypeBaseInfo();
TypeBaseInfo(const TypeBaseInfo& copy);
TypeBaseInfo(TypeBaseInfo&& move) noexcept;
TypeBaseInfo& operator=(const TypeBaseInfo& copy);
TypeBaseInfo& operator=(TypeBaseInfo&& move) noexcept;
};
}
8 changes: 8 additions & 0 deletions Cpp/include/RG3/Cpp/TypeStatement.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <RG3/Cpp/TypeReference.h>
#include <RG3/Cpp/DefinitionLocation.h>
#include <RG3/Cpp/TypeBaseInfo.h>

#include <optional>
#include <vector>
Expand All @@ -11,14 +12,21 @@ namespace rg3::cpp
{
struct TypeStatement
{
// Reference
TypeReference sTypeRef {};

// Statement location
std::optional<DefinitionLocation> sDefinitionLocation {};
bool bIsConst { false };
bool bIsPointer { false };
bool bIsPtrConst { false };
bool bIsReference { false };
bool bIsTemplateSpecialization { false };

// Type info
TypeBaseInfo sBaseInfo {};

// Globals
static const TypeStatement g_sVoid; // globally known void type

bool isVoid() const;
Expand Down
55 changes: 55 additions & 0 deletions Cpp/source/TypeBaseInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <RG3/Cpp/TypeBaseInfo.h>


namespace rg3::cpp
{
TypeBaseInfo::TypeBaseInfo() = default;
TypeBaseInfo::TypeBaseInfo(const TypeBaseInfo& copy)
: eKind(copy.eKind)
, sName(copy.sName)
, sPrettyName(copy.sPrettyName)
, sNameSpace(copy.sNameSpace)
, sDefLocation(copy.sDefLocation)
{}

TypeBaseInfo::TypeBaseInfo(TypeBaseInfo&& move) noexcept
: eKind(move.eKind)
, sName(std::move(move.sName))
, sPrettyName(std::move(move.sPrettyName))
, sNameSpace(std::move(move.sNameSpace))
, sDefLocation(std::move(move.sDefLocation))
{
move.eKind = {};
move.sName = {};
move.sPrettyName = {};
move.sNameSpace = {};
move.sDefLocation = {};
}

TypeBaseInfo& TypeBaseInfo::operator=(const TypeBaseInfo& copy)
{
eKind = copy.eKind;
sName = copy.sName;
sPrettyName = copy.sPrettyName;
sNameSpace = copy.sNameSpace;
sDefLocation = copy.sDefLocation;
return *this;
}

TypeBaseInfo& TypeBaseInfo::operator=(TypeBaseInfo&& move) noexcept
{
eKind = move.eKind;
sName = std::move(move.sName);
sPrettyName = std::move(move.sPrettyName);
sNameSpace = std::move(move.sNameSpace);
sDefLocation = std::move(move.sDefLocation);

move.eKind = {};
move.sName = {};
move.sPrettyName = {};
move.sNameSpace = {};
move.sDefLocation = {};

return *this;
}
}
3 changes: 2 additions & 1 deletion Extension/rg3py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@
from .rg3py import CppCompilerIssueKind
from .rg3py import CppCompilerIssue
from .rg3py import CppTypeReference
from .rg3py import ClangRuntime
from .rg3py import ClangRuntime
from .rg3py import TypeBaseInfo
14 changes: 3 additions & 11 deletions LLVM/include/RG3/LLVM/Utils.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
#pragma once

#include <clang/AST/Decl.h>
#include <RG3/Cpp/CppNamespace.h>
#include <RG3/Cpp/DefinitionLocation.h>
#include <RG3/Cpp/TypeClass.h>
#include <clang/AST/Decl.h>
#include <RG3/Cpp/TypeBaseInfo.h>

#include <filesystem>
#include <string>


namespace rg3::llvm
{
struct TypeBaseInfo
{
cpp::TypeKind eKind;
std::string sName;
std::string sPrettyName;
cpp::CppNamespace sNameSpace;
cpp::DefinitionLocation sDefLocation;
};

struct Utils
{
static void getDeclInfo(const clang::Decl* decl, rg3::cpp::CppNamespace& nameSpace);
Expand All @@ -28,7 +20,7 @@ namespace rg3::llvm

static cpp::ClassEntryVisibility getDeclVisibilityLevel(const clang::Decl* decl);

static bool getQualTypeBaseInfo(const clang::QualType& qualType, TypeBaseInfo& baseInfo, const clang::ASTContext& astContext);
static bool getQualTypeBaseInfo(const clang::QualType& qualType, cpp::TypeBaseInfo& baseInfo, const clang::ASTContext& astContext);

static void fillTypeStatementFromQualType(rg3::cpp::TypeStatement& typeStatement, clang::QualType qt, const clang::ASTContext& astContext);

Expand Down
11 changes: 8 additions & 3 deletions LLVM/source/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ namespace rg3::llvm
return cpp::ClassEntryVisibility::CEV_PRIVATE;
}

bool Utils::getQualTypeBaseInfo(const clang::QualType& qualType, TypeBaseInfo& baseInfo, const clang::ASTContext& astContext)
bool Utils::getQualTypeBaseInfo(const clang::QualType& qualType, cpp::TypeBaseInfo& baseInfo, const clang::ASTContext& astContext)
{
if (qualType->isTypedefNameType()) // must be first!
{
Expand Down Expand Up @@ -158,6 +158,7 @@ namespace rg3::llvm
baseInfo.sNameSpace = baseInfo.sNameSpace;
baseInfo.sPrettyName = baseInfo.sNameSpace.isEmpty() ? correctedName : fmt::format("{}::{}", baseInfo.sNameSpace.asString(), correctedName);
baseInfo.sDefLocation = aDefLocation;
baseInfo.eKind = cpp::TypeKind::TK_STRUCT_OR_CLASS;
return true;
}

Expand Down Expand Up @@ -224,33 +225,37 @@ namespace rg3::llvm
const clang::SourceManager& sm = astContext.getSourceManager();

{
TypeBaseInfo typeBaseInfo {};
cpp::TypeBaseInfo typeBaseInfo {};
if (!getQualTypeBaseInfo(qt, typeBaseInfo, astContext))
{
// Use "pure" view
typeStatement.sTypeRef = cpp::TypeReference(qt.getUnqualifiedType().getAsString());
typeStatement.sBaseInfo = {}; // invalid in this case
}
else
{
// Use correct view
typeStatement.sTypeRef = cpp::TypeReference(typeBaseInfo.sPrettyName);
typeStatement.sBaseInfo = typeBaseInfo;
}
}

typeStatement.bIsConst = qt.isConstQualified();

if (qt->isPointerType() || qt->isReferenceType())
{
TypeBaseInfo typeBaseInfo {};
cpp::TypeBaseInfo typeBaseInfo {};
if (!getQualTypeBaseInfo(qt->getPointeeType().getUnqualifiedType(), typeBaseInfo, astContext))
{
// Use "pure" view
typeStatement.sTypeRef = cpp::TypeReference(qt->getPointeeType().getUnqualifiedType().getAsString());
typeStatement.sBaseInfo = {}; // override to invalid
}
else
{
// Use correct view
typeStatement.sTypeRef = cpp::TypeReference(typeBaseInfo.sPrettyName);
typeStatement.sBaseInfo = typeBaseInfo; // override
}

typeStatement.bIsPointer = qt->isPointerType();
Expand Down
1 change: 1 addition & 0 deletions LLVM/source/Visitors/CxxTemplateSpecializationVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ namespace rg3::llvm::visitors

// Override type name & location in sTargetStmt from sCoreStmt
stmt.sTypeRef = sTargetStmt.sTypeRef;
stmt.sBaseInfo = sTargetStmt.sBaseInfo;
stmt.sDefinitionLocation = sTargetStmt.sDefinitionLocation;
stmt.bIsConst = sTargetStmt.bIsConst || stmt.bIsConst;
stmt.bIsPointer = sTargetStmt.bIsPointer || stmt.bIsPointer;
Expand Down
20 changes: 20 additions & 0 deletions PyBind/rg3py.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ class TypeStatement:
@property
def type_ref(self) -> CppTypeReference: ...

@property
def type_info(self) -> TypeBaseInfo: ...

@property
def location(self) -> Optional[Location]: ...

Expand All @@ -193,6 +196,23 @@ class TypeStatement:
def get_name(self) -> str: ...


class TypeBaseInfo:
@property
def kind(self) -> CppTypeKind: ...

@property
def namespace(self) -> CppNamespace: ...

@property
def location(self) -> Location: ...

@property
def name(self) -> str: ...

@property
def pretty_name(self) -> str: ...


class FunctionArgument:
@property
def type_info(self) -> TypeStatement: ...
Expand Down
26 changes: 23 additions & 3 deletions PyBind/source/PyBind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <RG3/Cpp/CppNamespace.h>
#include <RG3/Cpp/TypeClass.h>
#include <RG3/Cpp/TypeEnum.h>
#include <RG3/Cpp/TypeBaseInfo.h>

#include <RG3/PyBind/PyCodeAnalyzerBuilder.h>
#include <RG3/PyBind/PyTypeBase.h>
Expand Down Expand Up @@ -152,6 +153,16 @@ namespace rg3::pybind::wrappers
static const std::string s_Null {};
return boost::python::str(arg.asString(s_Null));
}

static boost::python::str TypeBaseInfo_getName(const rg3::cpp::TypeBaseInfo& sInfo)
{
return boost::python::str(sInfo.sName);
}

static boost::python::str TypeBaseInfo_getPrettyName(const rg3::cpp::TypeBaseInfo& sInfo)
{
return boost::python::str(sInfo.sPrettyName);
}
}


Expand Down Expand Up @@ -250,17 +261,26 @@ BOOST_PYTHON_MODULE(rg3py)
.add_property("value", make_getter(&rg3::cpp::EnumEntry::iValue), "Value of entry")
;

class_<rg3::cpp::TypeBaseInfo>("TypeBaseInfo")
.add_property("kind", make_getter(&rg3::cpp::TypeBaseInfo::eKind), "Kind of type")
.add_property("namespace", make_getter(&rg3::cpp::TypeBaseInfo::sNameSpace), "Namespace where type declared")
.add_property("location", make_getter(&rg3::cpp::TypeBaseInfo::sDefLocation), "Place where type declared")
.add_property("name", &rg3::pybind::wrappers::TypeBaseInfo_getName, "Name of type without namespace")
.add_property("pretty_name", &rg3::pybind::wrappers::TypeBaseInfo_getPrettyName, "Prettified name of type (included namespace and full form of name)")
;

class_<rg3::cpp::TypeStatement>("TypeStatement")
.add_property("type_ref", make_getter(&rg3::cpp::TypeStatement::sTypeRef), "Reference to type info")
.add_property("location", &rg3::pybind::wrappers::TypeStatement_getDefinitionLocation)
.add_property("type_info", make_getter(&rg3::cpp::TypeStatement::sBaseInfo), "Base information about type")
.add_property("location", &rg3::pybind::wrappers::TypeStatement_getDefinitionLocation, "(optional) Where type statement info defined (not a type!)")
.add_property("is_const", make_getter(&rg3::cpp::TypeStatement::bIsConst), "Is declaration constant")
.add_property("is_const_ptr", make_getter(&rg3::cpp::TypeStatement::bIsPtrConst), "Is pointer type with const qualifier (unused when is_ptr is False)")
.add_property("is_ptr", make_getter(&rg3::cpp::TypeStatement::bIsPointer), "Is declaration pointer")
.add_property("is_ref", make_getter(&rg3::cpp::TypeStatement::bIsReference), "Is declaration reference")
.add_property("is_template", make_getter(&rg3::cpp::TypeStatement::bIsTemplateSpecialization), "Is declaration presented via template specialization")
.add_property("is_void", &rg3::cpp::TypeStatement::isVoid)
.add_property("is_void", &rg3::cpp::TypeStatement::isVoid, "Is type C++ void or not")

.def("get_name", &rg3::pybind::wrappers::TypeStatement_getTypeName)
.def("get_name", &rg3::pybind::wrappers::TypeStatement_getTypeName, "Return name of the type")
;

class_<rg3::cpp::FunctionArgument>("FunctionArgument")
Expand Down
Loading

0 comments on commit 0255e15

Please sign in to comment.