#ifndef HALIDE_INTROSPECTION_H
#define HALIDE_INTROSPECTION_H
#include <string>
#include <iostream>
#include <stdint.h>
#include "Util.h"
namespace Halide {
namespace Internal {
namespace Introspection {
EXPORT std::string get_variable_name(const void *, const std::string &expected_type);
EXPORT void register_heap_object(const void *obj, size_t size, const void *helper);
EXPORT void deregister_heap_object(const void *obj, size_t size);
template<typename T>
const void *get_introspection_helper() {
static T *introspection_helper = nullptr;
return &introspection_helper;
}
EXPORT std::string get_source_location();
EXPORT void test_compilation_unit(bool (*test)(bool (*)(const void *, const std::string &)),
bool (*test_a)(const void *, const std::string &),
void (*calib)());
}
}
}
#ifndef COMPILING_HALIDE
namespace Halide {
namespace Internal {
static bool check_introspection(const void *var, const std::string &type,
const std::string &correct_name,
const std::string &correct_file, int line) {
std::string correct_loc = correct_file + ":" + std::to_string(line);
std::string loc = Introspection::get_source_location();
std::string name = Introspection::get_variable_name(var, type);
return name == correct_name && loc == correct_loc;
}
}
}
namespace HalideIntrospectionCanary {
static void offset_marker() {
std::cerr << "You should not have called this function\n";
}
struct A {
int an_int;
class B {
int private_member;
public:
float a_float;
A *parent;
B() : private_member(17) {
a_float = private_member * 2.0f;
}
};
B a_b;
A() {
a_b.parent = this;
}
bool test(const std::string &my_name);
};
static bool test_a(const void *a_ptr, const std::string &my_name) {
const A *a = (const A *)a_ptr;
bool success = true;
success &= Halide::Internal::check_introspection(&a->an_int, "int", my_name + ".an_int", __FILE__ , __LINE__);
success &= Halide::Internal::check_introspection(&a->a_b, "HalideIntrospectionCanary::A::B", my_name + ".a_b", __FILE__ , __LINE__);
success &= Halide::Internal::check_introspection(&a->a_b.parent, "HalideIntrospectionCanary::A *", my_name + ".a_b.parent", __FILE__ , __LINE__);
success &= Halide::Internal::check_introspection(&a->a_b.a_float, "float", my_name + ".a_b.a_float", __FILE__ , __LINE__);
success &= Halide::Internal::check_introspection(a->a_b.parent, "HalideIntrospectionCanary::A", my_name, __FILE__ , __LINE__);
return success;
}
static bool test(bool (*f)(const void *, const std::string &)) {
A a1, a2;
return f(&a1, "a1") && f(&a2, "a2");
}
namespace {
struct TestCompilationUnit {
TestCompilationUnit() {
Halide::Internal::Introspection::test_compilation_unit(&test, &test_a, &offset_marker);
}
};
}
static TestCompilationUnit test_object;
}
#endif
#endif