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

Changeset 1650:40bd4a0d4870

Show
Ignore:
Timestamp:
05/19/10 06:42:32 (2 years ago)
Author:
Tomas Lindquist Olsen
branch:
default
Message:

Update to work with LLVM 2.7.

Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).

Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.

Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.

Files:

Legend:

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

    Revision 1630:44b145be2ef5 Revision 1650:40bd4a0d4870
    39struct TemplateInstance; 39struct TemplateInstance; 
    40struct TemplateDeclaration; 40struct TemplateDeclaration; 
    41struct ClassDeclaration; 41struct ClassDeclaration; 
    42struct HdrGenState; 42struct HdrGenState; 
    43struct BinExp; 43struct BinExp; 
      44struct AssignExp; 
    44struct InterState; 45struct InterState; 
    45struct OverloadSet; 46struct OverloadSet; 
    46 47 
    47enum TOK; 48enum TOK; 
    48 49 
      
    175    virtual DValue* toElem(IRState* irs); 176    virtual DValue* toElem(IRState* irs); 
    176    virtual llvm::Constant *toConstElem(IRState *irs); 177    virtual llvm::Constant *toConstElem(IRState *irs); 
    177    virtual void cacheLvalue(IRState* irs); 178    virtual void cacheLvalue(IRState* irs); 
    178 179 
    179    llvm::Value* cachedLvalue; 180    llvm::Value* cachedLvalue; 
      181 
      182    virtual AssignExp* isAssignExp() { return NULL; } 
    180#endif 183#endif 
    181}; 184}; 
    182 185 
    183struct IntegerExp : Expression 186struct IntegerExp : Expression 
    184{ 187{ 
      
    1376#endif 1379#endif 
    1377 1380 
    1378#if IN_LLVM 1381#if IN_LLVM 
    1379    DValue* toElem(IRState* irs); 1382    DValue* toElem(IRState* irs); 
    1380#endif 1383#endif 
      1384 
      1385    AssignExp* isAssignExp() { return this; } 
    1381}; 1386}; 
    1382 1387 
    1383#if IN_DMD 1388#if IN_DMD 
    1384#define ASSIGNEXP_TOELEM    elem *toElem(IRState *irs); 1389#define ASSIGNEXP_TOELEM    elem *toElem(IRState *irs); 
    1385#elif IN_LLVM 1390#elif IN_LLVM 
  • dmd/statement.h

    Revision 1630:44b145be2ef5 Revision 1650:40bd4a0d4870
    139    virtual DeclarationStatement *isDeclarationStatement() { return NULL; } 139    virtual DeclarationStatement *isDeclarationStatement() { return NULL; } 
    140    virtual CompoundStatement *isCompoundStatement() { return NULL; } 140    virtual CompoundStatement *isCompoundStatement() { return NULL; } 
    141    virtual ReturnStatement *isReturnStatement() { return NULL; } 141    virtual ReturnStatement *isReturnStatement() { return NULL; } 
    142    virtual IfStatement *isIfStatement() { return NULL; } 142    virtual IfStatement *isIfStatement() { return NULL; } 
    143    virtual CaseStatement* isCaseStatement() { return NULL; } 143    virtual CaseStatement* isCaseStatement() { return NULL; } 
      144    virtual LabelStatement* isLabelStatement() { return NULL; } 
    144 145 
    145#if IN_LLVM 146#if IN_LLVM 
    146    virtual void toNakedIR(IRState *irs); 147    virtual void toNakedIR(IRState *irs); 
    147    virtual AsmBlockStatement* endsWithAsm(); 148    virtual AsmBlockStatement* endsWithAsm(); 
    148#endif 149#endif 
      
    861    void toIR(IRState *irs); 862    void toIR(IRState *irs); 
    862 863 
    863    // LDC 864    // LDC 
    864    bool asmLabel;       // for labels inside inline assembler 865    bool asmLabel;       // for labels inside inline assembler 
    865    void toNakedIR(IRState *irs); 866    void toNakedIR(IRState *irs); 
      867 
      868    LabelStatement* isLabelStatement() { return this; } 
    866}; 869}; 
    867 870 
    868struct LabelDsymbol : Dsymbol 871struct LabelDsymbol : Dsymbol 
    869{ 872{ 
    870    LabelStatement *statement; 873    LabelStatement *statement; 
  • gen/arrays.cpp

    Revision 1643:8f121883bce8 Revision 1650:40bd4a0d4870
    307            mismatch = true; 307            mismatch = true; 
    308    } 308    } 
    309 309 
    310    LLConstant* constarr; 310    LLConstant* constarr; 
    311    if (mismatch) 311    if (mismatch) 
    312        constarr = LLConstantStruct::get(gIR->context(), initvals); 312        constarr = LLConstantStruct::get(gIR->context(), initvals, false); // FIXME should this pack? 
    313    else 313    else 
    314        constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals); 314        constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals); 
    315 315 
    316//     std::cout << "constarr: " << *constarr << std::endl; 316//     std::cout << "constarr: " << *constarr << std::endl; 
    317 317 
      
    392 392 
    393////////////////////////////////////////////////////////////////////////////////////////// 393////////////////////////////////////////////////////////////////////////////////////////// 
    394LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) 394LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) 
    395{ 395{ 
    396    LLConstant* values[2] = { dim, ptr }; 396    LLConstant* values[2] = { dim, ptr }; 
    397    return LLConstantStruct::get(gIR->context(), values, 2); 397    return LLConstantStruct::get(gIR->context(), values, 2, false); 
    398} 398} 
    399 399 
    400////////////////////////////////////////////////////////////////////////////////////////// 400////////////////////////////////////////////////////////////////////////////////////////// 
    401static bool isInitialized(Type* et) { 401static bool isInitialized(Type* et) { 
    402    // Strip static array types from element type 402    // Strip static array types from element type 
  • gen/asmstmt.cpp

    Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870
    194 194 
    195    // get asm block 195    // get asm block 
    196    IRAsmBlock* asmblock = irs->asmBlock; 196    IRAsmBlock* asmblock = irs->asmBlock; 
    197    assert(asmblock); 197    assert(asmblock); 
    198 198 
      199    #ifndef DISABLE_DEBUG_INFO 
    199    // debug info 200    // debug info 
    200    if (global.params.symdebug) 201    if (global.params.symdebug) 
    201        DtoDwarfStopPoint(loc.linnum); 202        DtoDwarfStopPoint(loc.linnum); 
      203    #endif 
    202 204 
    203    if (! asmcode) 205    if (! asmcode) 
    204    return; 206    return; 
    205 207 
    206    static std::string i_cns = "i"; 208    static std::string i_cns = "i"; 
      
    255        default: assert(0); break; 257        default: assert(0); break; 
    256        } 258        } 
    257        break; 259        break; 
    258    case Arg_FrameRelative: 260    case Arg_FrameRelative: 
    259// FIXME 261// FIXME 
    260llvm::cout << "asm fixme Arg_FrameRelative" << std::endl; 262assert(0 && "asm fixme Arg_FrameRelative"); 
    261assert(0);   
    262/*      if (arg->expr->op == TOKvar) 263/*      if (arg->expr->op == TOKvar) 
    263        arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; 264        arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; 
    264        else 265        else 
    265        assert(0); 266        assert(0); 
    266        if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { 267        if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { 
      
    273        if (arg->mode != Mode_Input) 274        if (arg->mode != Mode_Input) 
    274        clobbers_mem = true; 275        clobbers_mem = true; 
    275        break;*/ 276        break;*/ 
    276    case Arg_LocalSize: 277    case Arg_LocalSize: 
    277// FIXME 278// FIXME 
    278llvm::cout << "asm fixme Arg_LocalSize" << std::endl; 279assert(0 && "asm fixme Arg_LocalSize"); 
    279assert(0);   
    280/*      var_frame_offset = cfun->x_frame_offset; 280/*      var_frame_offset = cfun->x_frame_offset; 
    281        if (var_frame_offset < 0) 281        if (var_frame_offset < 0) 
    282        var_frame_offset = - var_frame_offset; 282        var_frame_offset = - var_frame_offset; 
    283        arg_val = irs->integerConstant( var_frame_offset );*/ 283        arg_val = irs->integerConstant( var_frame_offset );*/ 
    284        goto do_integer; 284        goto do_integer; 
  • gen/cl_helpers.cpp

    Revision 1103:b30fe7e1dbb9 Revision 1650:40bd4a0d4870
    15    if (isupper(c)) 15    if (isupper(c)) 
    16        return tolower(c); 16        return tolower(c); 
    17    return c; 17    return c; 
    18} 18} 
    19 19 
    20bool FlagParser::parse(cl::Option &O, const char *ArgName, const std::string &Arg, bool &Val) { 20bool FlagParser::parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef Arg, bool &Val) { 
    21    // Make a std::string out of it to make comparisons easier 21    // Make a std::string out of it to make comparisons easier 
    22    // (and avoid repeated conversion) 22    // (and avoid repeated conversion) 
    23    std::string argname = ArgName; 23    llvm::StringRef argname = ArgName; 
    24     24 
    25    typedef std::vector<std::pair<std::string, bool> >::iterator It; 25    typedef std::vector<std::pair<std::string, bool> >::iterator It; 
    26    for (It I = switches.begin(), E = switches.end(); I != E; ++I) { 26    for (It I = switches.begin(), E = switches.end(); I != E; ++I) { 
    27        std::string name = I->first; 27        llvm::StringRef name = I->first; 
    28        if (name == argname 28        if (name == argname 
    29                || (name.length() < argname.length() 29                || (name.size() < argname.size() 
    30                    && argname.substr(0, name.length()) == name 30                    && argname.substr(0, name.size()) == name 
    31                    && argname[name.length()] == '=')) { 31                    && argname[name.size()] == '=')) { 
    32             32 
    33            if (!cl::parser<bool>::parse(O, ArgName, Arg, Val)) { 33            if (!cl::parser<bool>::parse(O, ArgName, Arg, Val)) { 
    34                Val = (Val == I->second); 34                Val = (Val == I->second); 
    35                return false; 35                return false; 
    36            } 36            } 
    37            // Invalid option value 37            // Invalid option value 
      
    39        } 39        } 
    40    } 40    } 
    41    return true; 41    return true; 
    42} 42} 
    43 43 
    44void FlagParser::getExtraOptionNames(std::vector<const char*> &Names) { 44void FlagParser::getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names) { 
    45    typedef std::vector<std::pair<std::string, bool> >::iterator It; 45    typedef std::vector<std::pair<std::string, bool> >::iterator It; 
    46    for (It I = switches.begin() + 1, E = switches.end(); I != E; ++I) { 46    for (It I = switches.begin() + 1, E = switches.end(); I != E; ++I) { 
    47        Names.push_back(I->first.c_str()); 47        Names.push_back(I->first.data()); 
    48    } 48    } 
    49} 49} 
    50 50 
    51 51 
    52MultiSetter::MultiSetter(bool invert, bool* p, ...) { 52MultiSetter::MultiSetter(bool invert, bool* p, ...) { 
  • gen/cl_helpers.h

    Revision 1200:3171f67ad006 Revision 1650:40bd4a0d4870
    19        void initialize(Opt &O) { 19        void initialize(Opt &O) { 
    20            std::string Name = O.ArgStr; 20            std::string Name = O.ArgStr; 
    21            switches.push_back(make_pair("enable-" + Name, true)); 21            switches.push_back(make_pair("enable-" + Name, true)); 
    22            switches.push_back(make_pair("disable-" + Name, false)); 22            switches.push_back(make_pair("disable-" + Name, false)); 
    23            // Replace <foo> with -enable-<foo> 23            // Replace <foo> with -enable-<foo> 
    24            O.ArgStr = switches[0].first.c_str(); 24            O.ArgStr = switches[0].first.data(); 
    25        } 25        } 
    26         26 
    27        bool parse(cl::Option &O, const char *ArgName, const std::string &ArgValue, bool &Val); 27        bool parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef ArgValue, bool &Val); 
    28         28 
    29        void getExtraOptionNames(std::vector<const char*> &Names); 29        void getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names); 
    30    }; 30    }; 
    31     31 
    32    /// Helper class for options that set multiple flags 32    /// Helper class for options that set multiple flags 
    33    class MultiSetter { 33    class MultiSetter { 
    34        std::vector<bool*> locations; 34        std::vector<bool*> locations; 
  • gen/configfile.cpp

    Revision 1537:ee6b20e7aedb Revision 1650:40bd4a0d4870
    107        std::cerr << "Error failed to locate the configuration file: " << filename << std::endl; 107        std::cerr << "Error failed to locate the configuration file: " << filename << std::endl; 
    108        return false; 108        return false; 
    109    } 109    } 
    110 110 
    111    // save config file path for -v output 111    // save config file path for -v output 
    112    pathstr = p.toString(); 112    pathstr = p.str(); 
    113 113 
    114    try 114    try 
    115    { 115    { 
    116        // read the cfg 116        // read the cfg 
    117        cfg->readFile(p.c_str()); 117        cfg->readFile(p.c_str()); 
  • gen/functions.cpp

    Revision 1607:207a8a438dea Revision 1650:40bd4a0d4870
    597    { 597    { 
    598        DtoDefineNakedFunction(fd); 598        DtoDefineNakedFunction(fd); 
    599        return; 599        return; 
    600    } 600    } 
    601 601 
      602    #ifndef DISABLE_DEBUG_INFO 
    602    // debug info 603    // debug info 
    603    if (global.params.symdebug) { 604    if (global.params.symdebug) 
    604        fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd); 605        fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd); 
    605    } 606    #endif 
    606 607 
    607    Type* t = fd->type->toBasetype(); 608    Type* t = fd->type->toBasetype(); 
    608    TypeFunction* f = (TypeFunction*)t; 609    TypeFunction* f = (TypeFunction*)t; 
    609    assert(f->irtype); 610    assert(f->irtype); 
    610 611 
      
    640    // create alloca point 641    // create alloca point 
    641    // this gets erased when the function is complete, so alignment etc does not matter at all 642    // this gets erased when the function is complete, so alignment etc does not matter at all 
    642    llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb); 643    llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb); 
    643    irfunction->allocapoint = allocaPoint; 644    irfunction->allocapoint = allocaPoint; 
    644 645 
      646    #ifndef DISABLE_DEBUG_INFO 
    645    // debug info - after all allocas, but before any llvm.dbg.declare etc 647    // debug info - after all allocas, but before any llvm.dbg.declare etc 
    646    if (global.params.symdebug) DtoDwarfFuncStart(fd); 648    if (global.params.symdebug) DtoDwarfFuncStart(fd); 
      649    #endif 
    647 650 
    648    // this hack makes sure the frame pointer elimination optimization is disabled. 651    // this hack makes sure the frame pointer elimination optimization is disabled. 
    649    // this this eliminates a bunch of inline asm related issues. 652    // this this eliminates a bunch of inline asm related issues. 
    650    if (fd->inlineAsm) 653    if (fd->inlineAsm) 
    651    { 654    { 
      
    666 669 
    667        assert(!fd->vthis->ir.irLocal); 670        assert(!fd->vthis->ir.irLocal); 
    668        fd->vthis->ir.irLocal = new IrLocal(fd->vthis); 671        fd->vthis->ir.irLocal = new IrLocal(fd->vthis); 
    669        fd->vthis->ir.irLocal->value = thismem; 672        fd->vthis->ir.irLocal->value = thismem; 
    670 673 
      674        #ifndef DISABLE_DEBUG_INFO 
    671        if (global.params.symdebug) 675        if (global.params.symdebug) 
    672            DtoDwarfLocalVariable(thismem, fd->vthis); 676            DtoDwarfLocalVariable(thismem, fd->vthis); 
      677        #endif 
    673 678 
    674    #if DMDV1 679    #if DMDV1 
    675        if (fd->vthis->nestedref) 680        if (fd->vthis->nestedref) 
    676        { 681        { 
    677            fd->nestedVars.insert(fd->vthis); 682            fd->nestedVars.insert(fd->vthis); 
      
    720 725 
    721                // set the arg var value to the alloca 726                // set the arg var value to the alloca 
    722                irloc->value = mem; 727                irloc->value = mem; 
    723            } 728            } 
    724 729 
      730            #ifndef DISABLE_DEBUG_INFO 
    725            if (global.params.symdebug && !(isaArgument(irloc->value) && !isaArgument(irloc->value)->hasByValAttr()) && !refout) 731            if (global.params.symdebug && !(isaArgument(irloc->value) && !isaArgument(irloc->value)->hasByValAttr()) && !refout) 
    726                DtoDwarfLocalVariable(irloc->value, vd); 732                DtoDwarfLocalVariable(irloc->value, vd); 
      733            #endif 
    727        } 734        } 
    728    } 735    } 
    729 736 
    730// need result variable? (nested) 737// need result variable? (nested) 
    731#if DMDV1 738#if DMDV1 
      
    794    } else if (!gIR->scopereturned()) { 801    } else if (!gIR->scopereturned()) { 
    795        // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 802        // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 
    796        // in automatically, so we do it here. 803        // in automatically, so we do it here. 
    797         804 
    798        // pass the previous block into this block 805        // pass the previous block into this block 
      806        #ifndef DISABLE_DEBUG_INFO 
    799        if (global.params.symdebug) DtoDwarfFuncEnd(fd); 807        if (global.params.symdebug) DtoDwarfFuncEnd(fd); 
      808        #endif 
    800        if (func->getReturnType() == LLType::getVoidTy(gIR->context())) { 809        if (func->getReturnType() == LLType::getVoidTy(gIR->context())) { 
    801            llvm::ReturnInst::Create(gIR->context(), gIR->scopebb()); 810            llvm::ReturnInst::Create(gIR->context(), gIR->scopebb()); 
    802        } 811        } 
    803        else if (!fd->isMain()) { 812        else if (!fd->isMain()) { 
    804            AsmBlockStatement* asmb = fd->fbody->endsWithAsm(); 813            AsmBlockStatement* asmb = fd->fbody->endsWithAsm(); 
  • gen/linker.cpp

    Revision 1600:a60e7d1ce3ee Revision 1650:40bd4a0d4870
    220    std::string errstr; 220    std::string errstr; 
    221 221 
    222    // find gcc for linking 222    // find gcc for linking 
    223    llvm::sys::Path gcc = getGcc(); 223    llvm::sys::Path gcc = getGcc(); 
    224    // get a string version for argv[0] 224    // get a string version for argv[0] 
    225    std::string gccStr = gcc.toString(); 225    const char* gccStr = gcc.c_str(); 
    226 226 
    227    // build arguments 227    // build arguments 
    228    std::vector<const char*> args; 228    std::vector<const char*> args; 
    229 229 
    230    // first the program name ?? 230    // first the program name ?? 
    231    args.push_back(gccStr.c_str()); 231    args.push_back(gccStr); 
    232 232 
    233    // object files 233    // object files 
    234    for (int i = 0; i < global.params.objfiles->dim; i++) 234    for (int i = 0; i < global.params.objfiles->dim; i++) 
    235    { 235    { 
    236        char *p = (char *)global.params.objfiles->data[i]; 236        char *p = (char *)global.params.objfiles->data[i]; 
      
    333    std::vector<const char*>::const_iterator I = args.begin(), E = args.end();  333    std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); 
    334    Stream logstr = Logger::cout(); 334    Stream logstr = Logger::cout(); 
    335    for (; I != E; ++I) 335    for (; I != E; ++I) 
    336        if (*I) 336        if (*I) 
    337            logstr << "'" << *I << "'" << " "; 337            logstr << "'" << *I << "'" << " "; 
    338    logstr << "\n" << std::flush; 338    logstr << "\n"; // FIXME where's flush ? 
    339 339 
    340 340 
    341    // terminate args list 341    // terminate args list 
    342    args.push_back(NULL); 342    args.push_back(NULL); 
    343 343 
      
    373    assert(gExePath.isValid()); 373    assert(gExePath.isValid()); 
    374 374 
    375    // build arguments 375    // build arguments 
    376    std::vector<const char*> args; 376    std::vector<const char*> args; 
    377    // args[0] should be the name of the executable 377    // args[0] should be the name of the executable 
    378    args.push_back(gExePath.toString().c_str()); 378    args.push_back(gExePath.c_str()); 
    379    // Skip first argument to -run; it's a D source file. 379    // Skip first argument to -run; it's a D source file. 
    380    for (size_t i = 1, length = opts::runargs.size(); i < length; i++) 380    for (size_t i = 1, length = opts::runargs.size(); i < length; i++) 
    381    { 381    { 
    382        args.push_back(opts::runargs[i].c_str()); 382        args.push_back(opts::runargs[i].c_str()); 
    383    } 383    } 
  • gen/llvmhelpers.cpp

    Revision 1643:8f121883bce8 Revision 1650:40bd4a0d4870
    158    args.push_back(c); 158    args.push_back(c); 
    159 159 
    160    // call 160    // call 
    161    gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); 161    gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); 
    162 162 
      163    #ifndef DISABLE_DEBUG_INFO 
    163    // end debug info 164    // end debug info 
    164    if (global.params.symdebug) 165    if (global.params.symdebug) 
    165        DtoDwarfFuncEnd(gIR->func()->decl); 166        DtoDwarfFuncEnd(gIR->func()->decl); 
      167    #endif 
    166 168 
    167    // after assert is always unreachable 169    // after assert is always unreachable 
    168    gIR->ir->CreateUnreachable(); 170    gIR->ir->CreateUnreachable(); 
    169} 171} 
    170 172 
      
    266 268 
    267void DtoEnclosingHandlers(Loc loc, Statement* target) 269void DtoEnclosingHandlers(Loc loc, Statement* target) 
    268{ 270{ 
    269    // labels are a special case: they are not required to enclose the current scope 271    // labels are a special case: they are not required to enclose the current scope 
    270    // for them we use the enclosing scope handler as a reference point 272    // for them we use the enclosing scope handler as a reference point 
    271    LabelStatement* lblstmt = dynamic_cast<LabelStatement*>(target)273    LabelStatement* lblstmt = target ? target->isLabelStatement() : 0
    272    if (lblstmt) 274    if (lblstmt) 
    273        target = lblstmt->enclosingScopeExit; 275        target = lblstmt->enclosingScopeExit; 
    274 276 
    275    // figure out up until what handler we need to emit 277    // figure out up until what handler we need to emit 
    276    FuncGen::TargetScopeVec::reverse_iterator targetit = gIR->func()->gen->targetScopes.rbegin(); 278    FuncGen::TargetScopeVec::reverse_iterator targetit = gIR->func()->gen->targetScopes.rbegin(); 
      
    483    { 485    { 
    484        return new DNullValue(type, LLConstant::getNullValue(lltype)); 486        return new DNullValue(type, LLConstant::getNullValue(lltype)); 
    485    } 487    } 
    486 488 
    487    // unknown 489    // unknown 
    488    llvm::cout << "unsupported: null value for " << type->toChars() << '\n'490    error("unsupported: null value for %s", type->toChars())
    489    assert(0); 491    assert(0); 
    490    return 0; 492    return 0; 
    491 493 
    492} 494} 
    493 495 
      
    852#endif 854#endif 
    853        } 855        } 
    854 856 
    855        gvar->setInitializer(initVal); 857        gvar->setInitializer(initVal); 
    856 858 
      859        #ifndef DISABLE_DEBUG_INFO 
    857        // do debug info 860        // do debug info 
    858        if (global.params.symdebug) 861        if (global.params.symdebug) 
    859        { 862        { 
    860            LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV(); 863            LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV(); 
    861            // keep a reference so GDCE doesn't delete it ! 864            // keep a reference so GDCE doesn't delete it ! 
    862            gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType())); 865            gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType())); 
    863        } 866        } 
      867        #endif 
    864    } 868    } 
    865} 869} 
    866 870 
    867/****************************************************************************************/ 871/****************************************************************************************/ 
    868/*//////////////////////////////////////////////////////////////////////////////////////// 872/*//////////////////////////////////////////////////////////////////////////////////////// 
      
    904                    vd->ir.irLocal = new IrLocal(vd); 908                    vd->ir.irLocal = new IrLocal(vd); 
    905 909 
    906                ExpInitializer* ex = vd->init->isExpInitializer(); 910                ExpInitializer* ex = vd->init->isExpInitializer(); 
    907                assert(ex && "ref vars must have expression initializer"); 911                assert(ex && "ref vars must have expression initializer"); 
    908                assert(ex->exp); 912                assert(ex->exp); 
    909                AssignExp* as = dynamic_cast<AssignExp*>(ex->exp); 913                AssignExp* as = ex->exp->isAssignExp(); 
    910                assert(as && "ref vars must be initialized by an assign exp"); 914                assert(as && "ref vars must be initialized by an assign exp"); 
    911                vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal(); 915                vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal(); 
    912            } 916            } 
    913             917 
    914            // referenced by nested delegate? 918            // referenced by nested delegate? 
      
    935                    allocainst = DtoAlloca(vd->type, vd->toChars()); 939                    allocainst = DtoAlloca(vd->type, vd->toChars()); 
    936 940 
    937                //allocainst->setAlignment(vd->type->alignsize()); // TODO 941                //allocainst->setAlignment(vd->type->alignsize()); // TODO 
    938                vd->ir.irLocal->value = allocainst; 942                vd->ir.irLocal->value = allocainst; 
    939 943 
      944                #ifndef DISABLE_DEBUG_INFO 
    940                if (global.params.symdebug) 945                if (global.params.symdebug) 
    941                {   
    942                    DtoDwarfLocalVariable(allocainst, vd); 946                    DtoDwarfLocalVariable(allocainst, vd); 
    943                } 947                #endif 
    944            } 948            } 
    945            else 949            else 
    946            { 950            { 
    947                assert(vd->ir.irLocal->value); 951                assert(vd->ir.irLocal->value); 
    948            } 952            } 
      
    1050    // alloca if necessary 1054    // alloca if necessary 
    1051    LLValue* allocaval = NULL; 1055    LLValue* allocaval = NULL; 
    1052    if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value)) 1056    if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value)) 
    1053    { 1057    { 
    1054        addr = DtoAlloca(var->type, var->toChars()); 1058        addr = DtoAlloca(var->type, var->toChars()); 
    1055          1059  
       1060         #ifndef DISABLE_DEBUG_INFO 
    1056        // add debug info 1061        // add debug info 
    1057        if (global.params.symdebug) 1062        if (global.params.symdebug) 
    1058            DtoDwarfLocalVariable(addr, var); 1063            DtoDwarfLocalVariable(addr, var); 
    1059    }  1064         #endif 
    1060          1065     } 
       1066  
    1061    // referenced by nested function? 1067    // referenced by nested function? 
    1062#if DMDV2 1068#if DMDV2 
    1063    if (var->nestedrefs.dim) 1069    if (var->nestedrefs.dim) 
    1064#else 1070#else 
    1065    if (var->nestedref) 1071    if (var->nestedref) 
  • gen/llvmhelpers.h

    Revision 1643:8f121883bce8 Revision 1650:40bd4a0d4870
    154//////////////////////////////////////////// 154//////////////////////////////////////////// 
    155// gen/tocall.cpp stuff below 155// gen/tocall.cpp stuff below 
    156//////////////////////////////////////////// 156//////////////////////////////////////////// 
    157 157 
    158/// convert DMD calling conv to LLVM 158/// convert DMD calling conv to LLVM 
    159unsigned DtoCallingConv(Loc loc, LINK l); 159llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l); 
    160 160 
    161/// 161/// 
    162TypeFunction* DtoTypeFunction(DValue* fnval); 162TypeFunction* DtoTypeFunction(DValue* fnval); 
    163 163 
    164/// 164/// 
  • gen/logger.cpp

    Revision 1502:2292878925f4 Revision 1650:40bd4a0d4870
    10 10 
    11#include "llvm/Support/CommandLine.h" 11#include "llvm/Support/CommandLine.h" 
    12 12 
    13#include "llvm/GlobalValue.h" 13#include "llvm/GlobalValue.h" 
    14#include "llvm/Support/Casting.h" 14#include "llvm/Support/Casting.h" 
    15#include "llvm/Support/raw_ostream.h" 15#include "llvm/Support/raw_os_ostream.h" 
    16#include "llvm/Assembly/Writer.h" 16#include "llvm/Assembly/Writer.h" 
    17 17 
    18#include "gen/logger.h" 18#include "gen/logger.h" 
    19#include "gen/irstate.h" 19#include "gen/irstate.h" 
    20 20 
      
    25 25 
    26void Stream::writeValue(std::ostream& OS, const llvm::Value& V) { 26void Stream::writeValue(std::ostream& OS, const llvm::Value& V) { 
    27    // Constants don't always get their types pretty-printed. 27    // Constants don't always get their types pretty-printed. 
    28    // (Only treat non-global constants like this, so that e.g. global variables 28    // (Only treat non-global constants like this, so that e.g. global variables 
    29    // still get their initializers printed) 29    // still get their initializers printed) 
      30    llvm::raw_os_ostream raw(OS); 
    30    if (llvm::isa<llvm::Constant>(V) && !llvm::isa<llvm::GlobalValue>(V)) 31    if (llvm::isa<llvm::Constant>(V) && !llvm::isa<llvm::GlobalValue>(V)) 
    31        llvm::WriteAsOperand(OS, &V, true, gIR->module); 32        llvm::WriteAsOperand(raw, &V, true, gIR->module); 
    32    else 33    else 
    33        OS << V34        V.print(raw)
    34} 35} 
    35 36 
    36namespace Logger 37namespace Logger 
    37{ 38{ 
    38    static std::string indent_str; 39    static std::string indent_str; 
  • gen/logger.h

    Revision 1502:2292878925f4 Revision 1650:40bd4a0d4870
    23     23 
    24public: 24public: 
    25    Stream() : OS(0) {} 25    Stream() : OS(0) {} 
    26    Stream(std::ostream* S) : OS(S) {} 26    Stream(std::ostream* S) : OS(S) {} 
    27    Stream(std::ostream& S) : OS(&S) {} 27    Stream(std::ostream& S) : OS(&S) {} 
    28      28  
       29     /* 
    29    Stream operator << (std::ios_base &(*Func)(std::ios_base&)) { 30    Stream operator << (std::ios_base &(*Func)(std::ios_base&)) { 
    30      if (OS) *OS << Func; 31      if (OS) *OS << Func; 
    31      return *this; 32      return *this; 
    32    } 33    } 
    33      34     */ 
       35  
    34    Stream operator << (std::ostream &(*Func)(std::ostream&)) { 36    Stream operator << (std::ostream &(*Func)(std::ostream&)) { 
    35      if (OS) *OS << Func37      if (OS) Func(*OS)
    36      return *this; 38      return *this; 
    37    } 39    } 
    38     40 
    39    template<typename Ty> 41    template<typename Ty> 
    40    Stream& operator << (const Ty& Thing) { 42    Stream& operator << (const Ty& Thing) { 
  • gen/main.cpp

    Revision 1645:1d2d1aa16841 Revision 1650:40bd4a0d4870
    482        for (unsigned i = 0; i != mAttrs.size(); ++i) 482        for (unsigned i = 0; i != mAttrs.size(); ++i) 
    483        Features.AddFeature(mAttrs[i]); 483        Features.AddFeature(mAttrs[i]); 
    484        FeaturesStr = Features.getString(); 484        FeaturesStr = Features.getString(); 
    485    } 485    } 
    486 486 
    487    std::auto_ptr<llvm::TargetMachine> target(theTarget->createTargetMachine(triple, FeaturesStr));  487     // FIXME 
    488    assert(target.get() && "Could not allocate target machine!");  488     //std::auto_ptr<llvm::TargetMachine> target(theTarget->createTargetMachine(triple, FeaturesStr)); 
    489    gTargetMachine = target.get();  489     //assert(target.get() && "Could not allocate target machine!"); 
    490    gTargetData = gTargetMachine->getTargetData();  490     //gTargetMachine = target.get(); 
       491  
       492     llvm::TargetMachine* target = theTarget->createTargetMachine(triple, FeaturesStr); 
       493     gTargetMachine = target; 
       494  
       495     gTargetData = target->getTargetData(); 
    491 496 
    492    // get final data layout 497    // get final data layout 
    493    std::string datalayout = gTargetData->getStringRepresentation(); 498    std::string datalayout = gTargetData->getStringRepresentation(); 
    494    global.params.dataLayout = datalayout.c_str(); 499    global.params.dataLayout = datalayout.c_str(); 
    495 500 
  • gen/optimizer.cpp

    Revision 1576:4551475bc6b6 Revision 1650:40bd4a0d4870
    105    // -O1 105    // -O1 
    106    if (optimizeLevel >= 1) 106    if (optimizeLevel >= 1) 
    107    { 107    { 
    108        //addPass(pm, createStripDeadPrototypesPass()); 108        //addPass(pm, createStripDeadPrototypesPass()); 
    109        addPass(pm, createGlobalDCEPass()); 109        addPass(pm, createGlobalDCEPass()); 
    110        addPass(pm, createRaiseAllocationsPass()); 110        addPass(pm, createPromoteMemoryToRegisterPass()); 
    111        addPass(pm, createCFGSimplificationPass()); 111        addPass(pm, createCFGSimplificationPass()); 
    112        if (optimizeLevel == 1) 112        if (optimizeLevel == 1) 
    113            addPass(pm, createPromoteMemoryToRegisterPass()); 113            addPass(pm, createPromoteMemoryToRegisterPass()); 
    114        else 114        else 
    115            addPass(pm, createScalarReplAggregatesPass()); 115            addPass(pm, createScalarReplAggregatesPass()); 
      
    175        addPass(pm, createInstructionCombiningPass()); 175        addPass(pm, createInstructionCombiningPass()); 
    176        addPass(pm, createJumpThreadingPass()); 176        addPass(pm, createJumpThreadingPass()); 
    177        addPass(pm, createCFGSimplificationPass()); 177        addPass(pm, createCFGSimplificationPass()); 
    178        addPass(pm, createScalarReplAggregatesPass()); 178        addPass(pm, createScalarReplAggregatesPass()); 
    179        addPass(pm, createInstructionCombiningPass()); 179        addPass(pm, createInstructionCombiningPass()); 
    180        addPass(pm, createCondPropagationPass()); 180        addPass(pm, createConstantPropagationPass()); 
    181 181 
    182        addPass(pm, createReassociatePass()); 182        addPass(pm, createReassociatePass()); 
    183        addPass(pm, createLoopRotatePass()); 183        addPass(pm, createLoopRotatePass()); 
    184        addPass(pm, createLICMPass()); 184        addPass(pm, createLICMPass()); 
    185        addPass(pm, createLoopUnswitchPass()); 185        addPass(pm, createLoopUnswitchPass()); 
      
    192        addPass(pm, createGVNPass()); 192        addPass(pm, createGVNPass()); 
    193        addPass(pm, createMemCpyOptPass()); 193        addPass(pm, createMemCpyOptPass()); 
    194        addPass(pm, createSCCPPass()); 194        addPass(pm, createSCCPPass()); 
    195 195 
    196        addPass(pm, createInstructionCombiningPass()); 196        addPass(pm, createInstructionCombiningPass()); 
    197        addPass(pm, createCondPropagationPass()); 197        addPass(pm, createConstantPropagationPass()); 
    198 198 
    199        addPass(pm, createDeadStoreEliminationPass()); 199        addPass(pm, createDeadStoreEliminationPass()); 
    200        addPass(pm, createAggressiveDCEPass()); 200        addPass(pm, createAggressiveDCEPass()); 
    201        addPass(pm, createCFGSimplificationPass()); 201        addPass(pm, createCFGSimplificationPass()); 
    202        addPass(pm, createDeadTypeEliminationPass()); 202        addPass(pm, createDeadTypeEliminationPass()); 
  • gen/passes/SimplifyDRuntimeCalls.cpp

    Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870
    16 16 
    17#define DEBUG_TYPE "simplify-drtcalls" 17#define DEBUG_TYPE "simplify-drtcalls" 
    18 18 
    19#include "Passes.h" 19#include "Passes.h" 
    20 20 
      21#include "llvm/Function.h" 
    21#include "llvm/Pass.h" 22#include "llvm/Pass.h" 
    22#include "llvm/Intrinsics.h" 23#include "llvm/Intrinsics.h" 
    23#include "llvm/Support/IRBuilder.h" 24#include "llvm/Support/IRBuilder.h" 
    24#include "llvm/Analysis/AliasAnalysis.h" 25#include "llvm/Analysis/AliasAnalysis.h" 
    25#include "llvm/Analysis/ValueTracking.h" 26#include "llvm/Analysis/ValueTracking.h" 
  • gen/statements.cpp

    Revision 1647:638a823ace45 Revision 1650:40bd4a0d4870
    51void ReturnStatement::toIR(IRState* p) 51void ReturnStatement::toIR(IRState* p) 
    52{ 52{ 
    53    Logger::println("ReturnStatement::toIR(): %s", loc.toChars()); 53    Logger::println("ReturnStatement::toIR(): %s", loc.toChars()); 
    54    LOG_SCOPE; 54    LOG_SCOPE; 
    55 55 
    56    if (global.params.symdebug)  56     #ifndef DISABLE_DEBUG_INFO 
    57        DtoDwarfStopPoint(loc.linnum);  57     if (global.params.symdebug) 
    58      58         DtoDwarfStopPoint(loc.linnum); 
       59     #endif 
       60  
    59    // is there a return value expression? 61    // is there a return value expression? 
    60    if (exp || (!exp && (p->topfunc() == p->mainFunc)) ) 62    if (exp || (!exp && (p->topfunc() == p->mainFunc)) ) 
    61    { 63    { 
    62        // if the functions return type is void this means that 64        // if the functions return type is void this means that 
    63        // we are returning through a pointer argument 65        // we are returning through a pointer argument 
      
    76            DtoAssign(loc, rvar, e); 78            DtoAssign(loc, rvar, e); 
    77 79 
    78            // emit scopes 80            // emit scopes 
    79            DtoEnclosingHandlers(loc, NULL); 81            DtoEnclosingHandlers(loc, NULL); 
    80 82 
      83            #ifndef DISABLE_DEBUG_INFO 
    81            // emit dbg end function 84            // emit dbg end function 
    82            if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 85            if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 
      86            #endif 
    83 87 
    84            // emit ret 88            // emit ret 
    85            llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 89            llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 
    86 90 
    87        } 91        } 
      
    124                    Logger::cout() << "return value after cast: " << *v << '\n'; 128                    Logger::cout() << "return value after cast: " << *v << '\n'; 
    125            } 129            } 
    126 130 
    127            DtoEnclosingHandlers(loc, NULL); 131            DtoEnclosingHandlers(loc, NULL); 
    128 132 
      133            #ifndef DISABLE_DEBUG_INFO 
    129            if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 134            if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 
      135            #endif 
    130            llvm::ReturnInst::Create(gIR->context(), v, p->scopebb()); 136            llvm::ReturnInst::Create(gIR->context(), v, p->scopebb()); 
    131        } 137        } 
    132    } 138    } 
    133    // no return value expression means it's a void function 139    // no return value expression means it's a void function 
    134    else 140    else 
    135    { 141    { 
    136        assert(p->topfunc()->getReturnType() == LLType::getVoidTy(gIR->context())); 142        assert(p->topfunc()->getReturnType() == LLType::getVoidTy(gIR->context())); 
    137        DtoEnclosingHandlers(loc, NULL); 143        DtoEnclosingHandlers(loc, NULL); 
    138 144 
      145        #ifndef DISABLE_DEBUG_INFO 
    139        if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 146        if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 
      147        #endif 
    140        llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 148        llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 
    141    } 149    } 
    142 150 
    143    // the return terminated this basicblock, start a new one 151    // the return terminated this basicblock, start a new one 
    144    llvm::BasicBlock* oldend = gIR->scopeend(); 152    llvm::BasicBlock* oldend = gIR->scopeend(); 
      
    151void ExpStatement::toIR(IRState* p) 159void ExpStatement::toIR(IRState* p) 
    152{ 160{ 
    153    Logger::println("ExpStatement::toIR(): %s", loc.toChars()); 161    Logger::println("ExpStatement::toIR(): %s", loc.toChars()); 
    154    LOG_SCOPE; 162    LOG_SCOPE; 
    155 163 
    156    if (global.params.symdebug)  164     #ifndef DISABLE_DEBUG_INFO 
    157        DtoDwarfStopPoint(loc.linnum);  165     if (global.params.symdebug) 
       166         DtoDwarfStopPoint(loc.linnum); 
       167     #endif 
    158 168 
    159    if (exp) { 169    if (exp) { 
    160        if (global.params.llvmAnnotate) 170        if (global.params.llvmAnnotate) 
    161            DtoAnnotation(exp->toChars()); 171            DtoAnnotation(exp->toChars()); 
    162        elem* e; 172        elem* e; 
      
    180void IfStatement::toIR(IRState* p) 190void IfStatement::toIR(IRState* p) 
    181{ 191{ 
    182    Logger::println("IfStatement::toIR(): %s", loc.toChars()); 192    Logger::println("IfStatement::toIR(): %s", loc.toChars()); 
    183    LOG_SCOPE; 193    LOG_SCOPE; 
    184 194 
    185    if (global.params.symdebug)  195     #ifndef DISABLE_DEBUG_INFO 
    186        DtoDwarfStopPoint(loc.linnum);  196     if (global.params.symdebug) 
       197         DtoDwarfStopPoint(loc.linnum); 
       198     #endif 
    187 199 
    188    if (match) 200    if (match) 
    189        DtoRawVarDeclaration(match); 201        DtoRawVarDeclaration(match); 
    190 202 
    191    DValue* cond_e = condition->toElem(p); 203    DValue* cond_e = condition->toElem(p); 
      
    268void WhileStatement::toIR(IRState* p) 280void WhileStatement::toIR(IRState* p) 
    269{ 281{ 
    270    Logger::println("WhileStatement::toIR(): %s", loc.toChars()); 282    Logger::println("WhileStatement::toIR(): %s", loc.toChars()); 
    271    LOG_SCOPE; 283    LOG_SCOPE; 
    272 284 
    273    if (global.params.symdebug)  285     #ifndef DISABLE_DEBUG_INFO 
    274        DtoDwarfStopPoint(loc.linnum);  286     if (global.params.symdebug) 
       287         DtoDwarfStopPoint(loc.linnum); 
       288     #endif 
    275 289 
    276    // create while blocks 290    // create while blocks 
    277    llvm::BasicBlock* oldend = gIR->scopeend(); 291    llvm::BasicBlock* oldend = gIR->scopeend(); 
    278    llvm::BasicBlock* whilebb = llvm::BasicBlock::Create(gIR->context(), "whilecond", gIR->topfunc(), oldend); 292    llvm::BasicBlock* whilebb = llvm::BasicBlock::Create(gIR->context(), "whilecond", gIR->topfunc(), oldend); 
    279    llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create(gIR->context(), "whilebody", gIR->topfunc(), oldend); 293    llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create(gIR->context(), "whilebody", gIR->topfunc(), oldend); 
      
    316void DoStatement::toIR(IRState* p) 330void DoStatement::toIR(IRState* p) 
    317{ 331{ 
    318    Logger::println("DoStatement::toIR(): %s", loc.toChars()); 332    Logger::println("DoStatement::toIR(): %s", loc.toChars()); 
    319    LOG_SCOPE; 333    LOG_SCOPE; 
    320 334 
    321    if (global.params.symdebug)  335     #ifndef DISABLE_DEBUG_INFO 
    322        DtoDwarfStopPoint(loc.linnum);  336     if (global.params.symdebug) 
       337         DtoDwarfStopPoint(loc.linnum); 
       338     #endif 
    323 339 
    324    // create while blocks 340    // create while blocks 
    325    llvm::BasicBlock* oldend = gIR->scopeend(); 341    llvm::BasicBlock* oldend = gIR->scopeend(); 
    326    llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create(gIR->context(), "dowhile", gIR->topfunc(), oldend); 342    llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create(gIR->context(), "dowhile", gIR->topfunc(), oldend); 
    327    llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "dowhilecond", gIR->topfunc(), oldend); 343    llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "dowhilecond", gIR->topfunc(), oldend); 
      
    361void ForStatement::toIR(IRState* p) 377void ForStatement::toIR(IRState* p) 
    362{ 378{ 
    363    Logger::println("ForStatement::toIR(): %s", loc.toChars()); 379    Logger::println("ForStatement::toIR(): %s", loc.toChars()); 
    364    LOG_SCOPE; 380    LOG_SCOPE; 
    365 381 
    366    if (global.params.symdebug)  382     #ifndef DISABLE_DEBUG_INFO 
    367        DtoDwarfStopPoint(loc.linnum);  383     if (global.params.symdebug) 
       384         DtoDwarfStopPoint(loc.linnum); 
       385     #endif 
    368 386 
    369    // create for blocks 387    // create for blocks 
    370    llvm::BasicBlock* oldend = gIR->scopeend(); 388    llvm::BasicBlock* oldend = gIR->scopeend(); 
    371    llvm::BasicBlock* forbb = llvm::BasicBlock::Create(gIR->context(), "forcond", gIR->topfunc(), oldend); 389    llvm::BasicBlock* forbb = llvm::BasicBlock::Create(gIR->context(), "forcond", gIR->topfunc(), oldend); 
    372    llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create(gIR->context(), "forbody", gIR->topfunc(), oldend); 390    llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create(gIR->context(), "forbody", gIR->topfunc(), oldend); 
      
    441    // don't emit two terminators in a row 459    // don't emit two terminators in a row 
    442    // happens just before DMD generated default statements if the last case terminates 460    // happens just before DMD generated default statements if the last case terminates 
    443    if (p->scopereturned()) 461    if (p->scopereturned()) 
    444        return; 462        return; 
    445 463 
    446    if (global.params.symdebug)  464     #ifndef DISABLE_DEBUG_INFO 
    447        DtoDwarfStopPoint(loc.linnum);  465     if (global.params.symdebug) 
       466         DtoDwarfStopPoint(loc.linnum); 
       467     #endif 
    448 468 
    449    if (ident != 0) { 469    if (ident != 0) { 
    450        Logger::println("ident = %s", ident->toChars()); 470        Logger::println("ident = %s", ident->toChars()); 
    451 471 
    452        DtoEnclosingHandlers(loc, target); 472        DtoEnclosingHandlers(loc, target); 
      
    496void ContinueStatement::toIR(IRState* p) 516void ContinueStatement::toIR(IRState* p) 
    497{ 517{ 
    498    Logger::println("ContinueStatement::toIR(): %s", loc.toChars()); 518    Logger::println("ContinueStatement::toIR(): %s", loc.toChars()); 
    499    LOG_SCOPE; 519    LOG_SCOPE; 
    500 520 
    501    if (global.params.symdebug)  521     #ifndef DISABLE_DEBUG_INFO 
    502        DtoDwarfStopPoint(loc.linnum);  522     if (global.params.symdebug) 
       523         DtoDwarfStopPoint(loc.linnum); 
       524     #endif 
    503 525 
    504    if (ident != 0) { 526    if (ident != 0) { 
    505        Logger::println("ident = %s", ident->toChars()); 527        Logger::println("ident = %s", ident->toChars()); 
    506 528 
    507        DtoEnclosingHandlers(loc, target); 529        DtoEnclosingHandlers(loc, target); 
      
    562void TryFinallyStatement::toIR(IRState* p) 584void TryFinallyStatement::toIR(IRState* p) 
    563{ 585{ 
    564    Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars()); 586    Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars()); 
    565    LOG_SCOPE; 587    LOG_SCOPE; 
    566 588 
    567    if (global.params.symdebug)  589     #ifndef DISABLE_DEBUG_INFO 
    568        DtoDwarfStopPoint(loc.linnum);  590     if (global.params.symdebug) 
       591         DtoDwarfStopPoint(loc.linnum); 
       592     #endif 
    569 593 
    570    // if there's no finalbody or no body, things are simple 594    // if there's no finalbody or no body, things are simple 
    571    if (!finalbody) { 595    if (!finalbody) { 
    572        if (body) 596        if (body) 
    573            body->toIR(p); 597            body->toIR(p); 
      
    640void TryCatchStatement::toIR(IRState* p) 664void TryCatchStatement::toIR(IRState* p) 
    641{ 665{ 
    642    Logger::println("TryCatchStatement::toIR(): %s", loc.toChars()); 666    Logger::println("TryCatchStatement::toIR(): %s", loc.toChars()); 
    643    LOG_SCOPE; 667    LOG_SCOPE; 
    644 668 
    645    if (global.params.symdebug)  669     #ifndef DISABLE_DEBUG_INFO 
    646        DtoDwarfStopPoint(loc.linnum);  670     if (global.params.symdebug) 
       671         DtoDwarfStopPoint(loc.linnum); 
       672     #endif 
    647 673 
    648    // create basic blocks 674    // create basic blocks 
    649    llvm::BasicBlock* oldend = p->scopeend(); 675    llvm::BasicBlock* oldend = p->scopeend(); 
    650 676 
    651    llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", p->topfunc(), oldend); 677    llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", p->topfunc(), oldend); 
      
    696void ThrowStatement::toIR(IRState* p) 722void ThrowStatement::toIR(IRState* p) 
    697{ 723{ 
    698    Logger::println("ThrowStatement::toIR(): %s", loc.toChars()); 724    Logger::println("ThrowStatement::toIR(): %s", loc.toChars()); 
    699    LOG_SCOPE; 725    LOG_SCOPE; 
    700 726 
    701    if (global.params.symdebug)  727     #ifndef DISABLE_DEBUG_INFO 
    702        DtoDwarfStopPoint(loc.linnum);  728     if (global.params.symdebug) 
       729         DtoDwarfStopPoint(loc.linnum); 
       730     #endif 
    703 731 
    704    assert(exp); 732    assert(exp); 
    705    DValue* e = exp->toElem(p); 733    DValue* e = exp->toElem(p); 
    706 734 
      735    #ifndef DISABLE_DEBUG_INFO 
    707    if (global.params.symdebug) DtoDwarfFuncEnd(gIR->func()->decl); 736    if (global.params.symdebug) DtoDwarfFuncEnd(gIR->func()->decl); 
      737    #endif 
    708 738 
    709    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception"); 739    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception"); 
    710    //Logger::cout() << "calling: " << *fn << '\n'; 740    //Logger::cout() << "calling: " << *fn << '\n'; 
    711    LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); 741    LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); 
    712    //Logger::cout() << "arg: " << *arg << '\n'; 742    //Logger::cout() << "arg: " << *arg << '\n'; 
      
    778void SwitchStatement::toIR(IRState* p) 808void SwitchStatement::toIR(IRState* p) 
    779{ 809{ 
    780    Logger::println("SwitchStatement::toIR(): %s", loc.toChars()); 810    Logger::println("SwitchStatement::toIR(): %s", loc.toChars()); 
    781    LOG_SCOPE; 811    LOG_SCOPE; 
    782 812 
    783    if (global.params.symdebug)  813     #ifndef DISABLE_DEBUG_INFO 
    784        DtoDwarfStopPoint(loc.linnum);  814     if (global.params.symdebug) 
       815         DtoDwarfStopPoint(loc.linnum); 
       816     #endif 
    785 817 
    786    llvm::BasicBlock* oldend = gIR->scopeend(); 818    llvm::BasicBlock* oldend = gIR->scopeend(); 
    787 819 
    788    // clear data from previous passes... :/ 820    // clear data from previous passes... :/ 
    789    for (int i=0; i<cases->dim; ++i) 821    for (int i=0; i<cases->dim; ++i) 
      
    949 981 
    950    // if no statements, there's nothing to do 982    // if no statements, there's nothing to do 
    951    if (!statements || !statements->dim) 983    if (!statements || !statements->dim) 
    952        return; 984        return; 
    953 985 
    954    if (global.params.symdebug)  986     #ifndef DISABLE_DEBUG_INFO 
    955        DtoDwarfStopPoint(loc.linnum);  987     if (global.params.symdebug) 
       988         DtoDwarfStopPoint(loc.linnum); 
       989     #endif 
    956 990 
    957    // DMD doesn't fold stuff like continue/break, and since this isn't really a loop 991    // DMD doesn't fold stuff like continue/break, and since this isn't really a loop 
    958    // we have to keep track of each statement and jump to the next/end on continue/break 992    // we have to keep track of each statement and jump to the next/end on continue/break 
    959 993 
    960    llvm::BasicBlock* oldend = gIR->scopeend(); 994    llvm::BasicBlock* oldend = gIR->scopeend(); 
      
    1015void ForeachStatement::toIR(IRState* p) 1049void ForeachStatement::toIR(IRState* p) 
    1016{ 1050{ 
    1017    Logger::println("ForeachStatement::toIR(): %s", loc.toChars()); 1051    Logger::println("ForeachStatement::toIR(): %s", loc.toChars()); 
    1018    LOG_SCOPE; 1052    LOG_SCOPE; 
    1019 1053 
    1020    if (global.params.symdebug)  1054     #ifndef DISABLE_DEBUG_INFO 
    1021        DtoDwarfStopPoint(loc.linnum);  1055     if (global.params.symdebug) 
       1056         DtoDwarfStopPoint(loc.linnum); 
       1057     #endif 
    1022 1058 
    1023    //assert(arguments->dim == 1); 1059    //assert(arguments->dim == 1); 
    1024    assert(value != 0); 1060    assert(value != 0); 
    1025    assert(aggr != 0); 1061    assert(aggr != 0); 
    1026    assert(func != 0); 1062    assert(func != 0); 
      
    1147void ForeachRangeStatement::toIR(IRState* p) 1183void ForeachRangeStatement::toIR(IRState* p) 
    1148{ 1184{ 
    1149    Logger::println("ForeachRangeStatement::toIR(): %s", loc.toChars()); 1185    Logger::println("ForeachRangeStatement::toIR(): %s", loc.toChars()); 
    1150    LOG_SCOPE; 1186    LOG_SCOPE; 
    1151 1187 
    1152    if (global.params.symdebug)  1188     #ifndef DISABLE_DEBUG_INFO 
    1153        DtoDwarfStopPoint(loc.linnum);  1189     if (global.params.symdebug) 
       1190         DtoDwarfStopPoint(loc.linnum); 
       1191     #endif 
    1154 1192 
    1155    // evaluate lwr/upr 1193    // evaluate lwr/upr 
    1156    assert(lwr->type->isintegral()); 1194    assert(lwr->type->isintegral()); 
    1157    LLValue* lower = lwr->toElem(p)->getRVal(); 1195    LLValue* lower = lwr->toElem(p)->getRVal(); 
    1158    assert(upr->type->isintegral()); 1196    assert(upr->type->isintegral()); 
      
    1296void GotoStatement::toIR(IRState* p) 1334void GotoStatement::toIR(IRState* p) 
    1297{ 1335{ 
    1298    Logger::println("GotoStatement::toIR(): %s", loc.toChars()); 1336    Logger::println("GotoStatement::toIR(): %s", loc.toChars()); 
    1299    LOG_SCOPE; 1337    LOG_SCOPE; 
    1300 1338 
    1301    if (global.params.symdebug)  1339     #ifndef DISABLE_DEBUG_INFO 
    1302        DtoDwarfStopPoint(loc.linnum);  1340     if (global.params.symdebug) 
       1341         DtoDwarfStopPoint(loc.linnum); 
       1342     #endif 
    1303 1343 
    1304    llvm::BasicBlock* oldend = gIR->scopeend(); 1344    llvm::BasicBlock* oldend = gIR->scopeend(); 
    1305    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", p->topfunc(), oldend); 1345    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", p->topfunc(), oldend); 
    1306 1346 
    1307    DtoGoto(loc, label->ident, enclosingFinally); 1347    DtoGoto(loc, label->ident, enclosingFinally); 
      
    1314void GotoDefaultStatement::toIR(IRState* p) 1354void GotoDefaultStatement::toIR(IRState* p) 
    1315{ 1355{ 
    1316    Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars()); 1356    Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars()); 
    1317    LOG_SCOPE; 1357    LOG_SCOPE; 
    1318 1358 
    1319    if (global.params.symdebug)  1359     #ifndef DISABLE_DEBUG_INFO 
    1320        DtoDwarfStopPoint(loc.linnum);  1360     if (global.params.symdebug) 
       1361         DtoDwarfStopPoint(loc.linnum); 
       1362     #endif 
    1321 1363 
    1322    llvm::BasicBlock* oldend = gIR->scopeend(); 1364    llvm::BasicBlock* oldend = gIR->scopeend(); 
    1323    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", p->topfunc(), oldend); 1365    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", p->topfunc(), oldend); 
    1324 1366 
    1325    assert(!p->scopereturned()); 1367    assert(!p->scopereturned()); 
      
    1336void GotoCaseStatement::toIR(IRState* p) 1378void GotoCaseStatement::toIR(IRState* p) 
    1337{ 1379{ 
    1338    Logger::println("GotoCaseStatement::toIR(): %s", loc.toChars()); 1380    Logger::println("GotoCaseStatement::toIR(): %s", loc.toChars()); 
    1339    LOG_SCOPE; 1381    LOG_SCOPE; 
    1340 1382 
    1341    if (global.params.symdebug)  1383     #ifndef DISABLE_DEBUG_INFO 
    1342        DtoDwarfStopPoint(loc.linnum);  1384     if (global.params.symdebug) 
       1385         DtoDwarfStopPoint(loc.linnum); 
       1386     #endif 
    1343 1387 
    1344    llvm::BasicBlock* oldend = gIR->scopeend(); 1388    llvm::BasicBlock* oldend = gIR->scopeend(); 
    1345    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", p->topfunc(), oldend); 1389    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", p->topfunc(), oldend); 
    1346 1390 
    1347    assert(!p->scopereturned()); 1391    assert(!p->scopereturned()); 
      
    1361void WithStatement::toIR(IRState* p) 1405void WithStatement::toIR(IRState* p) 
    1362{ 1406{ 
    1363    Logger::println("WithStatement::toIR(): %s", loc.toChars()); 1407    Logger::println("WithStatement::toIR(): %s", loc.toChars()); 
    1364    LOG_SCOPE; 1408    LOG_SCOPE; 
    1365 1409 
    1366    if (global.params.symdebug)  1410     #ifndef DISABLE_DEBUG_INFO 
    1367        DtoDwarfStopPoint(loc.linnum);  1411     if (global.params.symdebug) 
       1412         DtoDwarfStopPoint(loc.linnum); 
       1413     #endif 
    1368 1414 
    1369    assert(exp); 1415    assert(exp); 
    1370    assert(body); 1416    assert(body); 
    1371 1417 
    1372    // with(..) can either be used with expressions or with symbols 1418    // with(..) can either be used with expressions or with symbols 
      
    1391void SynchronizedStatement::toIR(IRState* p) 1437void SynchronizedStatement::toIR(IRState* p) 
    1392{ 1438{ 
    1393    Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars()); 1439    Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars()); 
    1394    LOG_SCOPE; 1440    LOG_SCOPE; 
    1395 1441 
    1396    if (global.params.symdebug)  1442     #ifndef DISABLE_DEBUG_INFO 
    1397        DtoDwarfStopPoint(loc.linnum);  1443     if (global.params.symdebug) 
       1444         DtoDwarfStopPoint(loc.linnum); 
       1445     #endif 
    1398 1446 
    1399    // enter lock 1447    // enter lock 
    1400    if (exp) 1448    if (exp) 
    1401    { 1449    { 
    1402        llsync = exp->toElem(p)->getRVal(); 1450        llsync = exp->toElem(p)->getRVal(); 
      
    1428void VolatileStatement::toIR(IRState* p) 1476void VolatileStatement::toIR(IRState* p) 
    1429{ 1477{ 
    1430    Logger::println("VolatileStatement::toIR(): %s", loc.toChars()); 1478    Logger::println("VolatileStatement::toIR(): %s", loc.toChars()); 
    1431    LOG_SCOPE; 1479    LOG_SCOPE; 
    1432 1480 
    1433    if (global.params.symdebug)  1481     #ifndef DISABLE_DEBUG_INFO 
    1434        DtoDwarfStopPoint(loc.linnum);  1482     if (global.params.symdebug) 
       1483         DtoDwarfStopPoint(loc.linnum); 
       1484     #endif 
    1435 1485 
    1436    // mark in-volatile 1486    // mark in-volatile 
    1437    // FIXME 1487    // FIXME 
    1438 1488 
    1439    // has statement 1489    // has statement 
  • gen/tocall.cpp

    Revision 1607:207a8a438dea Revision 1650:40bd4a0d4870
    33    return 0; 33    return 0; 
    34} 34} 
    35 35 
    36////////////////////////////////////////////////////////////////////////////////////////// 36////////////////////////////////////////////////////////////////////////////////////////// 
    37 37 
    38unsigned DtoCallingConv(Loc loc, LINK l) 38llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l) 
    39{ 39{ 
    40    if (l == LINKc || l == LINKcpp || l == LINKintrinsic) 40    if (l == LINKc || l == LINKcpp || l == LINKintrinsic) 
    41        return llvm::CallingConv::C; 41        return llvm::CallingConv::C; 
    42    else if (l == LINKd || l == LINKdefault) 42    else if (l == LINKd || l == LINKdefault) 
    43    { 43    { 
      
    205    // put data in d-array 205    // put data in d-array 
    206    std::vector<LLConstant*> pinits; 206    std::vector<LLConstant*> pinits; 
    207    pinits.push_back(DtoConstSize_t(vtype->getNumElements())); 207    pinits.push_back(DtoConstSize_t(vtype->getNumElements())); 
    208    pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))); 208    pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))); 
    209    const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf()); 209    const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf()); 
    210    tiinits = LLConstantStruct::get(gIR->context(), pinits); 210    tiinits = LLConstantStruct::get(gIR->context(), pinits, false); 
    211    LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty, 211    LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty, 
    212        true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array"); 212        true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array"); 
    213 213 
    214    llvm::AttributeWithIndex Attr; 214    llvm::AttributeWithIndex Attr; 
    215    // specify arguments 215    // specify arguments 
      
    277    bool thiscall = tf->fty.arg_this; 277    bool thiscall = tf->fty.arg_this; 
    278    bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); 278    bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); 
    279    bool nestedcall = tf->fty.arg_nest; 279    bool nestedcall = tf->fty.arg_nest; 
    280    bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); 280    bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); 
    281 281 
    282    unsigned callconv = DtoCallingConv(loc, tf->linkage); 282    llvm::CallingConv::ID callconv = DtoCallingConv(loc, tf->linkage); 
    283 283 
    284    // get callee llvm value 284    // get callee llvm value 
    285    LLValue* callable = DtoCallableValue(fnval); 285    LLValue* callable = DtoCallableValue(fnval); 
    286    const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); 286    const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); 
    287    assert(callableTy); 287    assert(callableTy); 
  • gen/todebug.cpp

    Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870
    16#include "gen/utils.h" 16#include "gen/utils.h" 
    17 17 
    18#include "ir/irmodule.h" 18#include "ir/irmodule.h" 
    19 19 
    20using namespace llvm::dwarf; 20using namespace llvm::dwarf; 
      21 
      22#ifndef DISABLE_DEBUG_INFO 
    21 23 
    22#define DBG_NULL    ( LLConstant::getNullValue(DBG_TYPE) ) 24#define DBG_NULL    ( LLConstant::getNullValue(DBG_TYPE) ) 
    23#define DBG_TYPE    ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) ) 25#define DBG_TYPE    ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) ) 
    24#define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) 26#define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) 
    25 27 
      
    634        ln, // line no 636        ln, // line no 
    635        0, // col no 637        0, // col no 
    636        gIR->scopebb() 638        gIR->scopebb() 
    637    ); 639    ); 
    638} 640} 
      641 
      642#endif 
  • gen/todebug.h

    Revision 946:1714836f2c0b Revision 1650:40bd4a0d4870
    1#ifndef LDC_GEN_TODEBUG_H 1#ifndef LDC_GEN_TODEBUG_H 
    2#define LDC_GEN_TODEBUG_H 2#define LDC_GEN_TODEBUG_H 
      3 
      4#ifndef DISABLE_DEBUG_INFO 
    3 5 
    4void RegisterDwarfSymbols(llvm::Module* mod); 6void RegisterDwarfSymbols(llvm::Module* mod); 
    5 7 
    6/** 8/** 
    7 * Emit the Dwarf compile_unit global for a Module m. 9 * Emit the Dwarf compile_unit global for a Module m. 
      
    43 * @param vd  45 * @param vd 
    44 * @return  46 * @return 
    45 */ 47 */ 
    46llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); 48llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); 
    47 49 
      50#endif // DISABLE_DEBUG_INFO 
      51 
    48#endif // LDC_GEN_TODEBUG_H 52#endif // LDC_GEN_TODEBUG_H 
    49 53 
    50 54 
  • gen/tollvm.cpp

    Revision 1644:9176437d98be Revision 1650:40bd4a0d4870
    360    if (ptrTy == valTy) 360    if (ptrTy == valTy) 
    361    { 361    { 
    362        return val; 362        return val; 
    363    } 363    } 
    364    // ptr is integer pointer 364    // ptr is integer pointer 
    365    else if (ptrTy->isInteger()) 365    else if (ptrTy->isIntegerTy()) 
    366    { 366    { 
    367        // val is integer 367        // val is integer 
    368        assert(valTy->isInteger()); 368        assert(valTy->isInteger()); 
    369        const LLIntegerType* pt = llvm::cast<const LLIntegerType>(ptrTy); 369        const LLIntegerType* pt = llvm::cast<const LLIntegerType>(ptrTy); 
    370        const LLIntegerType* vt = llvm::cast<const LLIntegerType>(valTy); 370        const LLIntegerType* vt = llvm::cast<const LLIntegerType>(valTy); 
  • gen/toobj.cpp

    Revision 1575:299a6b634178 Revision 1650:40bd4a0d4870
    12 12 
    13#include "gen/llvm.h" 13#include "gen/llvm.h" 
    14#include "llvm/Analysis/Verifier.h" 14#include "llvm/Analysis/Verifier.h" 
    15#include "llvm/Bitcode/ReaderWriter.h" 15#include "llvm/Bitcode/ReaderWriter.h" 
    16#include "llvm/Module.h" 16#include "llvm/Module.h" 
    17#include "llvm/ModuleProvider.h"   
    18#include "llvm/PassManager.h" 17#include "llvm/PassManager.h" 
    19#include "llvm/LinkAllPasses.h" 18#include "llvm/LinkAllPasses.h" 
    20#include "llvm/System/Program.h" 19#include "llvm/System/Program.h" 
    21#include "llvm/Support/raw_ostream.h" 20#include "llvm/Support/raw_ostream.h" 
    22#include "llvm/Support/CommandLine.h" 21#include "llvm/Support/CommandLine.h" 
    23#include "llvm/Support/FormattedStream.h" 22#include "llvm/Support/FormattedStream.h" 
    24#include "llvm/Target/TargetMachine.h" 23#include "llvm/Target/TargetMachine.h" 
      24#include "llvm/CodeGen/MachineCodeEmitter.h" 
    25 25 
    26#include "mars.h" 26#include "mars.h" 
    27#include "module.h" 27#include "module.h" 
    28#include "mtype.h" 28#include "mtype.h" 
    29#include "declaration.h" 29#include "declaration.h" 
      
    112        Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n'; 112        Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n'; 
    113 113 
    114    // allocate the target abi 114    // allocate the target abi 
    115    gABI = TargetABI::getTarget(); 115    gABI = TargetABI::getTarget(); 
    116 116 
      117    #ifndef DISABLE_DEBUG_INFO 
    117    // debug info 118    // debug info 
    118    if (global.params.symdebug) { 119    if (global.params.symdebug) { 
    119        RegisterDwarfSymbols(ir.module); 120        RegisterDwarfSymbols(ir.module); 
    120        DtoDwarfCompileUnit(this); 121        DtoDwarfCompileUnit(this); 
    121    } 122    } 
      123    #endif 
    122 124 
    123    // handle invalid 'objectÞ module 125    // handle invalid 'objectÞ module 
    124    if (!ClassDeclaration::object) { 126    if (!ClassDeclaration::object) { 
    125        error("is missing 'class Object'"); 127        error("is missing 'class Object'"); 
    126        fatal(); 128        fatal(); 
      
    223    if (global.params.output_bc) { 225    if (global.params.output_bc) { 
    224        LLPath bcpath = LLPath(filename); 226        LLPath bcpath = LLPath(filename); 
    225        bcpath.eraseSuffix(); 227        bcpath.eraseSuffix(); 
    226        bcpath.appendSuffix(std::string(global.bc_ext)); 228        bcpath.appendSuffix(std::string(global.bc_ext)); 
    227        Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); 229        Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); 
    228        std::ofstream bos(bcpath.c_str(), std::ios::binary);  230         std::string errinfo; 
    229        if (bos.fail())  231         llvm::raw_fd_ostream bos(bcpath.c_str(), errinfo, llvm::raw_fd_ostream::F_Binary); 
       232         if (bos.has_error()) 
    230        { 233        { 
    231            error("cannot write LLVM bitcode, failed to open file '%s'", bcpath.c_str()); 234            error("cannot write LLVM bitcode file '%s': %s", bcpath.c_str(), errinfo.c_str()); 
    232            fatal(); 235            fatal(); 
    233        } 236        } 
    234        llvm::WriteBitcodeToFile(m, bos); 237        llvm::WriteBitcodeToFile(m, bos); 
    235    } 238    } 
    236 239 
      
    238    if (global.params.output_ll) { 241    if (global.params.output_ll) { 
    239        LLPath llpath = LLPath(filename); 242        LLPath llpath = LLPath(filename); 
    240        llpath.eraseSuffix(); 243        llpath.eraseSuffix(); 
    241        llpath.appendSuffix(std::string(global.ll_ext)); 244        llpath.appendSuffix(std::string(global.ll_ext)); 
    242        Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); 245        Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); 
    243        std::ofstream aos(llpath.c_str());  246         std::string errinfo; 
    244        if (aos.fail())  247         llvm::raw_fd_ostream aos(llpath.c_str(), errinfo); 
       248         if (aos.has_error()) 
    245        { 249        { 
    246            error("cannot write LLVM asm, failed to open file '%s'", llpath.c_str()); 250            error("cannot write LLVM asm file '%s': %s", llpath.c_str(), errinfo.c_str()); 
    247            fatal(); 251            fatal(); 
    248        } 252        } 
    249        m->print(aos, NULL); 253        m->print(aos, NULL); 
    250    } 254    } 
    251 255 
      
    258            spath.createTemporaryFileOnDisk(); 262            spath.createTemporaryFileOnDisk(); 
    259        } 263        } 
    260        Logger::println("Writing native asm to: %s\n", spath.c_str()); 264        Logger::println("Writing native asm to: %s\n", spath.c_str()); 
    261        std::string err; 265        std::string err; 
    262        { 266        { 
    263            llvm::raw_fd_ostream out(spath.c_str(), false, true, err); 267            llvm::raw_fd_ostream out(spath.c_str(), err); 
    264            if (err.empty()) 268            if (err.empty()) 
    265            { 269            { 
    266                write_asm_to_file(*gTargetMachine, *m, out); 270                write_asm_to_file(*gTargetMachine, *m, out); 
    267            } 271            } 
    268            else 272            else 
      
    290void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out) 294void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out) 
    291{ 295{ 
    292    using namespace llvm; 296    using namespace llvm; 
    293 297 
    294    // Build up all of the passes that we want to do to the module. 298    // Build up all of the passes that we want to do to the module. 
    295    ExistingModuleProvider Provider(&m); 299    FunctionPassManager Passes(&m); 
    296    FunctionPassManager Passes(&Provider);   
    297 300 
    298    if (const TargetData *TD = Target.getTargetData()) 301    if (const TargetData *TD = Target.getTargetData()) 
    299        Passes.add(new TargetData(*TD)); 302        Passes.add(new TargetData(*TD)); 
    300    else 303    else 
    301        Passes.add(new TargetData(&m)); 304        Passes.add(new TargetData(&m)); 
    302   
    303    // Ask the target to add backend passes as necessary.   
    304    MachineCodeEmitter *MCE = 0;   
    305 305 
    306    // Last argument is enum CodeGenOpt::Level OptLevel 306    // Last argument is enum CodeGenOpt::Level OptLevel 
    307    // debug info doesn't work properly with OptLevel != None! 307    // debug info doesn't work properly with OptLevel != None! 
    308    CodeGenOpt::Level LastArg = CodeGenOpt::Default; 308    CodeGenOpt::Level LastArg = CodeGenOpt::Default; 
    309    if (global.params.symdebug || !optimize()) 309    if (global.params.symdebug || !optimize()) 
    310        LastArg = CodeGenOpt::None; 310        LastArg = CodeGenOpt::None; 
    311    else if (optLevel() >= 3) 311    else if (optLevel() >= 3) 
    312        LastArg = CodeGenOpt::Aggressive; 312        LastArg = CodeGenOpt::Aggressive; 
    313 313 
    314    llvm::formatted_raw_ostream fout(out); 314    llvm::formatted_raw_ostream fout(out); 
    315    FileModel::Model mod = Target.addPassesToEmitFile(Passes, fout, TargetMachine::AssemblyFile, LastArg); 315    if (Target.addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, LastArg)) 
    316    assert(mod == FileModel::AsmFile); 316        assert(0 && "no support for asm output"); 
    317   
    318    bool err = Target.addPassesToEmitFileFinish(Passes, MCE, LastArg);   
    319    assert(!err);   
    320 317 
    321    Passes.doInitialization(); 318    Passes.doInitialization(); 
    322 319 
    323    // Run our queue of passes all at once now, efficiently. 320    // Run our queue of passes all at once now, efficiently. 
    324    for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) 321    for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) 
      
    326            Passes.run(*I); 323            Passes.run(*I); 
    327 324 
    328    Passes.doFinalization(); 325    Passes.doFinalization(); 
    329 326 
    330    // release module from module provider so we can delete it ourselves 327    // release module from module provider so we can delete it ourselves 
    331    std::string Err; 328    //std::string Err; 
    332    llvm::Module* rmod = Provider.releaseModule(&Err); 329    //llvm::Module* rmod = Provider.releaseModule(&Err); 
    333    assert(rmod); 330    //assert(rmod); 
    334} 331} 
    335 332 
    336/* ================================================================== */ 333/* ================================================================== */ 
    337 334 
    338// uses gcc to make an obj out of an assembly file 335// uses gcc to make an obj out of an assembly file 
      
    348    // Note: 345    // Note: 
    349    //  We can't just assemble and link the file with the system assembler 346    //  We can't just assemble and link the file with the system assembler 
    350    //  and linker because we don't know where to put the _start symbol. 347    //  and linker because we don't know where to put the _start symbol. 
    351    //  GCC mysteriously knows how to do it. 348    //  GCC mysteriously knows how to do it. 
    352    std::vector<std::string> args; 349    std::vector<std::string> args; 
    353    args.push_back(gcc.toString()); 350    args.push_back(gcc.str()); 
    354    args.push_back("-fno-strict-aliasing"); 351    args.push_back("-fno-strict-aliasing"); 
    355    args.push_back("-O3"); 352    args.push_back("-O3"); 
    356    args.push_back("-c"); 353    args.push_back("-c"); 
    357    args.push_back("-xassembler"); 354    args.push_back("-xassembler"); 
    358    args.push_back(asmpath.toString()); 355    args.push_back(asmpath.str()); 
    359    args.push_back("-o"); 356    args.push_back("-o"); 
    360    args.push_back(objpath.toString()); 357    args.push_back(objpath.str()); 
    361 358 
    362    //FIXME: only use this if needed? 359    //FIXME: only use this if needed? 
    363    args.push_back("-fpic"); 360    args.push_back("-fpic"); 
    364 361 
    365    //FIXME: enforce 64 bit 362    //FIXME: enforce 64 bit 
      
    429 426 
    430    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 427    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 
    431    IRBuilder<> builder(bb); 428    IRBuilder<> builder(bb); 
    432 429 
    433    // debug info 430    // debug info 
      431    #ifndef DISABLE_DEBUG_INFO 
    434    LLGlobalVariable* subprog; 432    LLGlobalVariable* subprog; 
    435    if(global.params.symdebug) { 433    if(global.params.symdebug) { 
    436        subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 434        subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 
    437        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 435        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 
    438    } 436    } 
      437    #endif 
    439 438 
    440    for (size_t i=0; i<n; i++) { 439    for (size_t i=0; i<n; i++) { 
    441        llvm::Function* f = gIR->ctors[i]->ir.irFunc->func; 440        llvm::Function* f = gIR->ctors[i]->ir.irFunc->func; 
    442        llvm::CallInst* call = builder.CreateCall(f,""); 441        llvm::CallInst* call = builder.CreateCall(f,""); 
    443        call->setCallingConv(DtoCallingConv(0, LINKd)); 442        call->setCallingConv(DtoCallingConv(0, LINKd)); 
    444    } 443    } 
    445 444 
    446    // debug info end 445    // debug info end 
      446    #ifndef DISABLE_DEBUG_INFO 
    447    if(global.params.symdebug) 447    if(global.params.symdebug) 
    448        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 448        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 
      449    #endif 
    449 450 
    450    builder.CreateRetVoid(); 451    builder.CreateRetVoid(); 
    451    return fn; 452    return fn; 
    452} 453} 
    453 454 
      
    473    fn->setCallingConv(DtoCallingConv(0, LINKd)); 474    fn->setCallingConv(DtoCallingConv(0, LINKd)); 
    474 475 
    475    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 476    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 
    476    IRBuilder<> builder(bb); 477    IRBuilder<> builder(bb); 
    477 478 
      479    #ifndef DISABLE_DEBUG_INFO 
    478    // debug info 480    // debug info 
    479    LLGlobalVariable* subprog; 481    LLGlobalVariable* subprog; 
    480    if(global.params.symdebug) { 482    if(global.params.symdebug) { 
    481        subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 483        subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 
    482        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 484        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 
    483    } 485    } 
      486    #endif 
    484 487 
    485    for (size_t i=0; i<n; i++) { 488    for (size_t i=0; i<n; i++) { 
    486        llvm::Function* f = gIR->dtors[i]->ir.irFunc->func; 489        llvm::Function* f = gIR->dtors[i]->ir.irFunc->func; 
    487        llvm::CallInst* call = builder.CreateCall(f,""); 490        llvm::CallInst* call = builder.CreateCall(f,""); 
    488        call->setCallingConv(DtoCallingConv(0, LINKd)); 491        call->setCallingConv(DtoCallingConv(0, LINKd)); 
    489    } 492    } 
    490 493 
      494    #ifndef DISABLE_DEBUG_INFO 
    491    // debug info end 495    // debug info end 
    492    if(global.params.symdebug) 496    if(global.params.symdebug) 
    493        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 497        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 
      498    #endif 
    494 499 
    495    builder.CreateRetVoid(); 500    builder.CreateRetVoid(); 
    496    return fn; 501    return fn; 
    497} 502} 
    498 503 
      
    518    fn->setCallingConv(DtoCallingConv(0, LINKd)); 523    fn->setCallingConv(DtoCallingConv(0, LINKd)); 
    519 524 
    520    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 525    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 
    521    IRBuilder<> builder(bb); 526    IRBuilder<> builder(bb); 
    522 527 
      528    #ifndef DISABLE_DEBUG_INFO 
    523    // debug info 529    // debug info 
    524    LLGlobalVariable* subprog; 530    LLGlobalVariable* subprog; 
    525    if(global.params.symdebug) { 531    if(global.params.symdebug) { 
    526        subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 532        subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 
    527        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 533        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 
    528    } 534    } 
      535    #endif 
    529 536 
    530    for (size_t i=0; i<n; i++) { 537    for (size_t i=0; i<n; i++) { 
    531        llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func; 538        llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func; 
    532        llvm::CallInst* call = builder.CreateCall(f,""); 539        llvm::CallInst* call = builder.CreateCall(f,""); 
    533        call->setCallingConv(DtoCallingConv(0, LINKd)); 540        call->setCallingConv(DtoCallingConv(0, LINKd)); 
    534    } 541    } 
    535 542 
      543    #ifndef DISABLE_DEBUG_INFO 
    536    // debug info end 544    // debug info end 
    537    if(global.params.symdebug) 545    if(global.params.symdebug) 
    538        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 546        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 
      547    #endif 
    539 548 
    540    builder.CreateRetVoid(); 549    builder.CreateRetVoid(); 
    541    return fn; 550    return fn; 
    542} 551} 
    543 552 
      
    576    // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list 585    // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list 
    577    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "moduleinfoCtorEntry", ctor); 586    llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "moduleinfoCtorEntry", ctor); 
    578    IRBuilder<> builder(bb); 587    IRBuilder<> builder(bb); 
    579 588 
    580    // debug info 589    // debug info 
      590    #ifndef DISABLE_DEBUG_INFO 
    581    LLGlobalVariable* subprog; 591    LLGlobalVariable* subprog; 
    582    if(global.params.symdebug) { 592    if(global.params.symdebug) { 
    583        subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV(); 593        subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV(); 
    584        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 594        builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 
    585    } 595    } 
      596    #endif 
    586 597 
    587    // get current beginning 598    // get current beginning 
    588    LLValue* curbeg = builder.CreateLoad(mref, "current"); 599    LLValue* curbeg = builder.CreateLoad(mref, "current"); 
    589 600 
    590    // put current beginning as the next of this one 601    // put current beginning as the next of this one 
      
    592    builder.CreateStore(curbeg, gep); 603    builder.CreateStore(curbeg, gep); 
    593 604 
    594    // replace beginning 605    // replace beginning 
    595    builder.CreateStore(thismref, mref); 606    builder.CreateStore(thismref, mref); 
    596 607 
      608    #ifndef DISABLE_DEBUG_INFO 
    597    // debug info end 609    // debug info end 
    598    if(global.params.symdebug) 610    if(global.params.symdebug) 
    599        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 611        builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 
      612    #endif 
    600 613 
    601    // return 614    // return 
    602    builder.CreateRetVoid(); 615    builder.CreateRetVoid(); 
    603 616 
    604    return ctor; 617    return ctor; 
  • ir/irclass.cpp

    Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870
    481        // offset 481        // offset 
    482        LLConstant* off = DtoConstSize_t(it->offset); 482        LLConstant* off = DtoConstSize_t(it->offset); 
    483 483 
    484        // create Interface struct 484        // create Interface struct 
    485        LLConstant* inits[3] = { ci, vtb, off }; 485        LLConstant* inits[3] = { ci, vtb, off }; 
    486        LLConstant* entry = LLConstantStruct::get(gIR->context(), inits, 3); 486        LLConstant* entry = LLConstantStruct::get(gIR->context(), inits, 3, false); 
    487        constants.push_back(entry); 487        constants.push_back(entry); 
    488    } 488    } 
    489 489 
    490    // create Interface[N] 490    // create Interface[N] 
    491    const llvm::ArrayType* array_type = llvm::ArrayType::get( 491    const llvm::ArrayType* array_type = llvm::ArrayType::get( 
  • ir/irlandingpad.cpp

    Revision 1584:f4c56ed32238 Revision 1650:40bd4a0d4870
    131            selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol()); 131            selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol()); 
    132        } 132        } 
    133    } 133    } 
    134    // if there's a finally, the eh table has to have a 0 action 134    // if there's a finally, the eh table has to have a 0 action 
    135    if(hasFinally) 135    if(hasFinally) 
    136        selectorargs.push_back(DtoConstSize_t(0));//LLConstantInt::get(LLType::getInt32Ty(gIR->context()), 0)); 136        selectorargs.push_back(DtoConstUint(0)); 
    137 137 
    138    // personality fn 138    // personality fn 
    139    llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); 139    llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); 
    140    LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context()))); 140    LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context()))); 
    141    selectorargs.insert(selectorargs.begin(), personality_fn_arg); 141    selectorargs.insert(selectorargs.begin(), personality_fn_arg); 
      
    149        const LLType* objectTy = DtoType(ClassDeclaration::object->type); 149        const LLType* objectTy = DtoType(ClassDeclaration::object->type); 
    150        gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); 150        gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); 
    151    } 151    } 
    152 152 
    153    // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>); 153    // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>); 
    154    llvm::Function* eh_selector_fn; 154    llvm::Function* eh_selector_fn = GET_INTRINSIC_DECL(eh_selector); 
    155    if (global.params.is64bit)   
    156        eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i64);   
    157    else   
    158        eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i32);   
    159    LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end()); 155    LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end()); 
    160 156 
    161    // emit finallys and switches that branch to catches until there are no more catches 157    // emit finallys and switches that branch to catches until there are no more catches 
    162    // then simply branch to the finally chain 158    // then simply branch to the finally chain 
    163    llvm::SwitchInst* switchinst = NULL; 159    llvm::SwitchInst* switchinst = NULL; 
      
    184                switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create(gIR->context(), "switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); 180                switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create(gIR->context(), "switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); 
    185                gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); 181                gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); 
    186            } 182            } 
    187            // dubious comment 183            // dubious comment 
    188            // catches matched first get the largest switchval, so do size - unique int 184            // catches matched first get the largest switchval, so do size - unique int 
    189            llvm::ConstantInt* switchval = LLConstantInt::get(DtoSize_t(), catchToInt[rit->catchType]); 185            llvm::ConstantInt* switchval = DtoConstUint(catchToInt[rit->catchType]); 
    190            // and make sure we don't add the same switchval twice, may happen with nested trys 186            // and make sure we don't add the same switchval twice, may happen with nested trys 
    191            if(!switchinst->findCaseValue(switchval)) 187            if(!switchinst->findCaseValue(switchval)) 
    192                switchinst->addCase(switchval, rit->target); 188                switchinst->addCase(switchval, rit->target); 
    193        } 189        } 
    194    } 190    } 
  • ir/irtype.cpp

    Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870
    1#include "llvm/DerivedTypes.h" 1#include "llvm/DerivedTypes.h" 
      2#include "llvm/LLVMContext.h" 
    2#include "mars.h" 3#include "mars.h" 
    3#include "mtype.h" 4#include "mtype.h" 
    4#include "gen/irstate.h" 5#include "gen/irstate.h" 
    5#include "gen/logger.h" 6#include "gen/logger.h" 
    6#include "ir/irtype.h" 7#include "ir/irtype.h" 
    7 8 
      9// This code uses llvm::getGlobalContext() as these functions are invoked before gIR is set. 
      10// ... thus it segfaults on gIR==NULL 
      11 
    8////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////// 
    9 13 
    10extern const llvm::Type* DtoType(Type* dt); 14extern const llvm::Type* DtoType(Type* dt); 
    11extern const llvm::Type* DtoSize_t(); 15extern const llvm::Type* DtoSize_t(); 
    12 16 
      
    41 45 
    42const llvm::Type * IrTypeBasic::basic2llvm(Type* t) 46const llvm::Type * IrTypeBasic::basic2llvm(Type* t) 
    43{ 47{ 
    44    const llvm::Type* t2; 48    const llvm::Type* t2; 
    45 49 
    46    // FIXME: don't use getGlobalContext  50     llvm::LLVMContext& ctx = llvm::getGlobalContext(); 
       51  
    47    switch(t->ty) 52    switch(t->ty) 
    48    { 53    { 
    49    case Tvoid: 54    case Tvoid: 
    50        return llvm::Type::getVoidTy(llvm::getGlobalContext()); 55        return llvm::Type::getVoidTy(ctx); 
    51 56 
    52    case Tint8: 57    case Tint8: 
    53    case Tuns8: 58    case Tuns8: 
    54    case Tchar: 59    case Tchar: 
    55        return llvm::Type::getInt8Ty(llvm::getGlobalContext()); 60        return llvm::Type::getInt8Ty(ctx); 
    56 61 
    57    case Tint16: 62    case Tint16: 
    58    case Tuns16: 63    case Tuns16: 
    59    case Twchar: 64    case Twchar: 
    60        return llvm::Type::getInt16Ty(llvm::getGlobalContext()); 65        return llvm::Type::getInt16Ty(ctx); 
    61 66 
    62    case Tint32: 67    case Tint32: 
    63    case Tuns32: 68    case Tuns32: 
    64    case Tdchar: 69    case Tdchar: 
    65        return llvm::Type::getInt32Ty(llvm::getGlobalContext()); 70        return llvm::Type::getInt32Ty(ctx); 
    66 71 
    67    case Tint64: 72    case Tint64: 
    68    case Tuns64: 73    case Tuns64: 
    69        return llvm::Type::getInt64Ty(llvm::getGlobalContext()); 74        return llvm::Type::getInt64Ty(ctx); 
    70 75 
    71    /* 76    /* 
    72    case Tint128: 77    case Tint128: 
    73    case Tuns128: 78    case Tuns128: 
    74        return llvm::IntegerType::get(llvm::getGlobalContext(), 128); 79        return llvm::IntegerType::get(llvm::getGlobalContext(), 128); 
    75    */ 80    */ 
    76 81 
    77    case Tfloat32: 82    case Tfloat32: 
    78    case Timaginary32: 83    case Timaginary32: 
    79        return llvm::Type::getFloatTy(llvm::getGlobalContext()); 84        return llvm::Type::getFloatTy(ctx); 
    80 85 
    81    case Tfloat64: 86    case Tfloat64: 
    82    case Timaginary64: 87    case Timaginary64: 
    83        return llvm::Type::getDoubleTy(llvm::getGlobalContext()); 88        return llvm::Type::getDoubleTy(ctx); 
    84 89 
    85    case Tfloat80: 90    case Tfloat80: 
    86    case Timaginary80: 91    case Timaginary80: 
    87        // only x86 has 80bit float 92        // only x86 has 80bit float 
    88        if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 93        if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 
    89            return llvm::Type::getX86_FP80Ty(llvm::getGlobalContext()); 94            return llvm::Type::getX86_FP80Ty(ctx); 
    90        // other platforms use 64bit reals 95        // other platforms use 64bit reals 
    91        else 96        else 
    92            return llvm::Type::getDoubleTy(llvm::getGlobalContext()); 97            return llvm::Type::getDoubleTy(ctx); 
    93 98 
    94    case Tcomplex32: 99    case Tcomplex32: 
    95        t2 = llvm::Type::getFloatTy(llvm::getGlobalContext()); 100        t2 = llvm::Type::getFloatTy(ctx); 
    96        return llvm::StructType::get(llvm::getGlobalContext(), t2, t2, NULL); 101        return llvm::StructType::get(ctx, t2, t2, NULL); 
    97 102 
    98    case Tcomplex64: 103    case Tcomplex64: 
    99        t2 = llvm::Type::getDoubleTy(llvm::getGlobalContext()); 104        t2 = llvm::Type::getDoubleTy(ctx); 
    100        return llvm::StructType::get(llvm::getGlobalContext(), t2, t2, NULL); 105        return llvm::StructType::get(ctx, t2, t2, NULL); 
    101 106 
    102    case Tcomplex80: 107    case Tcomplex80: 
    103        t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 108        t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 
    104            ? llvm::Type::getX86_FP80Ty(llvm::getGlobalContext()109            ? llvm::Type::getX86_FP80Ty(ctx
    105            : llvm::Type::getDoubleTy(llvm::getGlobalContext()); 110            : llvm::Type::getDoubleTy(ctx); 
    106        return llvm::StructType::get(llvm::getGlobalContext(), t2, t2, NULL); 111        return llvm::StructType::get(ctx, t2, t2, NULL); 
    107 112 
    108    case Tbool: 113    case Tbool: 
    109        return llvm::Type::getInt1Ty(llvm::getGlobalContext()); 114        return llvm::Type::getInt1Ty(ctx); 
    110    } 115    } 
    111 116 
    112    assert(0 && "not basic type"); 117    assert(0 && "not basic type"); 
    113    return NULL; 118    return NULL; 
    114} 119} 
  • ir/irvar.cpp

    Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870
    1#include "gen/llvm.h" 1#include "gen/llvm.h" 
    2#include "declaration.h" 2#include "declaration.h" 
      3#include "gen/irstate.h" 
    3#include "ir/irvar.h" 4#include "ir/irvar.h" 
    4 5 
    5 6 
    6////////////////////////////////////////////////////////////////////////////// 7////////////////////////////////////////////////////////////////////////////// 
    7////////////////////////////////////////////////////////////////////////////// 8////////////////////////////////////////////////////////////////////////////// 
      
    16////////////////////////////////////////////////////////////////////////////// 17////////////////////////////////////////////////////////////////////////////// 
    17////////////////////////////////////////////////////////////////////////////// 18////////////////////////////////////////////////////////////////////////////// 
    18////////////////////////////////////////////////////////////////////////////// 19////////////////////////////////////////////////////////////////////////////// 
    19 20 
    20IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v), 21IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v), 
    21    type(llvm::OpaqueType::get(llvm::getGlobalContext())) 22    type(llvm::OpaqueType::get(gIR->context())) 
    22{ 23{ 
    23    constInit = NULL; 24    constInit = NULL; 
    24} 25} 
    25 26 
    26////////////////////////////////////////////////////////////////////////////// 27////////////////////////////////////////////////////////////////////////////// 
  • tango-0.99.9.patch

    Revision 1633:5c0cebff9be8 Revision 1650:40bd4a0d4870
    1Index: tango/core/rt/compiler/ldc/rt/lifetime.d 1Index: tango/core/rt/compiler/ldc/rt/lifetime.d 
    2=================================================================== 2=================================================================== 
    3--- tango/core/rt/compiler/ldc/rt/lifetime.d    (revision 53683--- tango/core/rt/compiler/ldc/rt/lifetime.d    (revision 5462
    4+++ tango/core/rt/compiler/ldc/rt/lifetime.d    (working copy) 4+++ tango/core/rt/compiler/ldc/rt/lifetime.d    (working copy) 
    5@@ -786,6 +786,7 @@ 5@@ -786,6 +786,7 @@ 
    6     return *cast(long*)px; 6     return *cast(long*)px; 
    7 } 7 } 
    8  8  
      
    51  51  
    52+/+ 52+/+ 
    53  53  
    54 /** 54 /** 
    55  * 55  * 
      56Index: tango/core/rt/compiler/ldc/rt/eh.d 
      57=================================================================== 
      58--- tango/core/rt/compiler/ldc/rt/eh.d  (revision 5462) 
      59+++ tango/core/rt/compiler/ldc/rt/eh.d  (working copy) 
      60@@ -1,38 +1,34 @@ 
      61 /** 
      62  * This module contains functions and structures required for 
      63- * exception handling. 
      64+ * dwarf exception handling with llvm 
      65  */ 
      66 module rt.eh; 
      67  
      68-import ldc.cstdarg; 
      69-import rt.compiler.util.console; 
      70+//debug = EH_personality; 
      71  
      72-// debug = EH_personality; 
      73- 
      74 // current EH implementation works on x86 
      75 // if it has a working unwind runtime 
      76 version(X86) { 
      77     version(linux) version=X86_UNWIND; 
      78     version(darwin) version=X86_UNWIND; 
      79     version(solaris) version=X86_UNWIND; 
      80-    version(freebsd) version=X86_UNWIND; 
      81 } 
      82 version(X86_64) { 
      83     version(linux) version=X86_UNWIND; 
      84     version(darwin) version=X86_UNWIND; 
      85     version(solaris) version=X86_UNWIND; 
      86-    version(freebsd) version=X86_UNWIND; 
      87 } 
      88  
      89 //version = HP_LIBUNWIND; 
      90  
      91 private extern(C) void abort(); 
      92 private extern(C) int printf(char*, ...); 
      93-private extern(C) int vprintf(char*, va_list va); 
      94+//private extern(C) int vprintf(char*, va_list va); 
      95  
      96 // D runtime functions 
      97 extern(C) { 
      98-    int _d_isbaseof(ClassInfo oc, ClassInfo c); 
      99+//    int _d_isbaseof(ClassInfo oc, ClassInfo c); 
      100+    Object _d_dynamic_cast(Object o, ClassInfo c); 
      101 } 
      102  
      103 // libunwind headers 
      104@@ -74,16 +70,19 @@ 
      105 // interface to HP's libunwind from http://www.nongnu.org/libunwind/ 
      106 version(HP_LIBUNWIND) 
      107 { 
      108+    // Haven't checked whether and how it has _Unwind_Get{Text,Data}RelBase 
      109+    pragma (msg, "HP_LIBUNWIND interface is out of date and untested"); 
      110+ 
      111     void __libunwind_Unwind_Resume(_Unwind_Exception *); 
      112     _Unwind_Reason_Code __libunwind_Unwind_RaiseException(_Unwind_Exception *); 
      113     ptrdiff_t __libunwind_Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr 
      114             context); 
      115-    ptrdiff_t __libunwind_Unwind_GetIP(_Unwind_Context_Ptr context); 
      116+    size_t __libunwind_Unwind_GetIP(_Unwind_Context_Ptr context); 
      117     ptrdiff_t __libunwind_Unwind_SetIP(_Unwind_Context_Ptr context, 
      118             ptrdiff_t new_value); 
      119     ptrdiff_t __libunwind_Unwind_SetGR(_Unwind_Context_Ptr context, int index, 
      120             ptrdiff_t new_value); 
      121-    ptrdiff_t __libunwind_Unwind_GetRegionStart(_Unwind_Context_Ptr context); 
      122+    size_t __libunwind_Unwind_GetRegionStart(_Unwind_Context_Ptr context); 
      123  
      124     alias __libunwind_Unwind_Resume _Unwind_Resume; 
      125     alias __libunwind_Unwind_RaiseException _Unwind_RaiseException; 
      126@@ -94,27 +93,30 @@ 
      127     alias __libunwind_Unwind_SetGR _Unwind_SetGR; 
      128     alias __libunwind_Unwind_GetRegionStart _Unwind_GetRegionStart; 
      129 } 
      130-else version(X86_UNWIND)  
      131+else version(X86_UNWIND) 
      132 { 
      133     void _Unwind_Resume(_Unwind_Exception*); 
      134     _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); 
      135     ptrdiff_t _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context); 
      136-    ptrdiff_t _Unwind_GetIP(_Unwind_Context_Ptr context); 
      137+    size_t _Unwind_GetIP(_Unwind_Context_Ptr context); 
      138     ptrdiff_t _Unwind_SetIP(_Unwind_Context_Ptr context, ptrdiff_t new_value); 
      139     ptrdiff_t _Unwind_SetGR(_Unwind_Context_Ptr context, int index, 
      140             ptrdiff_t new_value); 
      141-    ptrdiff_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); 
      142+    size_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); 
      143+ 
      144+    size_t _Unwind_GetTextRelBase(_Unwind_Context_Ptr); 
      145+    size_t _Unwind_GetDataRelBase(_Unwind_Context_Ptr); 
      146 } 
      147 else 
      148 { 
      149     // runtime calls these directly 
      150     void _Unwind_Resume(_Unwind_Exception*) 
      151     { 
      152-        console("_Unwind_Resume is not implemented on this platform.\n"); 
      153+        printf("_Unwind_Resume is not implemented on this platform.\n"); 
      154     } 
      155     _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*) 
      156     { 
      157-        console("_Unwind_RaiseException is not implemented on this platform.\n"); 
      158+        printf("_Unwind_RaiseException is not implemented on this platform.\n"); 
      159         return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; 
      160     } 
      161 } 
      162@@ -122,14 +124,161 @@ 
      163 } 
      164  
      165 // error and exit 
      166-extern(C) private void fatalerror(char[] format) 
      167+extern(C) private void fatalerror(char* format, ...) 
      168 { 
      169-  printf("Fatal error in EH code: %.*s\n", format.length, format.ptr); 
      170+//  va_list args; 
      171+//  va_start(args, format); 
      172+  printf("Fatal error in EH code: "); 
      173+//  vprintf(format, args); 
      174+  printf("\n"); 
      175   abort(); 
      176 } 
      177  
      178  
      179-// helpers for reading certain DWARF data 
      180+// DWARF EH encoding enum 
      181+// See e.g. http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/dwarfext.html 
      182+private enum : ubyte { 
      183+  DW_EH_PE_omit    = 0xff, // value is not present 
      184+ 
      185+  // value format 
      186+  DW_EH_PE_absptr  = 0x00, // literal pointer 
      187+  DW_EH_PE_uleb128 = 0x01, 
      188+  DW_EH_PE_udata2  = 0x02, // unsigned 2-byte 
      189+  DW_EH_PE_udata4  = 0x03, 
      190+  DW_EH_PE_udata8  = 0x04, 
      191+  DW_EH_PE_sleb128 = 0x09, 
      192+  DW_EH_PE_sdata2  = 0x0a, 
      193+  DW_EH_PE_sdata4  = 0x0b, 
      194+  DW_EH_PE_sdata8  = 0x0c, 
      195+ 
      196+  // value meaning 
      197+  DW_EH_PE_pcrel    = 0x10, // relative to program counter 
      198+  DW_EH_PE_textrel  = 0x20, // relative to .text 
      199+  DW_EH_PE_datarel  = 0x30, // relative to .got or .eh_frame_hdr 
      200+  DW_EH_PE_funcrel  = 0x40, // relative to beginning of function 
      201+  DW_EH_PE_aligned  = 0x50, // is an aligned void* 
      202+ 
      203+  // value is a pointer to the actual value 
      204+  // this is a mask on top of one of the above 
      205+  DW_EH_PE_indirect = 0x80 
      206+} 
      207+ 
      208+// Helpers for reading DWARF data 
      209+ 
      210+// Given an encoding and a context, return the base to which the encoding is 
      211+// relative 
      212+private size_t base_of_encoded(_Unwind_Context_Ptr context, ubyte encoding) 
      213+{ 
      214+  if (encoding == DW_EH_PE_omit) 
      215+    return 0; 
      216+ 
      217+  switch (encoding & 0x70) // ignore DW_EH_PE_indirect 
      218+  { 
      219+    case DW_EH_PE_absptr, DW_EH_PE_pcrel, DW_EH_PE_aligned: 
      220+      return 0; 
      221+ 
      222+    case DW_EH_PE_textrel: return _Unwind_GetTextRelBase(context); 
      223+    case DW_EH_PE_datarel: return _Unwind_GetDataRelBase(context); 
      224+    case DW_EH_PE_funcrel: return _Unwind_GetRegionStart(context); 
      225+ 
      226+    default: fatalerror("Unrecognized base for DWARF value"); 
      227+  } 
      228+} 
      229+ 
      230+// Only defined for fixed-size encodings 
      231+private size_t size_of_encoded(ubyte encoding) 
      232+{ 
      233+  if (encoding == DW_EH_PE_omit) 
      234+    return 0; 
      235+ 
      236+  switch (encoding & 0x07) // ignore leb128 
      237+  { 
      238+    case DW_EH_PE_absptr: return (void*).sizeof; 
      239+    case DW_EH_PE_udata2: return 2; 
      240+    case DW_EH_PE_udata4: return 4; 
      241+    case DW_EH_PE_udata8: return 8; 
      242+ 
      243+    default: fatalerror("Unrecognized fixed-size DWARF value encoding"); 
      244+  } 
      245+} 
      246+ 
      247+// Actual value readers below: read a value from the given ubyte* into the 
      248+// output parameter and return the pointer incremented past the value. 
      249+ 
      250+// Like read_encoded_with_base but gets the base from the given context 
      251+private ubyte* read_encoded(_Unwind_Context_Ptr context, ubyte encoding, ubyte* p, out size_t val) 
      252+{ 
      253+  return read_encoded_with_base(encoding, base_of_encoded(context, encoding), p, val); 
      254+} 
      255+ 
      256+private ubyte* read_encoded_with_base(ubyte encoding, size_t base, ubyte* p, out size_t val) 
      257+{ 
      258+  if (encoding == DW_EH_PE_aligned) 
      259+  { 
      260+    auto a = cast(size_t)p; 
      261+    a = (a + (void*).sizeof - 1) & -(void*).sizeof; 
      262+    val = *cast(size_t*)a; 
      263+    return cast(ubyte*)(a + (void*).sizeof); 
      264+  } 
      265+ 
      266+  union U 
      267+  { 
      268+    size_t ptr; 
      269+    ushort udata2; 
      270+    uint   udata4; 
      271+    ulong  udata8; 
      272+    short  sdata2; 
      273+    int    sdata4; 
      274+    long   sdata8; 
      275+  } 
      276+ 
      277+  auto u = cast(U*)p; 
      278+ 
      279+  size_t result; 
      280+ 
      281+  switch (encoding & 0x0f) 
      282+  { 
      283+    case DW_EH_PE_absptr: 
      284+      result = u.ptr; 
      285+      p += (void*).sizeof; 
      286+      break; 
      287+ 
      288+    case DW_EH_PE_uleb128: 
      289+    { 
      290+      p = get_uleb128(p, result); 
      291+      break; 
      292+    } 
      293+    case DW_EH_PE_sleb128: 
      294+    { 
      295+      ptrdiff_t sleb128; 
      296+      p = get_sleb128(p, sleb128); 
      297+      result = cast(size_t)sleb128; 
      298+      break; 
      299+    } 
      300+ 
      301+    case DW_EH_PE_udata2: result = cast(size_t)u.udata2; p += 2; break; 
      302+    case DW_EH_PE_udata4: result = cast(size_t)u.udata4; p += 4; break; 
      303+    case DW_EH_PE_udata8: result = cast(size_t)u.udata8; p += 8; break; 
      304+    case DW_EH_PE_sdata2: result = cast(size_t)u.sdata2; p += 2; break; 
      305+    case DW_EH_PE_sdata4: result = cast(size_t)u.sdata4; p += 4; break; 
      306+    case DW_EH_PE_sdata8: result = cast(size_t)u.sdata8; p += 8; break; 
      307+ 
      308+    default: fatalerror("Unrecognized DWARF value encoding format"); 
      309+  } 
      310+  if (result) 
      311+  { 
      312+    if ((encoding & 0x70) == DW_EH_PE_pcrel) 
      313+      result += cast(size_t)u; 
      314+    else 
      315+      result += base; 
      316+ 
      317+    if (encoding & DW_EH_PE_indirect) 
      318+      result = *cast(size_t*)result; 
      319+  } 
      320+  val = result; 
      321+  return p; 
      322+} 
      323+ 
      324 private ubyte* get_uleb128(ubyte* addr, ref size_t res) 
      325 { 
      326   res = 0; 
      327@@ -137,7 +286,7 @@ 
      328  
      329   // read as long as high bit is set 
      330   while(*addr & 0x80) { 
      331-    res |= (*addr & 0x7f) << bitsize; 
      332+    res |= (*addr & 0x7fU) << bitsize; 
      333     bitsize += 7; 
      334     addr += 1; 
      335     if(bitsize >= size_t.sizeof*8) 
      336@@ -153,12 +302,12 @@ 
      337  
      338 private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res) 
      339 { 
      340-  res = 0; 
      341+  size_t tres = 0; 
      342   size_t bitsize = 0; 
      343  
      344   // read as long as high bit is set 
      345   while(*addr & 0x80) { 
      346-    res |= (*addr & 0x7f) << bitsize; 
      347+    tres |= (*addr & 0x7fU) << bitsize; 
      348     bitsize += 7; 
      349     addr += 1; 
      350     if(bitsize >= size_t.sizeof*8) 
      351@@ -167,12 +316,14 @@ 
      352   // read last 
      353   if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize) 
      354     fatalerror("tried to read sleb128 that exceeded size of size_t"); 
      355-  res |= (*addr) << bitsize; 
      356+  tres |= (*addr) << bitsize; 
      357  
      358   // take care of sign 
      359-  if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40)) 
      360-    res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1); 
      361+  if(bitsize < size_t.sizeof*8 && (*addr & 0x40U) != 0) 
      362+    tres |= cast(size_t)(-1) ^ ((1 << (bitsize+7)) - 1); 
      363  
      364+  res = cast(ptrdiff_t)tres; 
      365+ 
      366   return addr + 1; 
      367 } 
      368  
      369@@ -190,8 +341,7 @@ 
      370  
      371 // the 8-byte string identifying the type of exception 
      372 // the first 4 are for vendor, the second 4 for language 
      373-//TODO: This may be the wrong way around 
      374-const char[8] _d_exception_class = "LLDCD1\0\0"; 
      375+const char[8] _d_exception_class = "LDC_D_10"; 
      376  
      377  
      378 // 
      379@@ -201,118 +351,174 @@ 
      380 version(X86_UNWIND) 
      381 { 
      382  
      383+// Various stuff we need 
      384+struct Region 
      385+{ 
      386+  ubyte* callsite_table; 
      387+  ubyte* action_table; 
      388+ 
      389+  // Note: classinfo_table points past the end of the table 
      390+  ubyte* classinfo_table; 
      391+ 
      392+  size_t start; 
      393+  size_t lpStart_base; // landing pad base 
      394+ 
      395+  ubyte ttypeEnc; 
      396+  size_t ttype_base; // typeinfo base 
      397+ 
      398+  ubyte callSiteEnc; 
      399+} 
      400+ 
      401 // the personality routine gets called by the unwind handler and is responsible for 
      402 // reading the EH tables and deciding what to do 
      403 extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context) 
      404 { 
      405+  debug(EH_personality) printf("Entering personality routine, context=%p\n", context); 
      406   // check ver: the C++ Itanium ABI only allows ver == 1 
      407   if(ver != 1) 
      408+  { 
      409+    debug(EH_personality) printf("eh version mismatch\n"); 
      410     return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; 
      411+  } 
      412  
      413   // check exceptionClass 
      414   //TODO: Treat foreign exceptions with more respect 
      415-  if((cast(char*)&exception_class)[0..8] != _d_exception_class) 
      416+  auto wanted_ec = *cast(ulong*)_d_exception_class.ptr; 
      417+  if(exception_class != wanted_ec) 
      418+  { 
      419+    debug(EH_personality) printf("exception class mismatch %p vs %p\n", exception_class, wanted_ec); 
      420     return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; 
      421+  } 
      422  
      423   // find call site table, action table and classinfo table 
      424   // Note: callsite and action tables do not contain static-length 
      425   // data and will be parsed as needed 
      426-  // Note: classinfo_table points past the end of the table 
      427-  ubyte* callsite_table; 
      428-  ubyte* action_table; 
      429-  ClassInfo* classinfo_table; 
      430-  _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table); 
      431-  if (!callsite_table) 
      432+ 
      433+  Region region; 
      434+ 
      435+  _d_getLanguageSpecificTables(context, region); 
      436+ 
      437+  // workaround. this should not happen 
      438+  if (!region.callsite_table) 
      439+  { 
      440+    debug(EH_personality) printf("callsite_table is null\n"); 
      441     return _Unwind_Reason_Code.CONTINUE_UNWIND; 
      442+  } 
      443  
      444+  debug(EH_personality) printf("yay, checking\n"); 
      445+  debug(EH_personality) printf("region.start = %p\n", region.start); 
      446+ 
      447   /* 
      448     find landing pad and action table index belonging to ip by walking 
      449     the callsite_table 
      450   */ 
      451-  ubyte* callsite_walker = callsite_table; 
      452+  ubyte* callsite_walker = region.callsite_table; 
      453+  debug(EH_personality) printf("callsite table at: %p\n", region.callsite_table); 
      454+  debug(EH_personality) printf("action table at: %p\n", region.action_table); 
      455+  debug(EH_personality) printf("rtti table at %p\n", region.classinfo_table); 
      456  
      457   // get the instruction pointer 
      458   // will be used to find the right entry in the callsite_table 
      459   // -1 because it will point past the last instruction 
      460-  ptrdiff_t ip = _Unwind_GetIP(context) - 1; 
      461+  debug(EH_personality) printf("check1\n"); 
      462+  size_t ip = _Unwind_GetIP(context) - 1; 
      463+  debug(EH_personality) printf("check2\n"); 
      464  
      465-  // address block_start is relative to 
      466-  ptrdiff_t region_start = _Unwind_GetRegionStart(context); 
      467- 
      468   // table entries 
      469-  uint block_start_offset, block_size; 
      470-  ptrdiff_t landing_pad; 
      471+  size_t landing_pad; 
      472   size_t action_offset; 
      473  
      474   while(true) { 
      475     // if we've gone through the list and found nothing... 
      476-    if(callsite_walker >= action_table) 
      477+    if(callsite_walker >= region.action_table) 
      478+    { 
      479+      debug(EH_personality) printf("found nothing\n"); 
      480       return _Unwind_Reason_Code.CONTINUE_UNWIND; 
      481+    } 
      482  
      483-    block_start_offset = *cast(uint*)callsite_walker; 
      484-    block_size = *(cast(uint*)callsite_walker + 1); 
      485-    landing_pad = *(cast(uint*)callsite_walker + 2); 
      486-    if(landing_pad) 
      487-      landing_pad += region_start; 
      488-    callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset); 
      489+    size_t block_start, block_size; 
      490  
      491-    debug(EH_personality_verbose) printf("ip=%llx %d %d %llx\n", ip, block_start_offset, block_size, landing_pad); 
      492+    callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, block_start); 
      493+    callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, block_size); 
      494+    callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, landing_pad); 
      495+    callsite_walker = get_uleb128(callsite_walker, action_offset); 
      496  
      497+    debug(EH_personality) printf("*block start offset = %p\n", block_start); 
      498+    debug(EH_personality) printf(" block size = %p\n", block_size); 
      499+    debug(EH_personality) printf(" landing pad = %p\n", landing_pad); 
      500+    debug(EH_personality) printf(" ip=%p %p %p %p\n", ip, block_start, block_size, landing_pad); 
      501+ 
      502     // since the list is sorted, as soon as we're past the ip 
      503     // there's no handler to be found 
      504-    if(ip < region_start + block_start_offset) 
      505+    if(ip < region.start + block_start) 
      506+    { 
      507+      debug(EH_personality) printf("found nothing2\n"); 
      508       return _Unwind_Reason_Code.CONTINUE_UNWIND; 
      509+    } 
      510  
      511+    if(landing_pad) 
      512+      landing_pad += region.lpStart_base; 
      513+ 
      514     // if we've found our block, exit 
      515-    if(ip < region_start + block_start_offset + block_size) 
      516+    if(ip < region.start + block_start + block_size) 
      517       break; 
      518   } 
      519  
      520-  debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", action_offset); 
      521+  debug(EH_personality) printf("Found correct landing pad %p and actionOffset %p\n", landing_pad, action_offset); 
      522  
      523   // now we need the exception's classinfo to find a handler 
      524   // the exception_info is actually a member of a larger _d_exception struct 
      525   // the runtime allocated. get that now 
      526-  _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof); 
      527+  _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - size_t.sizeof); //_d_exception.unwind_info.offsetof); 
      528  
      529   // if there's no action offset and no landing pad, continue unwinding 
      530   if(!action_offset && !landing_pad) 
      531     return _Unwind_Reason_Code.CONTINUE_UNWIND; 
      532  
      533   // if there's no action offset but a landing pad, this is a cleanup handler 
      534-  else if(!action_offset && landing_pad) 
      535-    return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context); 
      536+  else if(!action_offset && landing_pad != 0) 
      537+  { 
      538+    debug(EH_personality) printf("installing finally context\n"); 
      539+    return _d_eh_install_finally_context(actions, cast(ptrdiff_t)landing_pad, exception_struct, context); 
      540+  } 
      541  
      542   /* 
      543    walk action table chain, comparing classinfos using _d_isbaseof 
      544   */ 
      545-  ubyte* action_walker = action_table + action_offset - 1; 
      546+  ubyte* action_walker = region.action_table + action_offset - 1; 
      547  
      548-  ptrdiff_t ti_offset, next_action_offset; 
      549   while(true) { 
      550+    ptrdiff_t ti_offset, next_action_offset; 
      551+ 
      552     action_walker = get_sleb128(action_walker, ti_offset); 
      553     // it is intentional that we not modify action_walker here 
      554     // next_action_offset is from current action_walker position 
      555     get_sleb128(action_walker, next_action_offset); 
      556  
      557     // negative are 'filters' which we don't use 
      558-    if(!(ti_offset >= 0)) 
      559+    if(ti_offset < 0) 
      560       fatalerror("Filter actions are unsupported"); 
      561  
      562     // zero means cleanup, which we require to be the last action 
      563     if(ti_offset == 0) { 
      564-      if(!(next_action_offset == 0)) 
      565+      if(next_action_offset != 0) 
      566         fatalerror("Cleanup action must be last in chain"); 
      567-      return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context); 
      568+      return _d_eh_install_finally_context(actions, cast(ptrdiff_t)landing_pad, exception_struct, context); 
      569     } 
      570  
      571     // get classinfo for action and check if the one in the 
      572     // exception structure is a base 
      573-    ClassInfo catch_ci = *(classinfo_table - ti_offset); 
      574-    debug(EH_personality) printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr); 
      575-    if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci)) 
      576-      return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context); 
      577+    size_t typeinfo; 
      578+    auto filter = cast(size_t)ti_offset * size_of_encoded(region.ttypeEnc); 
      579+    read_encoded_with_base(region.ttypeEnc, region.ttype_base, region.classinfo_table - filter, typeinfo); 
      580  
      581+    debug(EH_personality) 
      582+      printf("classinfo at %zx (enc %zx (size %zx) base %zx ptr %zx)\n", typeinfo, region.ttypeEnc, size_of_encoded(region.ttypeEnc), region.ttype_base, region.classinfo_table - filter); 
      583+ 
      584+    auto catch_ci = *cast(ClassInfo*)&typeinfo; 
      585+    if(_d_dynamic_cast(exception_struct.exception_object, catch_ci) !is null) 
      586+      return _d_eh_install_catch_context(actions, ti_offset, cast(ptrdiff_t)landing_pad, exception_struct, context); 
      587+ 
      588     // we've walked through all actions and found nothing... 
      589     if(next_action_offset == 0) 
      590       return _Unwind_Reason_Code.CONTINUE_UNWIND; 
      591@@ -356,6 +562,7 @@ 
      592   } 
      593  
      594   fatalerror("reached unreachable"); 
      595+ 
      596   return _Unwind_Reason_Code.FATAL_PHASE2_ERROR; 
      597 } 
      598  
      599@@ -370,56 +577,78 @@ 
      600   _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)exception_struct); 
      601   _Unwind_SetGR(context, eh_selector_regno, 0); 
      602   _Unwind_SetIP(context, landing_pad); 
      603+ 
      604   return _Unwind_Reason_Code.INSTALL_CONTEXT; 
      605 } 
      606  
      607-private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci) 
      608+private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, out Region region) 
      609 { 
      610-  ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); 
      611+  auto data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); 
      612+ 
      613+  // workaround. this should not be 0... 
      614   if (!data) 
      615   { 
      616-    callsite = null; 
      617-    action = null; 
      618-    ci = null; 
      619-    return; 
      620+      //printf("language specific data is null\n"); 
      621+      return; 
      622   } 
      623  
      624-  //TODO: Do proper DWARF reading here 
      625-  if(*data++ != 0xff) 
      626-    fatalerror("DWARF header has unexpected format 1"); 
      627+  region.start = _Unwind_GetRegionStart(context); 
      628  
      629-  if(*data++ != 0x00) 
      630-    fatalerror("DWARF header has unexpected format 2"); 
      631-  size_t cioffset; 
      632-  data = get_uleb128(data, cioffset); 
      633-  ci = cast(ClassInfo*)(data + cioffset); 
      634+  // Read the C++-style LSDA: this is implementation-defined by GCC but LLVM 
      635+  // outputs the same kind of table 
      636  
      637-  if(*data++ != 0x03) 
      638-    fatalerror("DWARF header has unexpected format 3"); 
      639-  size_t callsitelength; 
      640-  data = get_uleb128(data, callsitelength); 
      641-  action = data + callsitelength; 
      642+  // Get @LPStart: landing pad offsets are relative to it 
      643+  auto lpStartEnc = *data++; 
      644+  if (lpStartEnc == DW_EH_PE_omit) 
      645+    region.lpStart_base = region.start; 
      646+  else 
      647+    data = read_encoded(context, lpStartEnc, data, region.lpStart_base); 
      648  
      649-  callsite = data; 
      650+  // Get @TType: the offset to the handler and typeinfo 
      651+  region.ttypeEnc = *data++; 
      652+  if (region.ttypeEnc == DW_EH_PE_omit) 
      653+    // Not sure about this one... 
      654+    fatalerror("@TType must not be omitted from DWARF header"); 
      655+ 
      656+  size_t ciOffset; 
      657+  data = get_uleb128(data, ciOffset); 
      658+  region.classinfo_table = data + ciOffset; 
      659+ 
      660+  region.ttype_base = base_of_encoded(context, region.ttypeEnc); 
      661+ 
      662+  // Get encoding and length of the call site table, which precedes the action 
      663+  // table. 
      664+  region.callSiteEnc = *data++; 
      665+  if (region.callSiteEnc == DW_EH_PE_omit) 
      666+    fatalerror("Call site table encoding must not be omitted from DWARF header"); 
      667+ 
      668+  size_t callSiteLength; 
      669+  region.callsite_table = get_uleb128(data, callSiteLength); 
      670+  region.action_table = region.callsite_table + callSiteLength; 
      671 } 
      672  
      673 } // end of x86 Linux specific implementation 
      674  
      675- 
      676-extern(C) void _d_throw_exception(Object e) 
      677+// called to throw object 
      678+extern(C) 
      679+void _d_throw_exception(Object e) 
      680 { 
      681+    //printf("throwing %p, rtti = %p\n", e, **cast(ClassRTTI***)e); 
      682     if (e !is null) 
      683     { 
      684         _d_exception* exc_struct = new _d_exception; 
      685         exc_struct.unwind_info.exception_class = *cast(ulong*)_d_exception_class.ptr; 
      686         exc_struct.exception_object = e; 
      687         _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info); 
      688-        console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); 
      689+        printf("Error: returned %d from raise exception.\n", ret); 
      690+        //console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); 
      691     } 
      692     abort(); 
      693 } 
      694  
      695-extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct) 
      696+// called to resume unwinding 
      697+extern(C) 
      698+void _d_eh_resume_unwind(void* exception_struct) 
      699 { 
      700-  _Unwind_Resume(&exception_struct.unwind_info); 
      701+    _Unwind_Resume(&(cast(_d_exception*)exception_struct).unwind_info); 
      702 } 
Copyright © 2008, LDC Development Team.