bool GetFields( RecordDecl * rd, Obj * entries) { //check the fields of this struct, if any one of them is not understandable, then this struct becomes 'opaque' //that is, we insert the type, and link it to its llvm type, so it can be used in terra code //but none of its fields are exposed (since we don't understand the layout) bool opaque = false; for(RecordDecl::field_iterator it = rd->field_begin(), end = rd->field_end(); it != end; ++it) { if(it->isBitField() || it->isAnonymousStructOrUnion() || !it->getDeclName()) { opaque = true; continue; } DeclarationName declname = it->getDeclName(); std::string declstr = declname.getAsString(); QualType FT = it->getType(); Obj fobj; if(!GetType(FT,&fobj)) { opaque = true; continue; } lua_newtable(L); fobj.push(); lua_setfield(L,-2,"type"); lua_pushstring(L,declstr.c_str()); lua_setfield(L,-2,"field"); entries->addentry(); } return !opaque; }
void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!"); const ASTRecordLayout &layout = Types.getContext().getASTRecordLayout(D); llvm::Type *unionType = 0; CharUnits unionSize = CharUnits::Zero(); CharUnits unionAlign = CharUnits::Zero(); bool hasOnlyZeroSizedBitFields = true; bool checkedFirstFieldZeroInit = false; unsigned fieldNo = 0; for (RecordDecl::field_iterator field = D->field_begin(), fieldEnd = D->field_end(); field != fieldEnd; ++field, ++fieldNo) { assert(layout.getFieldOffset(fieldNo) == 0 && "Union field offset did not start at the beginning of record!"); llvm::Type *fieldType = LayoutUnionField(*field, layout); if (!fieldType) continue; if (field->getDeclName() && !checkedFirstFieldZeroInit) { CheckZeroInitializable(field->getType()); checkedFirstFieldZeroInit = true; } hasOnlyZeroSizedBitFields = false; CharUnits fieldAlign = CharUnits::fromQuantity( Types.getDataLayout().getABITypeAlignment(fieldType)); CharUnits fieldSize = CharUnits::fromQuantity( Types.getDataLayout().getTypeAllocSize(fieldType)); if (fieldAlign < unionAlign) continue; if (fieldAlign > unionAlign || fieldSize > unionSize) { unionType = fieldType; unionAlign = fieldAlign; unionSize = fieldSize; } } // Now add our field. if (unionType) { AppendField(CharUnits::Zero(), unionType); if (getTypeAlignment(unionType) > layout.getAlignment()) { // We need a packed struct. Packed = true; unionAlign = CharUnits::One(); } } if (unionAlign.isZero()) { (void)hasOnlyZeroSizedBitFields; assert(hasOnlyZeroSizedBitFields && "0-align record did not have all zero-sized bit-fields!"); unionAlign = CharUnits::One(); } // Append tail padding. CharUnits recordSize = layout.getSize(); if (recordSize > unionSize) AppendPadding(recordSize, unionAlign); }