15     if (
const CXXRecordDecl * klass = Result.Nodes.getNodeAs<clang::CXXRecordDecl>(
"not std:: class")) {
    18         std::cerr << fmt::format(
"Got a class that's not a std:: class {}", class_name) << std::endl;
    21         if (klass->isDependentType()) {
    22             cerr << 
"Skipping 'class with annotation' dependent type: " << class_name << endl;
    27         if (std::regex_match(name, regex(
"^(class\\s+|struct\\s+)?std::.*$"))) {
    30         if (std::regex_match(name, regex(
"^(class\\s+|struct\\s+)?__.*$"))) {
    34         cerr << endl << 
"Got class definition: " << class_name << endl;
    35         fprintf(stderr, 
"decl ptr: %p\n", (
void *)klass);
    39             cerr << 
"SKIPPING BAD RECORD DECL" << endl;
    42         cerr << 
"Storing it for later processing (unless dupe)" << endl;
    48     if (
const CXXRecordDecl * klass = Result.Nodes.getNodeAs<clang::CXXRecordDecl>(
"forward declaration with annotation")) {
    51         cerr << endl << 
"Got forward declaration with annotation: " << class_name << endl;
    54         auto described_tmpl = klass->getDescribedClassTemplate();
    55         if (klass->isDependentType() && described_tmpl) {
    56             fprintf(stderr, 
"described template %p, %s\n", (
void *)described_tmpl, described_tmpl->getQualifiedNameAsString().c_str());
    57             printf(
"Merging %d annotations with template %p\n", (
int)
Annotations(klass).
get().size(), (
void*)described_tmpl);
    63     if (
const CXXRecordDecl * klass = Result.Nodes.getNodeAs<clang::CXXRecordDecl>(
"class derived from WrappedClassBase")) {
    66             cerr << 
"skipping 'bad' record decl" << endl;
    69         if (klass->isDependentType()) {
    70             cerr << 
"skipping dependent type" << endl;
    75         if (std::regex_match(name, regex(
"^(class\\s+|struct\\s+)?std::.*$"))) {
    78         if (std::regex_match(name, regex(
"^(class\\s+|struct\\s+)?__.*$"))) {
    84             cerr << 
"Skipping class because it's explicitly marked SKIP" << endl;
    93             cerr << 
"SKIPPING BAD RECORD DECL" << endl;
    96         cerr << 
"Storing it for later processing (unless dupe)" << endl;
   102     if (
auto typedef_decl = Result.Nodes.getNodeAs<clang::TypedefNameDecl>(
"named decl")) {
   103         auto qual_type = typedef_decl->getUnderlyingType();
   104         auto record_decl = qual_type->getAsCXXRecordDecl();
   111         if (std::regex_match(name, regex(
"^(class\\s+|struct\\s+)?std::.*$"))) {
   114         if (std::regex_match(name, regex(
"^(class\\s+|struct\\s+)?__.*$"))) {
   121             string name_alias = typedef_decl->getNameAsString();
   122             std::cerr << fmt::format(
"Annotated type name: {} => {}", record_decl->getQualifiedNameAsString(), typedef_decl->getNameAsString()) << std::endl;
   127                wrapped_class->name_alias = name_alias;
   134 #ifdef TEMPLATE_INFO_ONLY   136     if (
const ClassTemplateSpecializationDecl * klass = Result.Nodes.getNodeAs<clang::ClassTemplateSpecializationDecl>(
"class")) {
   141             if (std::regex_search(class_name, std::regex(
"^(class|struct)\\s+v8toolkit"))) {
   143                 print_logging = 
true;
   144                 cerr << fmt::format(
"Got class {}", class_name) << endl;
   148 #ifdef TEMPLATE_FILTER_STD   149             if (std::regex_search(class_name, std::regex(
"^std::"))) {
   150                 if (print_logging) cerr << 
"Filtering out because in std::" << endl;
   157             auto tmpl = klass->getSpecializedTemplate();
   159                 cerr << 
"got specialized template " << tmpl->getQualifiedNameAsString() << endl;
   164 #ifdef TEMPLATE_FILTER_STD   165             if (std::regex_search(tmpl->getQualifiedNameAsString(), std::regex(
"^std::"))) {
   176         if (
const CXXMethodDecl * method = Result.Nodes.getNodeAs<clang::CXXMethodDecl>(
"method")) {
   177             auto method_name = method->getQualifiedNameAsString();
   178             const FunctionDecl * pattern = 
nullptr;
   180             if (!method->isTemplateInstantiation()) {
   183 #ifdef TEMPLATE_FILTER_STD   184             if (std::regex_search(method_name, std::regex(
"^std::"))) {
   189             pattern = method->getTemplateInstantiationPattern();
   195                 llvm::report_fatal_error(
"method is template insantiation but pattern still nullptr");
   204             if (std::regex_search(method_name, std::regex(
"function_in_temp"))) {
   205                 cerr << endl << 
"*******Found function in templated class decl" << endl;
   206                 fprintf(stderr, 
"Method decl ptr: %p\n", (
void*) method);
   207                 cerr << 
"is dependent context: " << method->isDependentContext() << endl;
   208                 cerr << 
"has dependent template info: " << (method->getDependentSpecializationInfo() != 
nullptr) << endl;
   209                 cerr << 
"is template instantiation: " << (method->isTemplateInstantiation()) << endl;
   210                 cerr << 
"has instantiation pattern: " << (method->getTemplateInstantiationPattern() != 
nullptr) << endl;
   211                 if (method->getTemplateInstantiationPattern()) {
   212                 fprintf(stderr, 
"template instantiation pattern ptr: %p\n", (
void*) method->getTemplateInstantiationPattern());
   214                 print_logging = 
true;
   217             const FunctionTemplateDecl * function_template_decl = method->getDescribedFunctionTemplate();
   219             if (function_template_decl == 
nullptr && method->getTemplateSpecializationInfo()) {
   220                 function_template_decl = method->getTemplateSpecializationInfo()->getTemplate();
   223             if (function_template_decl) {
   224                 cerr << fmt::format(
"'real' templated method {} has instantiation pattern: {}", method_name, method->getTemplateInstantiationPattern() != 
nullptr) << endl;
   225                 fprintf(stderr, 
"method: %p, instantiation pattern: %p\n", (
void *)method, (
void*)method->getTemplateInstantiationPattern());
   227                 cerr << fmt::format(
"Got method {}", method_name) << endl;
   230                 if (print_logging) cerr << 
"not interesting method" << endl;
   237 #endif // end TEMPLATE_INFO_ONLY   254     auto full_source_loc = FullSourceLoc(wrapped_class.
decl->getLocation(), this->source_manager);
   256     auto file_id = full_source_loc.getFileID();
   289     if (
print_logging) cerr << 
"About to process base class info" << endl;
   298                 "Not wrapping constructor for class only wrapped because it's base class of another wrapped type")
   301             cerr << fmt::format(
"Not wrapping because class has DO NOT WRAP CONSTRUCTORS annotation") << endl;
   302         } 
else if (wrapped_class.
decl->isAbstract()) {
   303             cerr << 
"Skipping all constructors because class is abstract: " << class_name << endl;
   305             cerr << fmt::format(
"'force no constructors' set on {} so skipping making constructors", class_name)
   310                     "About to process constructors for {} -- passed all checks to skip class constructors.",
   318         if (top_level_class->constructors.empty() && top_level_class->
has_static_method) {
   322             if (!static_name_annotation.empty()) {
   323                 static_name = static_name_annotation[0];
   325             top_level_class->constructors.insert(
   326                 fmt::format(
"{}  class_wrapper.expose_static_methods(\"{}\", isolate);\n", indentation,
   335                 cerr << 
"Type " << top_level_class->
class_name << 
" **IS** bidirectional" << endl;
   337             auto generated_header_name = fmt::format(
"\"v8toolkit_generated_bidirectional_{}.h\"",
   341             auto bidirectional_class_name = fmt::format(
"JS{}", top_level_class->
get_short_name());
   345             cerr << 
"Creating new Wrapped class object for " << bidirectional_class_name << endl;
   346             js_wrapped_class = 
new WrappedClass(bidirectional_class_name,
   350             auto &bidirectional = *js_wrapped_class;
   351             bidirectional.base_types.insert(top_level_class);
   353             cerr << fmt::format(
"Adding derived bidirectional type {} to base type: {}",
   354                                 bidirectional.class_name, wrapped_class.
name_alias) << endl;
   359             bidirectional.include_files.insert(generated_header_name);
   360             bidirectional.my_include = generated_header_name;
   362             BidirectionalBindings bd(this->
ci, *js_wrapped_class, wrapped_class);
   363             bd.generate_bindings();
   368                 cerr << 
"Type " << top_level_class->
class_name << 
" is not bidirectional" << endl;
   379         cerr << warning << endl;
   385         cerr << 
"Errors detected:" << endl;
   387             cerr << error << endl;
   389         llvm::report_fatal_error(
"Errors detected in source data");
   394     cerr << 
"*************" << endl << 
"ABOUT TO GENERATE OUTPUT FILES" << endl << 
"*****************" << endl;
   403 void ClassHandler::handle_method(
WrappedClass & klass, CXXMethodDecl * method) {
   406     std::string full_method_name(method->getQualifiedNameAsString());
   407     std::string short_method_name(method->getNameAsString());
   427                                                  full_method_name.c_str(), export_type);
   432     if (method->getAccess() != AS_public) {
   439     if (method->isOverloadedOperator()) {
   442         if (OO_Call == method->getOverloadedOperator()) {
   448                 printf(
"**skipping overloaded operator %s\n", full_method_name.c_str());
   452     if (dyn_cast<CXXConstructorDecl>(method)) {
   456     if (dyn_cast<CXXDestructorDecl>(method)) {
   478     if (method->isVirtual() && method->size_overridden_methods()) {
   479         if (
PRINT_SKIPPED_EXPORT_REASONS) printf(
"**skipping derived-class override of base class virtual function %s\n", full_method_name.c_str());
   483     if (dyn_cast<CXXConversionDecl>(method)) {
   495     if (top_level_class->names.count(short_method_name)) {
   496         data_error(fmt::format(
"Skipping duplicate name {}/{} :: {}\n",
   503     top_level_class->names.insert(short_method_name);
   505     auto parsed_method = make_unique<ParsedMethod>(this->
ci, klass, method);
   514     std::stringstream result;
   516     auto short_field_name = field->getNameAsString();
   517     auto full_field_name = field->getQualifiedNameAsString();
   520     cerr << 
"Processing data member for: " << containing_class.
name_alias << 
": " << full_field_name << endl;
   533     top_level_class->names.insert(short_field_name);
   545     std::cerr << fmt::format(
"incrementing declaration count for {} - data member", top_level_class->
name_alias) << std::endl;
 
static map< const ClassTemplateDecl *, Annotations > annotations_for_class_templates
int matched_classes_returned
static WrappedClass & get_or_insert_wrapped_class(const CXXRecordDecl *decl, CompilerInstance &compiler_instance, FOUND_METHOD found_method)
string name_alias
this is the possibly shortened javascript name of the type - not necessarily valid in generated c++ ...
void data_error(const string &error)
static ClassTemplate & get_or_create(const ClassTemplateDecl *decl)
void update_wrapped_class_for_type(WrappedClass &wrapped_class, QualType qual_type)
std::string get_type_string(QualType qual_type, const std::string &indentation)
static FunctionTemplate & get_or_create(const FunctionDecl *decl)
set< string > include_files
bool is_good_record_decl(const CXXRecordDecl *decl)
#define V8TOOLKIT_NAME_ALIAS_STRING
virtual void onEndOfTranslationUnit() override
#define V8TOOLKIT_BIDIRECTIONAL_CLASS_STRING
bool force_no_constructors
#define PRINT_SKIPPED_EXPORT_REASONS
vector< string > data_errors
std::string get_include_string_for_fileid(CompilerInstance &compiler_instance, FileID &file_id)
FOUND_METHOD found_method
void print_specialization_info(const CXXRecordDecl *decl)
std::vector< string > get_regex(const string ®ex_string) const 
#define V8TOOLKIT_EXPOSE_STATIC_METHODS_AS_PREFIX
void generate_bidirectional_classes(CompilerInstance &compiler_instance)
EXPORT_TYPE get_export_type(const NamedDecl *decl, EXPORT_TYPE previous)
virtual void run(const ast_matchers::MatchFinder::MatchResult &Result) override
#define V8TOOLKIT_NONE_STRING
bool has(const std::string &target) const 
static WrappedClass * get_if_exists(const CXXRecordDecl *decl)
std::string handle_data_member(WrappedClass &containing_class, FieldDecl *field, const std::string &indentation)
void generate_javascript_stub(std::string const &filename)
set< WrappedClass * > derived_types
static void insert_wrapped_class(WrappedClass *wrapped_class)
vector< string > data_warnings
std::string get_canonical_name_for_decl(const TypeDecl *decl)
CXXRecordDecl const * decl
static map< const CXXRecordDecl *, string > names_for_record_decls
static map< const CXXRecordDecl *, Annotations > annotations_for_record_decls
void handle_class(WrappedClass &wrapped_class, bool top_level=true, const std::string &indentation="")
#define V8TOOLKIT_DO_NOT_WRAP_CONSTRUCTORS_STRING
std::string get_short_name() const