ldc::DIType ldc::DIBuilder::CreateEnumType(Type *type) { assert(type->ty == Tenum); llvm::Type *T = DtoType(type); TypeEnum *te = static_cast<TypeEnum *>(type); llvm::SmallVector<LLMetadata *, 8> subscripts; for (auto m : *te->sym->members) { EnumMember *em = m->isEnumMember(); llvm::StringRef Name(em->toChars()); uint64_t Val = em->value()->toInteger(); auto Subscript = DBuilder.createEnumerator(Name, Val); subscripts.push_back(Subscript); } llvm::StringRef Name = te->toChars(); unsigned LineNumber = te->sym->loc.linnum; ldc::DIFile File(CreateFile(te->sym)); return DBuilder.createEnumerationType( GetCU(), Name, File, LineNumber, getTypeAllocSize(T) * 8, // size (bits) getABITypeAlign(T) * 8, // align (bits) DBuilder.getOrCreateArray(subscripts), // subscripts CreateTypeDescription(te->sym->memtype, false)); }
unsigned cv4_Denum(EnumDeclaration *e) { //dbg_printf("cv4_Denum(%s)\n", e->toChars()); unsigned property = 0; if (!e->members || !e->memtype || !e->memtype->isintegral()) property |= 0x80; // enum is forward referenced or non-integer // Compute the number of fields, and the length of the fieldlist record unsigned nfields = 0; unsigned fnamelen = 2; if (!property) { for (size_t i = 0; i < e->members->dim; i++) { EnumMember *sf = (*e->members)[i]->isEnumMember(); if (sf) { dinteger_t value = sf->value()->toInteger(); unsigned fnamelen1 = fnamelen; // store only member's simple name fnamelen += 4 + cv4_numericbytes(value) + cv_stringbytes(sf->toChars()); if (config.fulltypes != CV8) { /* Optlink dies on longer ones, so just truncate */ if (fnamelen > CV4_NAMELENMAX) { fnamelen = fnamelen1; // back up break; // and skip the rest } } nfields++; } } } const char *id = e->toPrettyChars(); unsigned len; debtyp_t *d; unsigned memtype = e->memtype ? cv4_typidx(Type_toCtype(e->memtype)) : 0; switch (config.fulltypes) { case CV8: len = 14; d = debtyp_alloc(len + cv_stringbytes(id)); TOWORD(d->data,LF_ENUM_V3); TOLONG(d->data + 6,memtype); TOWORD(d->data + 4,property); len += cv_namestring(d->data + len,id); break; case CV4: len = 10; d = debtyp_alloc(len + cv_stringbytes(id)); TOWORD(d->data,LF_ENUM); TOWORD(d->data + 4,memtype); TOWORD(d->data + 8,property); len += cv_namestring(d->data + len,id); break; default: assert(0); } unsigned length_save = d->length; d->length = 0; // so cv_debtyp() will allocate new idx_t typidx = cv_debtyp(d); d->length = length_save; // restore length TOWORD(d->data + 2,nfields); unsigned fieldlist = 0; if (!property) // if forward reference, then fieldlist is 0 { // Generate fieldlist type record debtyp_t *dt = debtyp_alloc(fnamelen); TOWORD(dt->data,(config.fulltypes == CV8) ? LF_FIELDLIST_V2 : LF_FIELDLIST); // And fill it in unsigned j = 2; unsigned fieldi = 0; for (size_t i = 0; i < e->members->dim; i++) { EnumMember *sf = (*e->members)[i]->isEnumMember(); if (sf) { fieldi++; if (fieldi > nfields) break; // chop off the rest dinteger_t value = sf->value()->toInteger(); TOWORD(dt->data + j,(config.fulltypes == CV8) ? LF_ENUMERATE_V3 : LF_ENUMERATE); unsigned attribute = 0; TOWORD(dt->data + j + 2,attribute); cv4_storenumeric(dt->data + j + 4,value); j += 4 + cv4_numericbytes(value); // store only member's simple name j += cv_namestring(dt->data + j, sf->toChars()); // If enum is not a member of a class, output enum members as constants // if (!isclassmember(s)) // { // cv4_outsym(sf); // } } } assert(j == fnamelen); fieldlist = cv_debtyp(dt); } if (config.fulltypes == CV8) TOLONG(d->data + 10,fieldlist); else TOWORD(d->data + 6,fieldlist); // cv4_outsym(s); return typidx; }