diff --git a/.gitignore b/.gitignore index 253e16b..4a2771d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ out/ build/ .cache/ compile_commands.json +clangLog.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 95d680a..7f587bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,8 @@ add_executable(meta set(CLANG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/LLVM/include") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - message(FATAL "${CMAKE_SYSTEM_NAME} is not supported") + set(CLANG_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/LLVM/bin/Linux") + set(CLANG_LIB_LIBRARIES "${CLANG_LIB_DIR}/libclang.so.12") elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows") message(FATAL "${CMAKE_SYSTEM_NAME} is not supported") elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") @@ -31,5 +32,5 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") endif() endif() -target_include_directories(meta PRIVATE ${CLANG_INCLUDE_DIR} src) +target_include_directories(meta PRIVATE ${CLANG_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) target_link_libraries(meta PRIVATE sled ${CLANG_LIB_LIBRARIES}) diff --git a/runtime/reflection.cc b/runtime/reflection.cc new file mode 100644 index 0000000..4f7e127 --- /dev/null +++ b/runtime/reflection.cc @@ -0,0 +1,11 @@ +#include "reflection.h" + +namespace meta { +std::atomic next_type_id{0}; + +void +NoOp(void *) +{} + +Object::Object() : id_(GetTypeId()), data_(nullptr), deleter_(NoOp) {} +}// namespace meta diff --git a/runtime/reflection.h b/runtime/reflection.h new file mode 100644 index 0000000..ac2c71f --- /dev/null +++ b/runtime/reflection.h @@ -0,0 +1,61 @@ +#pragma once +#ifndef META_RUNTIME_REFLECTION_H +#define META_RUNTIME_REFLECTION_H +#include +#include +#include +#include +#include +#include + +namespace meta { +#define __REFLECTION_PARSER_ +#if defined(__REFLECTION_PARSER_) +#define CLASS(class_name, ...) \ + class __attribute__((annotate(#__VA_ARGS__))) class_name +#define STRUCT(struct_name, ...) \ + struct __attribute__((annotate(#__VA_ARGS__))) struct_name +#else +#define META(...) +#define CLASS(class_name, ...) class class_name +#define STRUCT(struct_name, ...) struct struct_name +#endif// __REFLECTION_PARSER_ + +#define REFLECTION_BODY(class_name) + +#define REFLECT_TYPE(class_name) + +class TypeInterface { +public: + virtual std::string name() const = 0; +}; + +class Class; + +class Method : public TypeInterface { +public: + virtual std::string name() = 0; + + template + ReturnT Invoke(void *instance, Args... args) const + { + std::vector arguments = {args...}; + return sled::any_cast( + std::forward(Invoke(instance, arguments))); + } + + sled::any Invoke(void *instance, std::vector &args) const + { + return InvokeImpl(instance, args); + } + +protected: + virtual sled::any InvokeImpl(void *instance, + std::vector &args) const = 0; +}; + +class Field; + +}// namespace meta + +#endif// META_RUNTIME_REFLECTION_H diff --git a/src/clang/cursor_type.h b/src/clang/cursor_type.h index ac2ad38..65ce174 100644 --- a/src/clang/cursor_type.h +++ b/src/clang/cursor_type.h @@ -9,6 +9,7 @@ extern "C" { } #endif +#include #include namespace meta { diff --git a/src/clang/parser.h b/src/clang/parser.h index 0f59d4e..6a42e6e 100644 --- a/src/clang/parser.h +++ b/src/clang/parser.h @@ -30,7 +30,7 @@ private: "-MG", "-M", "-ferror-limit=0", - "-o clangLog.txt"}}; + "-oclangLog.txt"}}; }; }// namespace meta diff --git a/src/language_types/field.h b/src/language_types/field.h new file mode 100644 index 0000000..4a87240 --- /dev/null +++ b/src/language_types/field.h @@ -0,0 +1,15 @@ +#pragma once +#ifndef META_LANGUAGE_TYPES_FIELD_H +#define META_LANGUAGE_TYPES_FIELD_H +#include "type.h" + +namespace meta { +class Field : public TypeInfo { +public: + virtual bool IsReadable() const; + virtual bool IsWritable() const; + virtual void *GetValue(void *instance) const; + virtual void SetValue(void *instance, void *value); +}; +}// namespace meta +#endif// META_LANGUAGE_TYPES_FIELD_H diff --git a/src/language_types/type.h b/src/language_types/type.h new file mode 100644 index 0000000..7af3a00 --- /dev/null +++ b/src/language_types/type.h @@ -0,0 +1,14 @@ +#pragma once +#ifndef META_LANGUAGE_TYPES_TYPE_H +#define META_LANGUAGE_TYPES_TYPE_H + +#include + +class TypeInfo { +public: + virtual ~TypeInfo() = default; + virtual std::string name() const = 0; + virtual std::string qualified_name() const = 0; +}; + +#endif// META_LANGUAGE_TYPES_TYPE_H diff --git a/src/meta/meta_info.h b/src/meta/meta_info.h index 52a2777..556820a 100644 --- a/src/meta/meta_info.h +++ b/src/meta/meta_info.h @@ -8,13 +8,16 @@ namespace meta { class MetaInfo { public: - MetaInfo(const Cursor& cursor); - std::string GetProperty(const std::string& key) const; - bool GetFlag(const std::string& key) const; - private: - using Property = std::pair ; - std::unordered_map properties_; - }; -} + MetaInfo(const Cursor &cursor); + std::string GetProperty(const std::string &key) const; + bool GetFlag(const std::string &key) const; -#endif // META_CLANG_META_INFO_H +private: + using Property = std::pair; + std::unordered_map properties_; + + std::vector ExtractProperties(const Cursor &cursor) const; +}; +}// namespace meta + +#endif// META_CLANG_META_INFO_H diff --git a/src/parser/parser.h b/src/parser/parser.h new file mode 100644 index 0000000..1b6812d --- /dev/null +++ b/src/parser/parser.h @@ -0,0 +1,18 @@ +#pragma once +#ifndef META_CLANG_PARSER_PARSER_H +#define META_CLANG_PARSER_PARSER_H +#include +#include + +namespace meta { +class MetaParser { +public: + MetaParser(const std::string &file_name); + ~MetaParser(); + +private: + CXIndex index_; + CXTranslationUnit translation_unit_; +}; +}// namespace meta +#endif// META_CLANG_PARSER_PARSER_H