mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-12 21:56:54 +00:00
Type Graph: Replace MutationTracker with the more general ResultTracker
MutationTracker could only store Type nodes, while ResultTracker is templated on the result type so can store anything. Template the Visitor base class on the return type of visit() functions. This sets us up for allowing visitors to return different results from their visit() functions in the future. This will be used in a future commit introducing DrgnExporter, where we cache drgn_type* results while walking the type graph.
This commit is contained in:
parent
8193d271a8
commit
8bf7dbae9f
@ -47,7 +47,7 @@ Type& IdentifyContainers::mutate(Type& type) {
|
||||
return *mutated;
|
||||
|
||||
Type& mutated = type.accept(*this);
|
||||
tracker_.set(type, mutated);
|
||||
tracker_.set(type, &mutated);
|
||||
return mutated;
|
||||
}
|
||||
|
||||
@ -60,12 +60,12 @@ Type& IdentifyContainers::visit(Class& c) {
|
||||
auto& container = typeGraph_.makeType<Container>(*containerInfo, c.size());
|
||||
container.templateParams = c.templateParams;
|
||||
|
||||
tracker_.set(c, container);
|
||||
tracker_.set(c, &container);
|
||||
RecursiveMutator::visit(container);
|
||||
return container;
|
||||
}
|
||||
|
||||
tracker_.set(c, c);
|
||||
tracker_.set(c, &c);
|
||||
RecursiveMutator::visit(c);
|
||||
return c;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class IdentifyContainers : public RecursiveMutator {
|
||||
Type& visit(Class& c) override;
|
||||
|
||||
private:
|
||||
MutationTracker tracker_;
|
||||
ResultTracker<Type*> tracker_;
|
||||
TypeGraph& typeGraph_;
|
||||
const std::vector<std::unique_ptr<ContainerInfo>>& containers_;
|
||||
};
|
||||
|
@ -109,23 +109,27 @@ class NodeTrackerHolder {
|
||||
};
|
||||
|
||||
/*
|
||||
* MutationTracker
|
||||
* ResultTracker
|
||||
*
|
||||
* Helper class for mutators. Efficiently tracks visited and replaces nodes.
|
||||
* Efficiently caches the results of visited nodes.
|
||||
*/
|
||||
class MutationTracker {
|
||||
template <typename T>
|
||||
class ResultTracker {
|
||||
public:
|
||||
MutationTracker(size_t size) : visited_(size) {
|
||||
ResultTracker() = default;
|
||||
ResultTracker(size_t size) : visited_(size) {
|
||||
}
|
||||
|
||||
static_assert(std::is_pointer_v<T>);
|
||||
|
||||
/*
|
||||
* get
|
||||
*
|
||||
* Returns a type pointer if the given node has been visited or replaced.
|
||||
* Returns the cached result if the given node has been visited.
|
||||
* Returns nullptr if this node has not yet been seen.
|
||||
*/
|
||||
Type* get(const Type& oldType) {
|
||||
auto id = oldType.id();
|
||||
T get(const Type& type) {
|
||||
auto id = type.id();
|
||||
if (id < 0)
|
||||
return nullptr;
|
||||
if (visited_.size() <= static_cast<size_t>(id))
|
||||
@ -136,19 +140,19 @@ class MutationTracker {
|
||||
/*
|
||||
* set
|
||||
*
|
||||
* Sets newType as the replacement node for oldType.
|
||||
* Caches the result of visiting the given node.
|
||||
*/
|
||||
void set(const Type& oldType, Type& newType) {
|
||||
auto id = oldType.id();
|
||||
void set(const Type& type, T result) {
|
||||
auto id = type.id();
|
||||
if (id < 0)
|
||||
return;
|
||||
if (visited_.size() <= static_cast<size_t>(id))
|
||||
visited_.resize(id + 1);
|
||||
visited_[id] = &newType;
|
||||
visited_[id] = result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Type*> visited_;
|
||||
std::vector<T> visited_;
|
||||
};
|
||||
|
||||
} // namespace oi::detail::type_graph
|
||||
|
@ -20,10 +20,10 @@
|
||||
namespace oi::detail::type_graph {
|
||||
|
||||
#define X(OI_TYPE_NAME) \
|
||||
void OI_TYPE_NAME::accept(Visitor& v) { \
|
||||
void OI_TYPE_NAME::accept(Visitor<void>& v) { \
|
||||
v.visit(*this); \
|
||||
} \
|
||||
Type& OI_TYPE_NAME::accept(Mutator& m) { \
|
||||
Type& OI_TYPE_NAME::accept(Visitor<Type&>& m) { \
|
||||
return m.visit(*this); \
|
||||
} \
|
||||
void OI_TYPE_NAME::accept(ConstVisitor& v) const { \
|
||||
|
@ -66,12 +66,12 @@ enum class Qualifier {
|
||||
};
|
||||
using QualifierSet = EnumBitset<Qualifier, static_cast<size_t>(Qualifier::Max)>;
|
||||
|
||||
template <typename T>
|
||||
class Visitor;
|
||||
class Mutator;
|
||||
class ConstVisitor;
|
||||
#define DECLARE_ACCEPT \
|
||||
void accept(Visitor& v) override; \
|
||||
Type& accept(Mutator& m) override; \
|
||||
#define DECLARE_ACCEPT \
|
||||
void accept(Visitor<void>& v) override; \
|
||||
Type& accept(Visitor<Type&>& m) override; \
|
||||
void accept(ConstVisitor& v) const override;
|
||||
|
||||
// TODO delete copy and move ctors
|
||||
@ -84,8 +84,8 @@ class ConstVisitor;
|
||||
class Type {
|
||||
public:
|
||||
virtual ~Type() = default;
|
||||
virtual void accept(Visitor& v) = 0;
|
||||
virtual Type& accept(Mutator& m) = 0;
|
||||
virtual void accept(Visitor<void>& v) = 0;
|
||||
virtual Type& accept(Visitor<Type&>& m) = 0;
|
||||
virtual void accept(ConstVisitor& v) const = 0;
|
||||
|
||||
virtual const std::string& name() const = 0;
|
||||
|
@ -34,26 +34,12 @@ namespace oi::detail::type_graph {
|
||||
* Abstract visitor base class.
|
||||
* A visitor simply walks over nodes in a type graph.
|
||||
*/
|
||||
template <typename T>
|
||||
class Visitor {
|
||||
public:
|
||||
virtual ~Visitor() = default;
|
||||
|
||||
#define X(OI_TYPE_NAME) virtual void visit(OI_TYPE_NAME&) = 0;
|
||||
OI_TYPE_LIST
|
||||
#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;
|
||||
#define X(OI_TYPE_NAME) virtual T visit(OI_TYPE_NAME&) = 0;
|
||||
OI_TYPE_LIST
|
||||
#undef X
|
||||
};
|
||||
@ -63,7 +49,7 @@ class Mutator {
|
||||
*
|
||||
* Visitor base class which takes no action by default.
|
||||
*/
|
||||
class LazyVisitor : public Visitor {
|
||||
class LazyVisitor : public Visitor<void> {
|
||||
public:
|
||||
virtual ~LazyVisitor() = default;
|
||||
|
||||
@ -79,7 +65,7 @@ class LazyVisitor : public Visitor {
|
||||
*
|
||||
* Visitor base class which recurses into types by default.
|
||||
*/
|
||||
class RecursiveVisitor : public Visitor {
|
||||
class RecursiveVisitor : public Visitor<void> {
|
||||
public:
|
||||
virtual ~RecursiveVisitor() = default;
|
||||
virtual void accept(Type&) = 0;
|
||||
@ -136,7 +122,7 @@ class RecursiveVisitor : public Visitor {
|
||||
*
|
||||
* Mutator base class which recurses into types by default.
|
||||
*/
|
||||
class RecursiveMutator : public Mutator {
|
||||
class RecursiveMutator : public Visitor<Type&> {
|
||||
public:
|
||||
virtual ~RecursiveMutator() = default;
|
||||
virtual Type& mutate(Type&) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user