TypeGraph: Create Mutator and RecursiveMutator base classes

This commit is contained in:
Alastair Robertson 2023-11-02 06:08:08 -07:00 committed by Alastair Robertson
parent 81ae075a68
commit 30678b1dad
3 changed files with 142 additions and 18 deletions

View File

@ -23,6 +23,9 @@ namespace oi::detail::type_graph {
void OI_TYPE_NAME::accept(Visitor& v) { \
v.visit(*this); \
} \
Type& OI_TYPE_NAME::accept(Mutator& m) { \
return m.visit(*this); \
} \
void OI_TYPE_NAME::accept(ConstVisitor& v) const { \
v.visit(*this); \
}

View File

@ -67,9 +67,11 @@ enum class Qualifier {
using QualifierSet = EnumBitset<Qualifier, static_cast<size_t>(Qualifier::Max)>;
class Visitor;
class Mutator;
class ConstVisitor;
#define DECLARE_ACCEPT \
void accept(Visitor& v) override; \
#define DECLARE_ACCEPT \
void accept(Visitor& v) override; \
Type& accept(Mutator& m) override; \
void accept(ConstVisitor& v) const override;
// TODO delete copy and move ctors
@ -83,6 +85,7 @@ class Type {
public:
virtual ~Type() = default;
virtual void accept(Visitor& v) = 0;
virtual Type& accept(Mutator& m) = 0;
virtual void accept(ConstVisitor& v) const = 0;
virtual const std::string& name() const = 0;
@ -123,6 +126,10 @@ class Member {
return type_;
}
void setType(Type& type) {
type_ = type;
}
private:
std::reference_wrapper<Type> type_;
@ -152,6 +159,10 @@ struct Parent {
return type_;
}
void setType(Type& type) {
type_ = type;
}
// uint64_t offset() const {
// return offset_;
// }
@ -178,6 +189,10 @@ struct TemplateParam {
return type_;
}
void setType(Type& type) {
type_ = type;
}
private:
std::reference_wrapper<Type> type_;
@ -426,6 +441,10 @@ class Container : public Type {
return id_;
}
void setAlign(uint64_t alignment) {
align_ = alignment;
}
std::vector<TemplateParam> templateParams;
const ContainerInfo& containerInfo_;
@ -433,6 +452,7 @@ class Container : public Type {
std::string name_;
std::string inputName_;
size_t size_;
uint64_t align_ = 0;
NodeId id_ = -1;
};
@ -506,7 +526,7 @@ class Array : public Type {
}
void regenerateName() {
name_ = std::string{"OIArray<"} + elementType_.name() + ", " +
name_ = std::string{"OIArray<"} + elementType_.get().name() + ", " +
std::to_string(len_) + ">";
}
@ -519,11 +539,11 @@ class Array : public Type {
}
virtual size_t size() const override {
return len_ * elementType_.size();
return len_ * elementType_.get().size();
}
virtual uint64_t align() const override {
return elementType_.align();
return elementType_.get().align();
}
virtual NodeId id() const override {
@ -534,12 +554,16 @@ class Array : public Type {
return elementType_;
}
void setElementType(Type& type) {
elementType_ = type;
}
size_t len() const {
return len_;
}
private:
Type& elementType_;
std::reference_wrapper<Type> elementType_;
std::string inputName_;
size_t len_;
NodeId id_ = -1;
@ -623,11 +647,11 @@ class Typedef : public Type {
}
virtual size_t size() const override {
return underlyingType_.size();
return underlyingType_.get().size();
}
virtual uint64_t align() const override {
return underlyingType_.align();
return underlyingType_.get().align();
}
virtual NodeId id() const override {
@ -638,10 +662,14 @@ class Typedef : public Type {
return underlyingType_;
}
void setUnderlyingType(Type& type) {
underlyingType_ = type;
}
private:
std::string name_;
std::string inputName_;
Type& underlyingType_;
std::reference_wrapper<Type> underlyingType_;
NodeId id_ = -1;
};
@ -661,7 +689,7 @@ class Pointer : public Type {
}
void regenerateName() {
name_ = pointeeType_.name() + "*";
name_ = pointeeType_.get().name() + "*";
}
virtual std::string_view inputName() const override {
@ -688,8 +716,12 @@ class Pointer : public Type {
return pointeeType_;
}
void setPointeeType(Type& type) {
pointeeType_ = type;
}
private:
Type& pointeeType_;
std::reference_wrapper<Type> pointeeType_;
std::string inputName_;
NodeId id_ = -1;
@ -772,7 +804,7 @@ class DummyAllocator : public Type {
}
void regenerateName() {
name_ = std::string{"DummyAllocator<"} + type_.name() + ", " +
name_ = std::string{"DummyAllocator<"} + type_.get().name() + ", " +
std::to_string(size_) + ", " + std::to_string(align_) + ", " +
std::to_string(id_) + ">";
}
@ -797,8 +829,12 @@ class DummyAllocator : public Type {
return type_;
}
void setAllocType(Type& type) {
type_ = type;
}
private:
Type& type_;
std::reference_wrapper<Type> type_;
size_t size_;
uint64_t align_;
NodeId id_ = -1;
@ -828,19 +864,19 @@ class CaptureKeys : public Type {
}
virtual std::string_view inputName() const override {
return container_.inputName();
return container_.get().inputName();
}
void regenerateName() {
name_ = "OICaptureKeys<" + container_.name() + ">";
name_ = "OICaptureKeys<" + container_.get().name() + ">";
}
virtual size_t size() const override {
return container_.size();
return container_.get().size();
}
virtual uint64_t align() const override {
return container_.align();
return container_.get().align();
}
virtual NodeId id() const override {
@ -855,8 +891,12 @@ class CaptureKeys : public Type {
return container_;
}
void setContainer(Container& container) {
container_ = container;
}
private:
Container& container_;
std::reference_wrapper<Container> container_;
const ContainerInfo& containerInfo_;
std::string name_;
};

View File

@ -32,6 +32,7 @@ namespace oi::detail::type_graph {
* Visitor
*
* Abstract visitor base class.
* A visitor simply walks over nodes in a type graph.
*/
class Visitor {
public:
@ -42,6 +43,21 @@ class Visitor {
#undef X
};
/*
* Mutator
*
* Abstract mutator base class.
* A mutator replaces nodes in a type graph with the node returned by visit().
*/
class Mutator {
public:
virtual ~Mutator() = default;
#define X(OI_TYPE_NAME) virtual Type& visit(OI_TYPE_NAME&) = 0;
OI_TYPE_LIST
#undef X
};
/*
* LazyVisitor
*
@ -115,6 +131,71 @@ class RecursiveVisitor : public Visitor {
}
};
/*
* RecursiveMutator
*
* Mutator base class which recurses into types by default.
*/
class RecursiveMutator : public Mutator {
public:
virtual ~RecursiveMutator() = default;
virtual Type& mutate(Type&) = 0;
virtual Type& visit(Incomplete& i) {
return i;
}
virtual Type& visit(Class& c) {
for (auto& param : c.templateParams) {
param.setType(mutate(param.type()));
}
for (auto& parent : c.parents) {
parent.setType(mutate(parent.type()));
}
for (auto& mem : c.members) {
mem.setType(mutate(mem.type()));
}
for (auto& child : c.children) {
child = dynamic_cast<Class&>(mutate(child));
}
return c;
}
virtual Type& visit(Container& c) {
for (auto& param : c.templateParams) {
param.setType(mutate(param.type()));
}
return c;
}
virtual Type& visit(Primitive& p) {
return p;
}
virtual Type& visit(Enum& e) {
return e;
}
virtual Type& visit(Array& a) {
a.setElementType(mutate(a.elementType()));
return a;
}
virtual Type& visit(Typedef& td) {
td.setUnderlyingType(mutate(td.underlyingType()));
return td;
}
virtual Type& visit(Pointer& p) {
p.setPointeeType(mutate(p.pointeeType()));
return p;
}
virtual Type& visit(Dummy& d) {
return d;
}
virtual Type& visit(DummyAllocator& d) {
d.setAllocType(mutate(d.allocType()));
return d;
}
virtual Type& visit(CaptureKeys& c) {
auto& newContainer = dynamic_cast<Container&>(mutate(c.container()));
c.setContainer(newContainer);
return c;
}
};
/*
* ConstVisitor
*