diff --git a/oi/type_graph/NameGen.cpp b/oi/type_graph/NameGen.cpp index c792766..5213b3d 100644 --- a/oi/type_graph/NameGen.cpp +++ b/oi/type_graph/NameGen.cpp @@ -194,6 +194,14 @@ void NameGen::visit(Pointer& p) { p.setInputName(inputName); } +void NameGen::visit(Reference& p) { + RecursiveVisitor::visit(p); + p.regenerateName(); + std::string inputName{p.pointeeType().inputName()}; + inputName += '*'; + p.setInputName(inputName); +} + void NameGen::visit(DummyAllocator& d) { RecursiveVisitor::visit(d); d.regenerateName(); diff --git a/oi/type_graph/NameGen.h b/oi/type_graph/NameGen.h index 7b01aef..e6437d0 100644 --- a/oi/type_graph/NameGen.h +++ b/oi/type_graph/NameGen.h @@ -46,6 +46,7 @@ class NameGen final : public RecursiveVisitor { void visit(Array& a) override; void visit(Typedef& td) override; void visit(Pointer& p) override; + void visit(Reference& p) override; void visit(DummyAllocator& d) override; void visit(CaptureKeys& d) override; diff --git a/oi/type_graph/Printer.cpp b/oi/type_graph/Printer.cpp index e7d70eb..5913977 100644 --- a/oi/type_graph/Printer.cpp +++ b/oi/type_graph/Printer.cpp @@ -147,6 +147,17 @@ void Printer::visit(const Pointer& p) { print(p.pointeeType()); } +void Printer::visit(const Reference& p) { + if (prefix(p)) + return; + + out_ << "Reference"; + if (auto inp = p.inputName(); !inp.empty()) + out_ << " [" << inp << "]"; + out_ << std::endl; + print(p.pointeeType()); +} + void Printer::visit(const Dummy& d) { if (prefix(d)) return; diff --git a/oi/type_graph/Printer.h b/oi/type_graph/Printer.h index a66581e..d7d60f3 100644 --- a/oi/type_graph/Printer.h +++ b/oi/type_graph/Printer.h @@ -40,6 +40,7 @@ class Printer : public ConstVisitor { void visit(const Array& a) override; void visit(const Typedef& td) override; void visit(const Pointer& p) override; + void visit(const Reference& p) override; void visit(const Dummy& d) override; void visit(const DummyAllocator& d) override; void visit(const CaptureKeys& d) override; diff --git a/oi/type_graph/RemoveTopLevelPointer.cpp b/oi/type_graph/RemoveTopLevelPointer.cpp index 9ecaaaa..e1909a7 100644 --- a/oi/type_graph/RemoveTopLevelPointer.cpp +++ b/oi/type_graph/RemoveTopLevelPointer.cpp @@ -42,4 +42,8 @@ void RemoveTopLevelPointer::visit(Pointer& p) { topLevelType_ = &p.pointeeType(); } +void RemoveTopLevelPointer::visit(Reference& p) { + topLevelType_ = &p.pointeeType(); +} + } // namespace oi::detail::type_graph diff --git a/oi/type_graph/RemoveTopLevelPointer.h b/oi/type_graph/RemoveTopLevelPointer.h index 611429f..6b70545 100644 --- a/oi/type_graph/RemoveTopLevelPointer.h +++ b/oi/type_graph/RemoveTopLevelPointer.h @@ -36,6 +36,7 @@ class RemoveTopLevelPointer : public LazyVisitor { void removeTopLevelPointers(std::vector>& types); void visit(Pointer& p) override; + void visit(Reference& p) override; private: Type* topLevelType_ = nullptr; diff --git a/oi/type_graph/Types.h b/oi/type_graph/Types.h index f503886..8aba760 100644 --- a/oi/type_graph/Types.h +++ b/oi/type_graph/Types.h @@ -49,6 +49,7 @@ X(Array) \ X(Typedef) \ X(Pointer) \ + X(Reference) \ X(Dummy) \ X(DummyAllocator) \ X(CaptureKeys) @@ -715,6 +716,61 @@ class Pointer : public Type { std::string name_; }; +class Reference : public Type { + public: + explicit Reference(NodeId id, Type& pointeeType) + : pointeeType_(pointeeType), id_(id) { + regenerateName(); + } + + static inline constexpr bool has_node_id = true; + + DECLARE_ACCEPT + + virtual const std::string& name() const override { + return name_; + } + + void regenerateName() { + name_ = pointeeType_.get().name() + "&"; + } + + virtual std::string_view inputName() const override { + return inputName_; + } + + void setInputName(std::string name) { + inputName_ = std::move(name); + } + + virtual size_t size() const override { + return sizeof(uintptr_t); + } + + virtual uint64_t align() const override { + return size(); + } + + virtual NodeId id() const override { + return id_; + } + + Type& pointeeType() const { + return pointeeType_; + } + + void setPointeeType(Type& type) { + pointeeType_ = type; + } + + private: + std::reference_wrapper pointeeType_; + std::string inputName_; + NodeId id_ = -1; + + std::string name_; +}; + /* * Dummy * diff --git a/oi/type_graph/Visitor.h b/oi/type_graph/Visitor.h index 7e4395e..b2fb7a2 100644 --- a/oi/type_graph/Visitor.h +++ b/oi/type_graph/Visitor.h @@ -121,6 +121,9 @@ class RecursiveVisitor : public Visitor { virtual void visit(Pointer& p) { accept(p.pointeeType()); } + virtual void visit(Reference& r) { + accept(r.pointeeType()); + } virtual void visit(Dummy&) { } virtual void visit(DummyAllocator& d) { @@ -182,6 +185,10 @@ class RecursiveMutator : public Mutator { p.setPointeeType(mutate(p.pointeeType())); return p; } + virtual Type& visit(Reference& p) { + p.setPointeeType(mutate(p.pointeeType())); + return p; + } virtual Type& visit(Dummy& d) { return d; }