Clang and LLVM solved your problem by creating tables containing their objects using a combination of code generation and preprocessor tricks.
You can skip any step, depending on your own setup. For instance:
EXPAND_RECORD(Foo, "Foo", 4);
EXPAND_RECORD(Bar, "Bar", 18);
EXPAND_RECORD(Bar2, "Bar", 19);
:
enum Record {
#define EXPAND_RECORD(Name, String, Value) Name,
#include "records.inc"
#undef EXPAND_RECORD
};
char const* getRecordName(Record r);
int getRecordValue(Record r);
char const* getRecordName(Record r) {
switch(r) {
#define EXPAND_RECORD(Name, String, Value) case Name: return String;
#include "records.inc"
#undef EXPAND_RECORD
}
abort();
}
int getRecordValue(Record r) {
switch(r) {
#define EXPAND_RECORD(Name, String, Value) case Name: return Value;
#include "records.inc"
#undef EXPAND_RECORD
}
abort();
}
Clang LLVM .inc .
... , . , " ", , , (, ) (unsigned), : , , .