Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Changeset 797:340acf1535d0

Show
Ignore:
Timestamp:
11/29/08 15:25:43 (1 month ago)
Author:
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
Children:

798:92ea3015ace6 800:d14e4594c7d7

branch:
default
Message:

Removed KDevelop3 project files, CMake can generate them just fine!
Fixed function literals in static initializers.
Changed alignment of delegates from 2*PTRSIZE to just PTRSIZE.
Changed errors to go to stderr instead of stdout.
Fairly major rewriting of struct/union/class handling, STILL A BIT BUGGY !!!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dmd/aggregate.h

    r336 r797  
    4646    class GlobalVariable; 
    4747} 
    48 struct DUnion; 
    4948 
    5049struct AggregateDeclaration : ScopeDsymbol 
     
    259258    Symbol *vtblsym; 
    260259 
    261     // llvm 
    262     void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result); 
    263  
    264260    ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 
    265261}; 
  • dmd/attrib.c

    r794 r797  
    617617    aad.structalign = sc->structalign; 
    618618    aad.parent = ad; 
    619  
    620619    for (unsigned i = 0; i < decl->dim; i++) 
    621620    { 
     
    672671    { 
    673672        VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; 
     673 
     674        // LDC 
     675        v->offset2 = sc->offset; 
    674676 
    675677        v->offset += sc->offset; 
  • dmd/attrib.h

    r710 r797  
    5151    AttribDeclaration *isAttribDeclaration() { return this; } 
    5252 
    53     void toObjFile(int multiobj);         // compile to .obj file 
     53    virtual void toObjFile(int multiobj);         // compile to .obj file 
    5454    int cvMember(unsigned char *p); 
    5555}; 
     
    108108    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    109109    const char *kind(); 
     110 
     111    // LDC 
     112    void toObjFile(int multiobj);           // compile to .obj file 
    110113}; 
    111114 
  • dmd/declaration.c

    r737 r797  
    625625    // LDC 
    626626    anonDecl = NULL; 
     627    offset2 = 0; 
    627628} 
    628629 
  • dmd/declaration.h

    r751 r797  
    274274    // LDC 
    275275    AnonDeclaration* anonDecl; 
     276    unsigned offset2; 
    276277}; 
    277278 
  • dmd/expression.h

    r664 r797  
    629629    //Expression *doInline(InlineDoState *ids); 
    630630    //Expression *inlineScan(InlineScanState *iss); 
     631 
     632    // LDC 
     633    virtual llvm::Constant *toConstElem(IRState *irs); 
    631634}; 
    632635 
  • dmd/mars.c

    r788 r797  
    11971197    } 
    11981198    } 
     1199#endif 
    11991200    if (global.errors) 
    12001201    fatal(); 
    1201 #endif 
    12021202 
    12031203    // Generate output files 
  • dmd/mars.h

    r735 r797  
    346346 
    347347/*** Where to send error messages ***/ 
    348 #if IN_GCC 
     348#if IN_GCC || IN_LLVM 
    349349#define stdmsg stderr 
    350350#else 
  • dmd/mtype.c

    r780 r797  
    31853185{ 
    31863186    return PTRSIZE * 2; 
     3187} 
     3188 
     3189// LDC added, no reason to align to 2*PTRSIZE 
     3190unsigned TypeDelegate::alignsize() 
     3191{ 
     3192    // A Delegate consists of two ptr values, so align it on pointer size 
     3193    // boundary 
     3194    return PTRSIZE; 
    31873195} 
    31883196 
  • dmd/mtype.h

    r758 r797  
    452452    Type *semantic(Loc loc, Scope *sc); 
    453453    d_uns64 size(Loc loc); 
     454    unsigned alignsize(); // added in LDC 
    454455    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    455456    Expression *defaultInit(Loc loc); 
  • dmd2/aggregate.h

    r758 r797  
    4646    class GlobalVariable; 
    4747} 
    48 struct DUnion; 
    4948 
    5049struct AggregateDeclaration : ScopeDsymbol 
     
    265264    Symbol *vtblsym; 
    266265 
    267     // llvm 
    268     void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result); 
    269  
    270266    ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 
    271267}; 
  • dmd2/attrib.c

    r758 r797  
    630630    aad.structalign = sc->structalign; 
    631631    aad.parent = ad; 
    632  
    633632    for (unsigned i = 0; i < decl->dim; i++) 
    634633    { 
     
    685684    { 
    686685        VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; 
     686 
     687        // LDC 
     688        v->offset2 = sc->offset; 
    687689 
    688690        v->offset += sc->offset; 
  • dmd2/attrib.h

    r758 r797  
    5151    AttribDeclaration *isAttribDeclaration() { return this; } 
    5252 
    53     void toObjFile(int multiobj);         // compile to .obj file 
     53    virtual void toObjFile(int multiobj);         // compile to .obj file 
    5454    int cvMember(unsigned char *p); 
    5555}; 
  • dmd2/declaration.c

    r758 r797  
    619619    // LDC 
    620620    anonDecl = NULL; 
     621    offset2 = 0; 
    621622} 
    622623 
  • dmd2/declaration.h

    r758 r797  
    280280    // LDC 
    281281    AnonDeclaration* anonDecl; 
     282    unsigned offset2; 
    282283}; 
    283284 
  • dmd2/expression.h

    r758 r797  
    654654    //Expression *doInline(InlineDoState *ids); 
    655655    //Expression *inlineScan(InlineScanState *iss); 
     656 
     657    // LDC 
     658    virtual llvm::Constant *toConstElem(IRState *irs); 
    656659}; 
    657660 
  • dmd2/mars.c

    r789 r797  
    12211221    } 
    12221222    } 
     1223#endif 
    12231224    if (global.errors) 
    12241225    fatal(); 
    1225 #endif 
    12261226 
    12271227    // Generate output files 
  • dmd2/mars.h

    r758 r797  
    351351 
    352352/*** Where to send error messages ***/ 
    353 #if IN_GCC 
     353#if IN_GCC || IN_LLVM 
    354354#define stdmsg stderr 
    355355#else 
  • dmd2/mtype.c

    r771 r797  
    36953695} 
    36963696 
     3697// LDC added, no reason to align to 2*PTRSIZE 
     3698unsigned TypeDelegate::alignsize() 
     3699{ 
     3700    // A Delegate consists of two ptr values, so align it on pointer size 
     3701    // boundary 
     3702    return PTRSIZE; 
     3703} 
     3704 
    36973705void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    36983706{ 
  • dmd2/mtype.h

    r758 r797  
    517517    Type *semantic(Loc loc, Scope *sc); 
    518518    d_uns64 size(Loc loc); 
     519    unsigned alignsize(); // added in LDC 
    519520    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    520521    Expression *defaultInit(Loc loc); 
  • gen/arrays.cpp

    r796 r797  
    209209 
    210210////////////////////////////////////////////////////////////////////////////////////////// 
     211 
     212// FIXME: this looks like it could use a cleanup 
     213 
    211214LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) 
    212215{ 
     
    241244    Type* arrnext = arrinittype->nextOf(); 
    242245    const LLType* elemty = DtoType(arrinittype->nextOf()); 
     246 
     247    // true if there is a mismatch with one of the initializers 
     248    bool mismatch = false; 
    243249 
    244250    assert(arrinit->index.dim == arrinit->value.dim); 
     
    293299        assert(v); 
    294300 
     301        // global arrays of unions might have type mismatch for each element 
     302        // if there is any mismatch at all, we need to use a struct instead :/ 
     303        if (v->getType() != elemty) 
     304            mismatch = true; 
     305 
    295306        inits[i] = v; 
    296307        if (Logger::enabled()) 
     
    299310 
    300311    Logger::println("building constant array"); 
     312 
     313    LLConstant* constarr; 
    301314    const LLArrayType* arrty = LLArrayType::get(elemty,tdim); 
    302     LLConstant* constarr = LLConstantArray::get(arrty, inits); 
     315 
     316    if (mismatch) 
     317    { 
     318        constarr = LLConstantStruct::get(inits); 
     319    } 
     320    else 
     321    { 
     322        constarr = LLConstantArray::get(arrty, inits); 
     323    } 
     324 
     325#if 0 
     326    if (Logger::enabled()) 
     327    { 
     328        Logger::cout() << "array type: " << *arrty << '\n'; 
     329        size_t n = inits.size(); 
     330        for (size_t i=0; i<n; i++) 
     331            Logger::cout() << "  init " << i << " = " << *inits[i] << '\n'; 
     332    } 
     333#endif 
    303334 
    304335    if (arrinittype->ty == Tsarray) 
     
    307338        assert(arrinittype->ty == Tarray); 
    308339 
    309     LLGlobalVariable* gvar = new LLGlobalVariable(arrty,true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module); 
     340    LLGlobalVariable* gvar = new LLGlobalVariable(constarr->getType(),true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module); 
    310341    LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; 
     342 
    311343    LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 
     344    gep = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(elemty)); 
     345 
    312346    return DtoConstSlice(DtoConstSize_t(tdim),gep); 
    313347} 
     
    793827    // return result 
    794828    return (op == TOKnotidentity) ? gIR->ir->CreateNot(res) : res; 
    795 } 
    796  
    797 ////////////////////////////////////////////////////////////////////////////////////////// 
    798 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c) 
    799 { 
    800     const LLArrayType* at = isaArray(t); 
    801     assert(at); 
    802  
    803     if (isaArray(at->getElementType())) 
    804     { 
    805         c = DtoConstStaticArray(at->getElementType(), c); 
    806     } 
    807     else { 
    808         assert(at->getElementType() == c->getType()); 
    809     } 
    810     std::vector<LLConstant*> initvals; 
    811     initvals.resize(at->getNumElements(), c); 
    812     return llvm::ConstantArray::get(at, initvals); 
    813829} 
    814830 
  • gen/arrays.h

    r591 r797  
    1010LLConstant* DtoConstArrayInitializer(ArrayInitializer* si); 
    1111LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr); 
    12 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c); 
    1312 
    1413void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src); 
  • gen/classes.cpp

    r796 r797  
    2222////////////////////////////////////////////////////////////////////////////////////////// 
    2323 
    24 static void LLVM_AddBaseClassInterfaces(ClassDeclaration* target, BaseClasses* bcs) 
    25 
    26     // add base class data members first 
    27     for (int j=0; j<bcs->dim; j++) 
    28     { 
    29         BaseClass* bc = (BaseClass*)(bcs->data[j]); 
    30  
    31         // base *classes* might add more interfaces? 
    32         DtoResolveClass(bc->base); 
    33         LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); 
    34  
    35         // resolve interfaces while we're at it 
    36         if (bc->base->isInterfaceDeclaration()) 
     24// adds interface b to target, if newinstance != 0, then target must provide all 
     25// functions required to implement b (it reimplements b) 
     26static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance) 
     27
     28    Logger::println("adding interface: %s", b->base->toChars()); 
     29    LOG_SCOPE; 
     30 
     31    InterfaceDeclaration* inter = b->base->isInterfaceDeclaration(); 
     32    DtoResolveClass(inter); 
     33 
     34    assert(inter); 
     35    IrStruct* irstruct = target->ir.irStruct; 
     36    assert(irstruct); 
     37 
     38    // add interface to map/list 
     39    // if it's already inserted in the map, it's because another interface has it as baseclass 
     40    // but if it appears here, it's because we're reimplementing it, so we overwrite the IrInterface entry 
     41    IrInterface* iri; 
     42    bool overwrite = false; 
     43    if (irstruct->interfaceMap.find(inter) != irstruct->interfaceMap.end()) 
     44    { 
     45        overwrite = true; 
     46    } 
     47 
     48    iri = new IrInterface(b); 
     49    // add to map 
     50    if (overwrite) 
     51        irstruct->interfaceMap[b->base] = iri; 
     52    else 
     53        irstruct->interfaceMap.insert(std::make_pair(b->base, iri)); 
     54    // add to ordered list 
     55    irstruct->interfaceVec.push_back(iri); 
     56 
     57    // assign this iri to all base interfaces of this one 
     58    for (unsigned j = 0; j < b->baseInterfaces_dim; j++) 
     59    { 
     60        BaseClass *bc = &b->baseInterfaces[j]; 
     61        // add to map 
     62        if (irstruct->interfaceMap.find(bc->base) == irstruct->interfaceMap.end()) 
    3763        { 
    38             // don't add twice 
    39             if (target->ir.irStruct->interfaceMap.find(bc->base) == target->ir.irStruct->interfaceMap.end()) 
    40             { 
    41                 Logger::println("adding interface '%s'", bc->base->toPrettyChars()); 
    42                 IrInterface* iri = new IrInterface(bc); 
    43  
    44                 // add to map 
    45                 target->ir.irStruct->interfaceMap.insert(std::make_pair(bc->base, iri)); 
    46                 // add to ordered list 
    47                 target->ir.irStruct->interfaceVec.push_back(iri); 
    48  
    49                 // Fill in vtbl[] 
    50                 if (!target->isAbstract()) { 
    51                     bc->fillVtbl(target, &bc->vtbl, 0); 
    52                 } 
    53             } 
     64            irstruct->interfaceMap.insert(std::make_pair(bc->base, iri)); 
    5465        } 
    5566    } 
    56 
    57  
    58 ////////////////////////////////////////////////////////////////////////////////////////// 
    59  
    60 static void LLVM_AddBaseClassData(IrStruct* irstruct, BaseClasses* bcs) 
    61 
    62     // add base class data members first 
    63     for (int j=0; j<bcs->dim; j++) 
    64     { 
    65         BaseClass* bc = (BaseClass*)(bcs->data[j]); 
    66  
    67         // interfaces never add data fields 
    68         if (bc->base->isInterfaceDeclaration()) 
    69             continue; 
    70  
    71         // recursively add baseclass data 
    72         LLVM_AddBaseClassData(irstruct, &bc->base->baseclasses); 
    73  
    74         Array* arr = &bc->base->fields; 
    75         if (arr->dim == 0) 
    76             continue; 
    77  
    78         Logger::println("Adding base class members of %s", bc->base->toChars()); 
    79         LOG_SCOPE; 
    80  
    81         for (int k=0; k < arr->dim; k++) { 
    82             VarDeclaration* v = (VarDeclaration*)(arr->data[k]); 
    83             Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); 
    84             // init fields, used to happen in VarDeclaration::toObjFile 
    85             irstruct->addField(v); 
     67 
     68    // build the interface vtable 
     69    b->fillVtbl(target, &b->vtbl, newinstance); 
     70 
     71    // add the vtable type 
     72    assert(inter->type->ir.type); 
     73    irstruct->types.push_back( inter->type->ir.type->get() ); 
     74    // set and increment index 
     75    iri->index = irstruct->index++; 
     76
     77 
     78static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd) 
     79
     80    Logger::println("Adding data from class: %s", cd->toChars()); 
     81    LOG_SCOPE; 
     82 
     83    // recurse into baseClasses 
     84    if (cd->baseClass) 
     85    { 
     86        add_class_data(target, cd->baseClass); 
     87        //offset = baseClass->structsize; 
     88    } 
     89 
     90    // add members 
     91    Array* arr = cd->members; 
     92    for (int k=0; k < arr->dim; k++) { 
     93        Dsymbol* s = (Dsymbol*)arr->data[k]; 
     94        s->toObjFile(0); 
     95    } 
     96 
     97    // add interfaces 
     98    if (cd->vtblInterfaces) 
     99    { 
     100        Logger::println("num vtbl interfaces: %u", cd->vtblInterfaces->dim); 
     101        for (int i = 0; i < cd->vtblInterfaces->dim; i++) 
     102        { 
     103            BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; 
     104            assert(b); 
     105            // create new instances only for explicitly derived interfaces 
     106            add_interface(target, b, (cd == target)); 
    86107        } 
    87108    } 
     
    90111////////////////////////////////////////////////////////////////////////////////////////// 
    91112 
    92 void DtoResolveClass(ClassDeclaration* cd) 
     113static void DtoResolveInterface(InterfaceDeclaration* cd) 
    93114{ 
    94115    if (cd->ir.resolved) return; 
    95116    cd->ir.resolved = true; 
    96117 
    97     Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 
     118    Logger::println("DtoResolveInterface(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 
    98119    LOG_SCOPE; 
    99  
    100     //printf("resolve class: %s\n", cd->toPrettyChars()); 
    101120 
    102121    // get the TypeClass 
     
    104123    TypeClass* ts = (TypeClass*)cd->type; 
    105124 
    106     // make sure the IrStruct is created 
    107     IrStruct* irstruct = cd->ir.irStruct; 
    108     if (!irstruct) { 
    109         irstruct = new IrStruct(ts); 
    110         cd->ir.irStruct = irstruct; 
     125    // create the IrStruct, we need somewhere to store the classInfo 
     126    assert(!cd->ir.irStruct); 
     127    IrStruct* irstruct = new IrStruct(cd); 
     128    cd->ir.irStruct = irstruct; 
     129 
     130    // handle base interfaces 
     131    if (cd->baseclasses.dim) 
     132    { 
     133        Logger::println("num baseclasses: %u", cd->baseclasses.dim); 
     134        LOG_SCOPE; 
     135 
     136        for (int i=0; i<cd->baseclasses.dim; i++) 
     137        { 
     138            BaseClass* bc = (BaseClass*)cd->baseclasses.data[i]; 
     139            Logger::println("baseclass %d: %s", i, bc->base->toChars()); 
     140 
     141            InterfaceDeclaration* id = bc->base->isInterfaceDeclaration(); 
     142            assert(id); 
     143 
     144            DtoResolveInterface(id); 
     145     
     146            // add to interfaceInfos 
     147            IrInterface* iri = new IrInterface(bc); 
     148            irstruct->interfaceVec.push_back(iri); 
     149        } 
     150    } 
     151 
     152    // create the type 
     153    const LLType* t = LLArrayType::get(getVoidPtrType(), cd->vtbl.dim); 
     154    assert(!ts->ir.type); 
     155    ts->ir.type = new LLPATypeHolder(getPtrToType(t)); 
     156 
     157    // request declaration 
     158    gIR->declareList.push_back(cd); 
     159 
     160    // handle members 
     161    // like "nested" interfaces 
     162    Array* arr = cd->members; 
     163    for (int k=0; k < arr->dim; k++) { 
     164        Dsymbol* s = (Dsymbol*)arr->data[k]; 
     165        s->toObjFile(0); 
     166    } 
     167
     168 
     169////////////////////////////////////////////////////////////////////////////////////////// 
     170 
     171// FIXME: this needs to be cleaned up 
     172 
     173void DtoResolveClass(ClassDeclaration* cd) 
     174
     175    if (InterfaceDeclaration* id = cd->isInterfaceDeclaration()) 
     176    { 
     177        DtoResolveInterface(id); 
     178        return; 
     179    } 
     180 
     181    if (cd->ir.resolved) return; 
     182    cd->ir.resolved = true; 
     183 
     184    Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 
     185    LOG_SCOPE; 
     186 
     187    //printf("resolve class: %s\n", cd->toPrettyChars()); 
     188 
     189    // get the TypeClass 
     190    assert(cd->type->ty == Tclass); 
     191    TypeClass* ts = (TypeClass*)cd->type; 
     192 
     193    // create the IrStruct 
     194    assert(!cd->ir.irStruct); 
     195    IrStruct* irstruct = new IrStruct(cd); 
     196    cd->ir.irStruct = irstruct; 
     197 
     198    // create the type 
     199    ts->ir.type = new LLPATypeHolder(llvm::OpaqueType::get()); 
     200 
     201    // if it just a forward declaration? 
     202    if (cd->sizeok != 1) 
     203    { 
     204        // just name the type 
     205        gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 
     206        return; 
    111207    } 
    112208 
     
    116212    } 
    117213 
    118     // resolve interface vtables 
    119     /*if (cd->vtblInterfaces) { 
    120         Logger::println("Vtbl interfaces for '%s'", cd->toPrettyChars()); 
    121         LOG_SCOPE; 
    122         for (int i=0; i < cd->vtblInterfaces->dim; i++) { 
    123             BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; 
    124             ClassDeclaration *id = b->base; 
    125             Logger::println("Vtbl interface: '%s'", id->toPrettyChars()); 
    126             DtoResolveClass(id); 
    127             // Fill in vtbl[] 
    128             b->fillVtbl(cd, &b->vtbl, 1); 
    129         } 
    130     }*/ 
    131  
    132214    // push state 
    133215    gIR->structs.push_back(irstruct); 
    134     gIR->classes.push_back(cd); 
    135  
    136     // vector holding the field types 
    137     std::vector<const LLType*> fieldtypes; 
    138216 
    139217    // add vtable 
    140     ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); 
    141     const LLType* vtabty = getPtrToType(ts->ir.vtblType->get()); 
    142     fieldtypes.push_back(vtabty); 
     218    irstruct->types.push_back(getPtrToType(irstruct->vtblTy.get())); 
     219    irstruct->index++; 
    143220 
    144221    // add monitor 
    145     fieldtypes.push_back(getVoidPtrType()); 
    146  
    147     // add base class data fields first 
    148     LLVM_AddBaseClassData(irstruct, &cd->baseclasses); 
    149  
    150     // add own fields 
    151     Array* fields = &cd->fields; 
    152     for (int k=0; k < fields->dim; k++) 
    153     { 
    154         VarDeclaration* v = (VarDeclaration*)fields->data[k]; 
    155         Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); 
    156         // init fields, used to happen in VarDeclaration::toObjFile 
    157         irstruct->addField(v); 
    158     } 
    159  
    160     // then add other members of us, if any 
    161     if(cd->members) { 
    162         for (int k=0; k < cd->members->dim; k++) { 
    163             Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]); 
    164             dsym->toObjFile(0); // TODO: multiobj 
    165         } 
    166     } 
    167  
    168     // resolve class data fields (possibly unions) 
    169     Logger::println("doing class fields"); 
    170  
    171     if (irstruct->offsets.empty()) 
    172     { 
    173         Logger::println("has no fields"); 
    174     } 
    175     else 
    176     { 
    177         Logger::println("has fields"); 
    178         unsigned prevsize = (unsigned)-1; 
    179         unsigned lastoffset = (unsigned)-1; 
    180         const LLType* fieldtype = NULL; 
    181         VarDeclaration* fieldinit = NULL; 
    182         size_t fieldpad = 0; 
    183         int idx = 0; 
    184         for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 
    185             // first iteration 
    186             if (lastoffset == (unsigned)-1) { 
    187                 lastoffset = i->first; 
    188                 fieldtype = i->second.type; 
    189                 fieldinit = i->second.var; 
    190                 prevsize = getABITypeSize(fieldtype); 
    191                 i->second.var->ir.irField->index = idx; 
    192             } 
    193             // colliding offset? 
    194             else if (lastoffset == i->first) { 
    195                 size_t s = getABITypeSize(i->second.type); 
    196                 if (s > prevsize) { 
    197                     fieldpad += s - prevsize; 
    198                     prevsize = s; 
    199                 } 
    200                 cd->ir.irStruct->hasUnions = true; 
    201                 i->second.var->ir.irField->index = idx; 
    202             } 
    203             // intersecting offset? 
    204             else if (i->first < (lastoffset + prevsize)) { 
    205                 size_t s = getABITypeSize(i->second.type); 
    206                 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size 
    207                 cd->ir.irStruct->hasUnions = true; 
    208                 i->second.var->ir.irField->index = idx; 
    209                 i->second.var->ir.irField->indexOffset = (i->first - lastoffset) / s; 
    210             } 
    211             // fresh offset 
    212             else { 
    213                 // commit the field 
    214                 fieldtypes.push_back(fieldtype); 
    215                 irstruct->defaultFields.push_back(fieldinit); 
    216                 if (fieldpad) { 
    217                     fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad)); 
    218                     irstruct->defaultFields.push_back(NULL); 
    219                     idx++; 
    220                 } 
    221  
    222                 idx++; 
    223  
    224                 // start new 
    225                 lastoffset = i->first; 
    226                 fieldtype = i->second.type; 
    227                 fieldinit = i->second.var; 
    228                 prevsize = getABITypeSize(fieldtype); 
    229                 i->second.var->ir.irField->index = idx; 
    230                 fieldpad = 0; 
    231             } 
    232         } 
    233         fieldtypes.push_back(fieldtype); 
    234         irstruct->defaultFields.push_back(fieldinit); 
    235         if (fieldpad) { 
    236             fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad)); 
    237             irstruct->defaultFields.push_back(NULL); 
    238         } 
    239     } 
    240  
    241     // populate interface map 
    242     { 
    243         Logger::println("Adding interfaces to '%s'", cd->toPrettyChars()); 
    244         LOG_SCOPE; 
    245         LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses); 
    246         Logger::println("%d interfaces added", cd->ir.irStruct->interfaceVec.size()); 
    247         assert(cd->ir.irStruct->interfaceVec.size() == cd->ir.irStruct->interfaceMap.size()); 
    248     } 
    249  
    250     // add interface vtables at the end 
    251     int interIdx = (int)fieldtypes.size(); 
    252     for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 
    253     { 
    254         IrInterface* iri = *i; 
    255         ClassDeclaration* id = iri->decl; 
    256  
    257         // set vtbl type 
    258         TypeClass* itc = (TypeClass*)id->type; 
    259         const LLType* ivtblTy = itc->ir.vtblType->get(); 
    260         assert(ivtblTy); 
    261         if (Logger::enabled()) 
    262             Logger::cout() << "interface vtbl type: " << *ivtblTy << '\n'; 
    263         fieldtypes.push_back(getPtrToType(ivtblTy)); 
    264  
    265         // fix the interface vtable type 
    266         assert(iri->vtblTy == NULL); 
    267         iri->vtblTy = new llvm::PATypeHolder(ivtblTy); 
    268  
    269         // set index 
    270         iri->index = interIdx++; 
    271     } 
    272     Logger::println("%d interface vtables added", cd->ir.irStruct->interfaceVec.size()); 
    273     assert(cd->ir.irStruct->interfaceVec.size() == cd->ir.irStruct->interfaceMap.size()); 
     222    irstruct->types.push_back(getVoidPtrType()); 
     223    irstruct->index++; 
     224 
     225    // add class data fields and interface vtables recursively 
     226    add_class_data(cd, cd); 
     227 
     228    // check if errors occured while building interface vtables 
     229    if (global.errors) 
     230        fatal(); 
    274231 
    275232    // create type 
    276     const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); 
     233    assert(irstruct->index == irstruct->types.size()); 
     234    const LLType* structtype = irstruct->build(); 
    277235 
    278236    // refine abstract types for stuff like: class C {C next;} 
    279     assert(irstruct->recty != 0); 
    280     llvm::PATypeHolder& spa = irstruct->recty; 
    281     llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); 
    282     structtype = isaStruct(spa.get()); 
    283  
    284     // make it official 
    285     if (!ts->ir.type) 
    286         ts->ir.type = new llvm::PATypeHolder(structtype); 
    287     else 
    288         *ts->ir.type = structtype; 
    289     spa = *ts->ir.type; 
     237    llvm::PATypeHolder* spa = ts->ir.type; 
     238    llvm::cast<llvm::OpaqueType>(spa->get())->refineAbstractTypeTo(structtype); 
     239    structtype = isaStruct(spa->get()); 
    290240 
    291241    // name the type 
    292242    gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 
    293243 
    294     // create vtable type 
    295     llvm::GlobalVariable* svtblVar = 0; 
    296 #if OPAQUE_VTBLS 
     244    // refine vtable type 
     245 
    297246    // void*[vtbl.dim] 
    298     const llvm::ArrayType* svtbl_ty 
    299         = llvm::ArrayType::get(getVoidPtrType(), cd->vtbl.dim); 
    300  
    301 #else 
    302     std::vector<const LLType*> sinits_ty; 
    303  
    304     for (int k=0; k < cd->vtbl.dim; k++) 
    305     { 
    306         Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; 
    307         assert(dsym); 
    308         //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; 
    309  
    310         if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 
    311             DtoResolveFunction(fd); 
    312             //assert(fd->type->ty == Tfunction); 
    313             //TypeFunction* tf = (TypeFunction*)fd->type; 
    314             //const LLType* fpty = getPtrToType(tf->ir.type->get()); 
    315             const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); 
    316             const LLType* vfpty = getPtrToType(vfty); 
    317             sinits_ty.push_back(vfpty); 
    318         } 
    319         else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { 
    320             Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars()); 
    321             const LLType* cinfoty; 
    322             if (cd->isInterfaceDeclaration()) { 
    323                 cinfoty = DtoInterfaceInfoType(); 
    324             } 
    325             else if (cd != ClassDeclaration::classinfo) { 
    326                 cinfoty = ClassDeclaration::classinfo->type->ir.type->get(); 
    327             } 
    328             else { 
    329                 // this is the ClassInfo class, the type is this type 
    330                 cinfoty = ts->ir.type->get(); 
    331             } 
    332             const LLType* cty = getPtrToType(cinfoty); 
    333             sinits_ty.push_back(cty); 
    334         } 
    335         else 
    336         assert(0); 
    337     } 
    338  
    339     // get type 
    340     assert(!sinits_ty.empty()); 
    341     const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty); 
    342 #endif 
    343  
    344     // refine for final vtable type 
    345     llvm::cast<llvm::OpaqueType>(ts->ir.vtblType->get())->refineAbstractTypeTo(svtbl_ty); 
    346  
    347 #if !OPAQUE_VTBLS 
    348     // name vtbl type 
    349     std::string styname(cd->mangle()); 
    350     styname.append("__vtblType"); 
    351     gIR->module->addTypeName(styname, svtbl_ty); 
    352 #endif 
     247    llvm::cast<llvm::OpaqueType>(irstruct->vtblTy.get())->refineAbstractTypeTo(LLArrayType::get(getVoidPtrType(), cd->vtbl.dim)); 
    353248 
    354249    // log 
    355     //Logger::cout() << "final class type: " << *ts->ir.type->get() << '\n'; 
     250    Logger::cout() << "final class type: " << *ts->ir.type->get() << '\n'; 
    356251 
    357252    // pop state 
    358     gIR->classes.pop_back(); 
    359253    gIR->structs.pop_back(); 
    360254 
     
    365259////////////////////////////////////////////////////////////////////////////////////////// 
    366260 
    367 void DtoDeclareClass(ClassDeclaration* cd) 
     261static void DtoDeclareInterface(InterfaceDeclaration* cd) 
    368262{ 
    369263    if (cd->ir.declared) return; 
    370264    cd->ir.declared = true; 
    371265 
    372     Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 
     266    Logger::println("DtoDeclareInterface(%s): %s", cd->toPrettyChars(), cd->locToChars()); 
     267    LOG_SCOPE; 
     268 
     269    assert(cd->ir.irStruct); 
     270    IrStruct* irstruct = cd->ir.irStruct; 
     271 
     272    // get interface info type 
     273    const llvm::StructType* infoTy = DtoInterfaceInfoType(); 
     274 
     275    // interface info array 
     276    if (!irstruct->interfaceVec.empty()) { 
     277        // symbol name 
     278        std::string nam = "_D"; 
     279        nam.append(cd->mangle()); 
     280        nam.append("16__interfaceInfosZ"); 
     281 
     282        llvm::GlobalValue::LinkageTypes linkage = DtoLinkage(cd); 
     283 
     284        // resolve array type 
     285        const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, irstruct->interfaceVec.size()); 
     286  &