selfpatch-slr/pinpoint/stage0/stage0.h

68 lines
1.9 KiB
C++

#pragma once
#include <cstddef>
#include <map>
#include <string>
#include <limits>
#include <safe-tree.h>
#include <safe-gimple.h>
using UID = std::size_t;
constexpr UID UID_INVALID = std::numeric_limits<UID>::max();
class TargetType {
public:
struct Field {
static constexpr std::size_t FLAG_DANGEROUS = 1;
std::size_t offset;
std::size_t size;
std::size_t flags;
};
private:
static constexpr std::size_t FLAG_MAIN_VARIANT = 1;
static constexpr std::size_t FLAG_FIELDS = 2;
UID m_uid;
std::size_t m_flags;
tree m_main_variant;
// Fields are identified by their offsets
std::map<std::size_t, Field> m_fields;
public:
TargetType(const TargetType& other) = default;
TargetType& operator=(const TargetType& other) = default;
TargetType(TargetType&& other) = default;
TargetType& operator=(TargetType&& other) = default;
TargetType(tree t); // Does NOT fetch fields
~TargetType();
bool valid() const;
bool fields() const;
std::string name() const;
const Field* field(std::size_t off, bool exact = true) const;
UID uid() const;
static void add(tree t);
static std::size_t count();
static const TargetType* find(tree t); // O(n)
static const TargetType* find(UID uid); // O(1)
static bool reference(tree ref, UID& target, std::size_t& offset);
private:
friend void on_finish_type(void*, void*);
bool fetch_fields(bool redo = false);
static TargetType* find_mutable(tree t);
};
/* Stage 0 offsetof separators are function calls, such as:
SPSLR_PINPOINT_STAGE0_SEPARATOR(target, member offset) */
tree make_stage0_ast_separator(UID target, std::size_t offset);
gimple* make_stage0_gimple_separator(UID target, std::size_t offset); // lhs is a new temporary variable
bool is_stage0_separator(gimple* stmt, UID& target, std::size_t& offset);
void on_register_attributes(void* plugin_data, void* user_data);
void on_finish_type(void* plugin_data, void* user_data);
void on_preserve_component_ref(void* plugin_data, void* user_data);