Skip to content

Commit

Permalink
feat: TArg stores types
Browse files Browse the repository at this point in the history
  • Loading branch information
sdkrystian committed Jul 12, 2023
1 parent 2cc093d commit c0fd3fc
Show file tree
Hide file tree
Showing 39 changed files with 714 additions and 369 deletions.
2 changes: 1 addition & 1 deletion include/mrdox/Metadata/Specialization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct SpecializationInfo
: IsInfo<InfoKind::Specialization>
{
/** The template arguments the parent template is specialized for */
std::vector<TArg> Args;
std::vector<std::unique_ptr<TArg>> Args;

/** ID of the template to which the arguments pertain */
SymbolID Primary = SymbolID::zero;
Expand Down
155 changes: 125 additions & 30 deletions include/mrdox/Metadata/Template.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,123 @@
#include <mrdox/Platform.hpp>
#include <mrdox/ADT/Optional.hpp>
#include <mrdox/Metadata/Type.hpp>
#include <mrdox/Support/TypeTraits.hpp>
#include <optional>
#include <string>
#include <vector>

namespace clang {
namespace mrdox {

enum class TArgKind : int
{
// type arguments
Type = 1, // for bitstream
// non-type arguments, i.e. expressions
NonType,
// template template arguments, i.e. template names
Template
};

MRDOX_DECL dom::String toString(TArgKind kind) noexcept;

struct TArg
{
/** The kind of template argument this is. */
TArgKind Kind;

/** Whether this template argument is a parameter expansion. */
bool IsPackExpansion = false;

constexpr virtual ~TArg() = default;

constexpr bool isType() const noexcept { return Kind == TArgKind::Type; }
constexpr bool isNonType() const noexcept { return Kind == TArgKind::NonType; }
constexpr bool isTemplate() const noexcept { return Kind == TArgKind::Template; }

protected:
constexpr
TArg(
TArgKind kind) noexcept
: Kind(kind)
{
}
};

template<TArgKind K>
struct IsTArg : TArg
{
static constexpr TArgKind kind_id = K;

static constexpr bool isType() noexcept { return K == TArgKind::Type; }
static constexpr bool isNonType() noexcept { return K == TArgKind::NonType; }
static constexpr bool isTemplate() noexcept { return K == TArgKind::Template; }

protected:
constexpr
IsTArg() noexcept
: TArg(K)
{
}
};

struct TypeTArg
: IsTArg<TArgKind::Type>
{
/** Template argument type. */
std::unique_ptr<TypeInfo> Type;
};

struct NonTypeTArg
: IsTArg<TArgKind::NonType>
{
/** Template argument expression. */
ExprInfo Value;
};

struct TemplateTArg
: IsTArg<TArgKind::Template>
{
/** SymbolID of the referenced template. */
SymbolID Template;

/** Name of the referenced template. */
std::string Name;
};

template<
typename TArgTy,
typename F,
typename... Args>
requires std::derived_from<TArgTy, TArg>
constexpr
decltype(auto)
visit(
TArgTy& A,
F&& f,
Args&&... args)
{
switch(A.Kind)
{
case TArgKind::Type:
return f(static_cast<add_cv_from_t<
TArgTy, TypeTArg>&>(A),
std::forward<Args>(args)...);
case TArgKind::NonType:
return f(static_cast<add_cv_from_t<
TArgTy, NonTypeTArg>&>(A),
std::forward<Args>(args)...);
case TArgKind::Template:
return f(static_cast<add_cv_from_t<
TArgTy, TemplateTArg>&>(A),
std::forward<Args>(args)...);
default:
MRDOX_UNREACHABLE();
}
}

// ----------------------------------------------------------------

enum class TParamKind : int
{
// template type parameter, e.g. "typename T" or "class T"
Expand Down Expand Up @@ -103,48 +213,31 @@ struct TemplateTParam
Optional<std::string> Default;
};

template<typename F, typename... Args>
template<
typename TParamTy,
typename F,
typename... Args>
requires std::derived_from<TParamTy, TParam>
constexpr
decltype(auto)
visit(
TParam& P,
TParamTy& P,
F&& f,
Args&&... args)
{
switch(P.Kind)
{
case TParamKind::Type:
return f(static_cast<TypeTParam&>(P),
return f(static_cast<add_cv_from_t<
TParamTy, TypeTParam>&>(P),
std::forward<Args>(args)...);
case TParamKind::NonType:
return f(static_cast<NonTypeTParam&>(P),
return f(static_cast<add_cv_from_t<
TParamTy, NonTypeTParam>&>(P),
std::forward<Args>(args)...);
case TParamKind::Template:
return f(static_cast<TemplateTParam&>(P),
std::forward<Args>(args)...);
default:
MRDOX_UNREACHABLE();
}
}

template<typename F, typename... Args>
constexpr
decltype(auto)
visit(
const TParam& P,
F&& f,
Args&&... args)
{
switch(P.Kind)
{
case TParamKind::Type:
return f(static_cast<const TypeTParam&>(P),
std::forward<Args>(args)...);
case TParamKind::NonType:
return f(static_cast<const NonTypeTParam&>(P),
std::forward<Args>(args)...);
case TParamKind::Template:
return f(static_cast<const TemplateTParam&>(P),
return f(static_cast<add_cv_from_t<
TParamTy, TemplateTParam>&>(P),
std::forward<Args>(args)...);
default:
MRDOX_UNREACHABLE();
Expand All @@ -153,6 +246,7 @@ visit(

// ----------------------------------------------------------------

#if 0
struct TArg
{
std::string Value;
Expand All @@ -162,6 +256,7 @@ struct TArg
MRDOX_DECL
TArg(std::string&& value);
};
#endif

// ----------------------------------------------------------------

Expand Down Expand Up @@ -191,7 +286,7 @@ struct TemplateInfo
once in Args outside of a non-deduced context
*/
std::vector<std::unique_ptr<TParam>> Params;
std::vector<TArg> Args;
std::vector<std::unique_ptr<TArg>> Args;

/** Primary template ID for partial and explicit specializations.
*/
Expand Down
2 changes: 1 addition & 1 deletion include/mrdox/Metadata/Type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ struct SpecializationTypeInfo
std::unique_ptr<TypeInfo> ParentType;
std::string Name;
SymbolID id = SymbolID::zero;
std::vector<TArg> TemplateArgs;
std::vector<std::unique_ptr<TArg>> TemplateArgs;
};

struct LValueReferenceTypeInfo
Expand Down
3 changes: 3 additions & 0 deletions include/mrdox/MetadataFwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ struct ConstantExprInfo;

struct TemplateInfo;
struct TArg;
struct TypeTArg;
struct NonTypeTArg;
struct TemplateTArg;
struct TParam;
struct TypeTParam;
struct NonTypeTParam;
Expand Down
21 changes: 17 additions & 4 deletions src/lib/-XML/CXXTags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ writeType(
if constexpr(T::isSpecialization())
{
for(const auto& targ : t.TemplateArgs)
writeTemplateArg(targ, tags);
writeTemplateArg(*targ, tags);
}

if constexpr(requires { t.PointeeType; })
Expand Down Expand Up @@ -365,9 +365,22 @@ inline void writeTemplateParam(const TParam& I, XMLTags& tags)

inline void writeTemplateArg(const TArg& I, XMLTags& tags)
{
tags.write(targTagName, {}, {
{ "value", I.Value }
});
visit(I, [&]<typename T>(const T& A)
{
Attributes attrs = {
{"class", toString(T::kind_id)}
};

if constexpr(T::isType())
attrs.push({"type", toString(*A.Type)});
else if constexpr(T::isNonType())
attrs.push({"value", A.Value.Written});
else if constexpr(T::isTemplate())
attrs.push({A.Template});

tags.write(targTagName, {},
std::move(attrs));
});
}

/** Return the xml tag name for the Info.
Expand Down
6 changes: 3 additions & 3 deletions src/lib/-XML/XMLWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ openTemplate(
for(const auto& tparam : I->Params)
writeTemplateParam(*tparam, tags_);
for(const auto& targ : I->Args)
writeTemplateArg(targ, tags_);
writeTemplateArg(*targ, tags_);
}

void
Expand All @@ -516,8 +516,8 @@ writeSpecialization(
{"primary", toString(I.Primary) }
});

for(const TArg& targ : I.Args)
writeTemplateArg(targ, tags_);
for(const auto& targ : I.Args)
writeTemplateArg(*targ, tags_);

corpus_.traverse(I, *this);

Expand Down
Loading

0 comments on commit c0fd3fc

Please sign in to comment.