clReflect v0.4 pre-release, C++ Reflection using clang

Installation Instructions

The executables in the "bin" directory can be run directly but require the MSVC 2010 x86 redistributables.

Quick Tour

clReflectTest is an up-to-date test of the clReflect library, showing how to build a database and load it at runtime.

C++ primitives are not reflected by default and need to be marked by clcpp_reflect Reflection Specs or using reflect attributes. More details can be found here.

Basic build steps are...

// Use clReflectScan to parse your C++ files and output a readable database of type information:
bin/clscan.exe file_a.cpp -output file_a.csv -ast_log file_a_astlog.txt -spec_log file_a_speclog.txt -i "include_path"

// Use clReflectMerge to merge the output of many C++ files into one readable database of type information:
bin/clmerge.exe module.csv file_a.csv file_b.csv file_c.csv ...

// Use clReflectExport to convert the readable database to a memory-mapped, C++ loadable/queryable database:
bin/clexport.exe module.csv -cpp module.cppbin -cpp_log module_cpplog.txt

This will give you a runtime loadable database with two limitations:

  1. Functions and their parameters/return types will be reflected but their call address will not.
  2. You will have to use clcpp::Database::GetType in unison with clcpp::Database::GetName to get types at runtime instead of the more efficient clcpp::GetType.

To reflect function call addresses, pass a MAP file generated by your linker to the final clReflectExport build step:

bin/clexport.exe module.csv -cpp module.cppbin -cpp_log module_cpplog.txt -map module.map

To use the constant-time, string-less GetType and GetTypeNameHash functions you need to ask clReflectMerge to generate their implementations for you:

bin/clmerge.exe module.csv -cpp_codegen clcppGeneratedCode.cpp file_a.csv file_b.csv file_c.csv ...

Compile and link this generated C++ file with the rest of your code, load your database, call the generated initialisation function to perform one-time setup and all features of clReflect are available to you.

Make sure you pay attention to all reported warnings and inspect all output log files if you suspect there is a problem!

Release notes - detailed


  • Updated to use the new clang/LLVM 3.0 release branch, including the source as part of the tree.
  • Added container support with iterator interfaces and a means of registering/parsing the containers in C++.
  • Added support for constant-size arrays as field types (classes, functions, methods).
  • Added constant-time, string-less GetType and GetTypeNameHash functions so that a runtime should never need to depend on string processing and the functions can be used in templated functions.
  • Added support for anonymous structs and unions.
  • Added new utility library that contains optional C++ runtime components that can be used with clReflect.
  • Added versioned, binary serialisation for reflected types.
  • Added a JSON serialiser for reflected types with no external library dependencies.
  • Added a basic object model implementation with base objects and object database with iterators.
  • Added a generic field visitor with delegate for callback.
  • Added support for template types as base classes. Template types can now also have base classes/template types.
  • Added support for 'int64', 'unsigned int64', 'long long', 'unsigned long long' and 'wchar_t'.
  • Added support for typedefs - treated as typical C++ type aliases.
  • Added function address rebasing for the case of rebased DLLs.
  • Added a Module (DLL-only) abstraction to utilities with interface/implementation support.
  • Added a DerivesFrom method to Classes.
  • Added the 'noreflect' attribute for skipping reflection of problematic primitives.
  • Added flag attribute bit fields for common flag attributes.
  • Added support for the colon character in attribute parsing, for scoped symbols.
  • Added primitive searching for overloaded primitives (e.g. functions).
  • Added command-line option for system include files - these don't display compile warnings.
  • Added CallConstructor/CallDestructor and made it so that clcpp_impl_class now only requires one parameter.
  • Big refactor of is_const/modifier parameters. Introduced the Qualifier type to abstract this concept and make it usable elsewhere.
  • Field names are no longer fully-scoped, leading to smaller storage, less chance of CRC conflicts and simpler runtime querying/serialisation.
  • Shifted unresolved primitive references to clexport where the problem can be more accurately diagnosed. clscan was the wrong place to do this for the majority of cases as types can be forward referenced without a reflection spec.
  • Pushed Name construction as far back in the AST consumer as possible. This is potentially slower but it prevents an awful lot of unused name data being constructed, hence reducing the size of the cppbin file (by 20% in my game).
  • Using the minimum-size config for linking with clang/LLVM to reduce clscan.exe size by 1MB.
  • Fixed bug with the clcpp::FindPrimitive binary search and larger than int range hashes.
  • Fixed nasty crash bug with clReflectExport's use of CArray.
  • Fixed typo in the database binary serialiser that crashed when a file didn't exist.
  • Fixed an assert in the pointer relocator that would assert when allocated data was sizeof(0) and at the end of the allocated stack data.
  • Fixed return code of clscan.exe when there are compile errors.
  • Fixed bug with reflection spec warnings being generated incorrectly for partially reflected primitives.
  • Many more bug fixes and lots of refactoring; see the commit list for more info.