static LLVMMetadataRef make_debug_field(compile_t* c, reach_type_t* t, uint32_t i) { const char* name; char buf[32]; unsigned flags = 0; uint64_t offset = 0; ast_t* ast; if(t->underlying != TK_TUPLETYPE) { ast_t* def = (ast_t*)ast_data(t->ast); ast_t* members = ast_childidx(def, 4); ast = ast_childidx(members, i); name = ast_name(ast_child(ast)); if(is_name_private(name)) flags |= DW_FLAG_Private; uint32_t extra = 0; if(t->underlying != TK_STRUCT) extra++; if(t->underlying == TK_ACTOR) extra++; offset = LLVMOffsetOfElement(c->target_data, t->structure, i + extra); } else { snprintf(buf, 32, "_%d", i + 1); name = buf; ast = t->ast; offset = LLVMOffsetOfElement(c->target_data, t->primitive, i); } LLVMTypeRef type; LLVMMetadataRef di_type; if(t->fields[i].embed) { type = t->fields[i].type->structure; di_type = t->fields[i].type->di_type_embed; } else { type = t->fields[i].type->use_type; di_type = t->fields[i].type->di_type; } uint64_t size = LLVMABISizeOfType(c->target_data, type); uint64_t align = LLVMABIAlignmentOfType(c->target_data, type); return LLVMDIBuilderCreateMemberType(c->di, c->di_unit, name, t->di_file, (unsigned)ast_line(ast), 8 * size, 8 * align, 8 * offset, flags, di_type); }
// Add the given AST to the given list, using the name from the specified // child. // ASTs with hygenic names are ignored. // Leading underscores on names are ignored for sorting purposes. // When false the allow_public parameter causes ASTs with public names to be // ignored. allow_private does the same for private names. static void doc_list_add_named(ast_list_t* list, ast_t* ast, size_t id_index, bool allow_public, bool allow_private) { assert(list != NULL); assert(ast != NULL); const char* name = ast_name(ast_childidx(ast, id_index)); assert(name != NULL); if(is_name_internal_test(name)) // Ignore internally generated names return; if(is_name_private(name) && !allow_private) // Ignore private return; if(!is_name_private(name) && !allow_public) // Ignore public return; if(is_name_private(name)) // Ignore leading underscore for ordering name++; doc_list_add(list, ast, name, false); }
static const char* suggest_alt_name(ast_t* ast, const char* name) { assert(ast != NULL); assert(name != NULL); size_t name_len = strlen(name); if(is_name_private(name)) { // Try without leading underscore const char* try_name = stringtab(name + 1); if(ast_get(ast, try_name, NULL) != NULL) return try_name; } else { // Try with a leading underscore char* buf = (char*)ponyint_pool_alloc_size(name_len + 2); buf[0] = '_'; strncpy(buf + 1, name, name_len + 1); const char* try_name = stringtab_consume(buf, name_len + 2); if(ast_get(ast, try_name, NULL) != NULL) return try_name; } // Try with a different case (without crossing type/value boundary) ast_t* case_ast = ast_get_case(ast, name, NULL); if(case_ast != NULL) { ast_t* id = case_ast; if(ast_id(id) != TK_ID) id = ast_child(id); assert(ast_id(id) == TK_ID); const char* try_name = ast_name(id); if(ast_get(ast, try_name, NULL) != NULL) return try_name; } // Give up return NULL; }
bool symtab_merge_public(symtab_t* dst, symtab_t* src) { size_t i = HASHMAP_BEGIN; symbol_t* sym; while((sym = symtab_next(src, &i)) != NULL) { if(is_name_private(sym->name) || (sym->status == SYM_NOCASE) || !strcmp(sym->name, "Main")) continue; if(!symtab_add(dst, sym->name, sym->def, sym->status)) return false; } return true; }
static bool make_tuple_index(ast_t** astp) { ast_t* ast = *astp; const char* name = ast_name(ast); if(!is_name_private(name)) return false; for(size_t i = 1; name[i] != '\0'; i++) { if((name[i] < '0') || (name[i] > '9')) return false; } size_t index = strtol(&name[1], NULL, 10) - 1; ast_t* node = ast_from_int(ast, index); ast_replace(astp, node); return true; }