From 436e35516ac997ec5fc0d769386d9b1128195b16 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Jan 2016 17:02:51 -0700 Subject: [PATCH] parseh properly ignores anonymous structs and nodes get valid create_index values --- src/analyze.cpp | 2 +- src/main.cpp | 3 ++- src/parseh.cpp | 38 ++++++++++++++++++++++++++++++++------ src/parseh.hpp | 4 ++-- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 88c9ba0323..27e6a1a382 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1111,7 +1111,7 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A int err; if ((err = parse_h_buf(child_import, &errors, child_context->c_import_buf, g->clang_argv, g->clang_argv_len, - buf_ptr(g->libc_include_path), false))) + buf_ptr(g->libc_include_path), false, &g->next_node_index))) { zig_panic("unable to parse h file: %s\n", err_str(err)); } diff --git a/src/main.cpp b/src/main.cpp index 8105634d6a..9248954e8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -221,7 +221,8 @@ static int parseh(const char *arg0, int argc, char **argv) { ImportTableEntry import = {0}; ZigList errors = {0}; - int err = parse_h_file(&import, &errors, &clang_argv, warnings_on); + uint32_t next_node_index = 0; + int err = parse_h_file(&import, &errors, &clang_argv, warnings_on, &next_node_index); if (err) { fprintf(stderr, "unable to parse .h file: %s\n", err_str(err)); diff --git a/src/parseh.cpp b/src/parseh.cpp index 743531ea7e..0d62ba352e 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -40,6 +40,7 @@ struct Context { SourceManager *source_manager; ZigList aliases; ZigList macro_symbols; + uint32_t *next_node_index; }; static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl); @@ -76,6 +77,8 @@ static AstNode *create_node(Context *c, NodeType type) { AstNode *node = allocate(1); node->type = type; node->owner = c->import; + node->create_index = *c->next_node_index; + *c->next_node_index += 1; return node; } @@ -398,7 +401,10 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, { const RecordType *record_ty = static_cast(ty); Buf *record_name = buf_create_from_str(decl_name(record_ty->getDecl())); - if (type_table->maybe_get(record_name)) { + if (buf_len(record_name) == 0) { + emit_warning(c, decl, "unhandled anonymous struct"); + return nullptr; + } else if (type_table->maybe_get(record_name)) { const char *prefix_str; if (type_table == &c->enum_type_table) { prefix_str = "enum_"; @@ -416,7 +422,10 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, { const EnumType *enum_ty = static_cast(ty); Buf *record_name = buf_create_from_str(decl_name(enum_ty->getDecl())); - if (type_table->maybe_get(record_name)) { + if (buf_len(record_name) == 0) { + emit_warning(c, decl, "unhandled anonymous enum"); + return nullptr; + } else if (type_table->maybe_get(record_name)) { const char *prefix_str; if (type_table == &c->enum_type_table) { prefix_str = "enum_"; @@ -560,6 +569,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) return; } + // if the underlying type is anonymous, we can special case it to just + // use the name of this typedef + // TODO + add_typedef_node(c, type_name, make_qual_type_node(c, child_qt, typedef_decl)); } @@ -650,13 +663,24 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { } static void visit_record_decl(Context *c, const RecordDecl *record_decl) { - Buf *bare_name = buf_create_from_str(decl_name(record_decl)); + const char *raw_name = decl_name(record_decl); + + if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) { + return; + } + + Buf *bare_name = buf_create_from_str(raw_name); if (!record_decl->isStruct()) { emit_warning(c, record_decl, "skipping record %s, not a struct", buf_ptr(bare_name)); return; } + if (buf_len(bare_name) == 0) { + emit_warning(c, record_decl, "skipping anonymous struct"); + return; + } + Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); if (c->struct_type_table.maybe_get(bare_name)) { @@ -1030,7 +1054,8 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { } int parse_h_buf(ImportTableEntry *import, ZigList *errors, Buf *source, - const char **args, int args_len, const char *libc_include_path, bool warnings_on) + const char **args, int args_len, const char *libc_include_path, bool warnings_on, + uint32_t *next_node_index) { int err; Buf tmp_file_path = BUF_INIT; @@ -1047,7 +1072,7 @@ int parse_h_buf(ImportTableEntry *import, ZigList *errors, Buf *sour clang_argv.append(args[i]); } - err = parse_h_file(import, errors, &clang_argv, warnings_on); + err = parse_h_file(import, errors, &clang_argv, warnings_on, next_node_index); os_delete_file(&tmp_file_path); @@ -1055,7 +1080,7 @@ int parse_h_buf(ImportTableEntry *import, ZigList *errors, Buf *sour } int parse_h_file(ImportTableEntry *import, ZigList *errors, - ZigList *clang_argv, bool warnings_on) + ZigList *clang_argv, bool warnings_on, uint32_t *next_node_index) { Context context = {0}; Context *c = &context; @@ -1068,6 +1093,7 @@ int parse_h_file(ImportTableEntry *import, ZigList *errors, c->struct_type_table.init(8); c->fn_table.init(8); c->macro_table.init(8); + c->next_node_index = next_node_index; char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS"); if (ZIG_PARSEH_CFLAGS) { diff --git a/src/parseh.hpp b/src/parseh.hpp index 47564b2b16..f3a6c8371f 100644 --- a/src/parseh.hpp +++ b/src/parseh.hpp @@ -12,9 +12,9 @@ #include "all_types.hpp" int parse_h_file(ImportTableEntry *out_import, ZigList *out_errs, - ZigList *clang_argv, bool warnings_on); + ZigList *clang_argv, bool warnings_on, uint32_t *next_node_index); int parse_h_buf(ImportTableEntry *out_import, ZigList *out_errs, Buf *source, const char **args, int args_len, const char *libc_include_path, - bool warnings_on); + bool warnings_on, uint32_t *next_node_index); #endif