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

Changeset 1587:def7a1d494fd

Show
Ignore:
Timestamp:
11/06/09 17:58:01 (10 months ago)
Author:
Christian Kamm <kamm incasoftware de>
branch:
default
Message:

Merge DMD 1.051

Files:

Legend:

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

    Revision 1530:05c235309d6f Revision 1587:def7a1d494fd
    45    class ConstantStruct; 45    class ConstantStruct; 
    46    class GlobalVariable; 46    class GlobalVariable; 
    47} 47} 
    48 48 
    49struct AggregateDeclaration : ScopeDsymbol 49struct AggregateDeclaration : ScopeDsymbol 
    50{ 50{ 
    51    Type *type; 51    Type *type; 
    52    unsigned storage_class; 52    unsigned storage_class; 
    53    enum PROT protection; 53    enum PROT protection; 
    54    Type *handle;       // 'this' type 54    Type *handle;       // 'this' type 
    55    unsigned structsize;    // size of struct 55    unsigned structsize;    // size of struct 
    56    unsigned alignsize;     // size of struct for alignment purposes 56    unsigned alignsize;     // size of struct for alignment purposes 
    57    unsigned structalign;   // struct member alignment in effect 57    unsigned structalign;   // struct member alignment in effect 
    58    int hasUnions;      // set if aggregate has overlapping fields 58    int hasUnions;      // set if aggregate has overlapping fields 
    59    Array fields;       // VarDeclaration fields 59    Array fields;       // VarDeclaration fields 
    60    unsigned sizeok;        // set when structsize contains valid data 60    unsigned sizeok;        // set when structsize contains valid data 
    61                // 0: no size 61                // 0: no size 
    62                // 1: size is correct 62                // 1: size is correct 
    63                // 2: cannot determine size; fwd referenced 63                // 2: cannot determine size; fwd referenced 
    64    int isdeprecated;       // !=0 if deprecated 64    int isdeprecated;       // !=0 if deprecated 
    65    Scope *scope;       // !=NULL means context to use   
    66 65 
    67    // Special member functions 66    // Special member functions 
    68    InvariantDeclaration *inv;      // invariant 67    InvariantDeclaration *inv;      // invariant 
    69    NewDeclaration *aggNew;     // allocator 68    NewDeclaration *aggNew;     // allocator 
    70    DeleteDeclaration *aggDelete;   // deallocator 69    DeleteDeclaration *aggDelete;   // deallocator 
      70 
      71#if DMDV2 
      72    //CtorDeclaration *ctor; 
      73    Dsymbol *ctor;          // CtorDeclaration or TemplateDeclaration 
      74    CtorDeclaration *defaultCtor;   // default constructor 
      75    Dsymbol *aliasthis;         // forward unresolved lookups to aliasthis 
      76#endif 
    71 77 
    72    FuncDeclarations dtors; // Array of destructors 78    FuncDeclarations dtors; // Array of destructors 
    73    FuncDeclaration *dtor;  // aggregate destructor 79    FuncDeclaration *dtor;  // aggregate destructor 
    74 80 
    75#ifdef IN_GCC 81#ifdef IN_GCC 
    76    Array methods;              // flat list of all methods for debug information 82    Array methods;              // flat list of all methods for debug information 
    77#endif 83#endif 
    78 84 
    79    AggregateDeclaration(Loc loc, Identifier *id); 85    AggregateDeclaration(Loc loc, Identifier *id); 
    80    void semantic2(Scope *sc); 86    void semantic2(Scope *sc); 
    81    void semantic3(Scope *sc); 87    void semantic3(Scope *sc); 
    82    void inlineScan(); 88    void inlineScan(); 
    83    unsigned size(Loc loc); 89    unsigned size(Loc loc); 
    84    static void alignmember(unsigned salign, unsigned size, unsigned *poffset); 90    static void alignmember(unsigned salign, unsigned size, unsigned *poffset); 
    85    Type *getType(); 91    Type *getType(); 
    86    void addField(Scope *sc, VarDeclaration *v); 92    void addField(Scope *sc, VarDeclaration *v); 
    87    int isDeprecated();     // is aggregate deprecated? 93    int isDeprecated();     // is aggregate deprecated? 
    88    FuncDeclaration *buildDtor(Scope *sc); 94    FuncDeclaration *buildDtor(Scope *sc); 
    89 95 
    90    void emitComment(Scope *sc); 96    void emitComment(Scope *sc); 
      97    void toJsonBuffer(OutBuffer *buf); 
    91    void toDocBuffer(OutBuffer *buf); 98    void toDocBuffer(OutBuffer *buf); 
    92 99 
    93    // For access checking 100    // For access checking 
    94    virtual PROT getAccess(Dsymbol *smember);   // determine access to smember 101    virtual PROT getAccess(Dsymbol *smember);   // determine access to smember 
    95    int isFriendOf(AggregateDeclaration *cd); 102    int isFriendOf(AggregateDeclaration *cd); 
    96    int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? 103    int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? 
    97    void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); 104    void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); 
    98 105 
    99    enum PROT prot(); 106    enum PROT prot(); 
    100 107 
    101#if IN_DMD 108#if IN_DMD 
    102    // Back end 109    // Back end 
    103    Symbol *stag;       // tag symbol for debug data 110    Symbol *stag;       // tag symbol for debug data 
    104    Symbol *sinit; 111    Symbol *sinit; 
    105    Symbol *toInitializer(); 112    Symbol *toInitializer(); 
    106#endif 113#endif 
    107 114 
    108    AggregateDeclaration *isAggregateDeclaration() { return this; } 115    AggregateDeclaration *isAggregateDeclaration() { return this; } 
    109 116 
    110#if IN_LLVM 117#if IN_LLVM 
  • dmd/arrayop.c

    Revision 1408:afecdb8ee962 Revision 1587:def7a1d494fd
    1 1 
    2// Copyright (c) 1999-2008 by Digital Mars 2// Copyright (c) 1999-2009 by Digital Mars 
    3// All Rights Reserved 3// All Rights Reserved 
    4// written by Walter Bright 4// written by Walter Bright 
    5// http://www.digitalmars.com 5// http://www.digitalmars.com 
    6// License for redistribution is by either the Artistic License 6// License for redistribution is by either the Artistic License 
    7// in artistic.txt, or the GNU General Public License in gnu.txt. 7// in artistic.txt, or the GNU General Public License in gnu.txt. 
    8// See the included readme.txt for details. 8// See the included readme.txt for details. 
    9 9 
    10#include <stdio.h> 10#include <stdio.h> 
    11#include <string.h> 11#include <string.h> 
    12#include <assert.h> 12#include <assert.h> 
    13 13 
    14#include "rmem.h" 14#include "rmem.h" 
    15 15 
    16#include "stringtable.h" 16#include "stringtable.h" 
    17 17 
    18#include "expression.h" 18#include "expression.h" 
    19#include "statement.h" 19#include "statement.h" 
    20#include "mtype.h" 20#include "mtype.h" 
    21#include "declaration.h" 21#include "declaration.h" 
    22#include "scope.h" 22#include "scope.h" 
    23#include "id.h" 23#include "id.h" 
    24#include "module.h" 24#include "module.h" 
    25#include "init.h" 25#include "init.h" 
    26 26 
    27 27 
    28/*********************************** 28/*********************************** 
    29 * Construct the array operation expression. 29 * Construct the array operation expression. 
    30 */ 30 */ 
    31 31 
    32Expression *BinExp::arrayOp(Scope *sc) 32Expression *BinExp::arrayOp(Scope *sc) 
    33{ 33{ 
      34    //printf("BinExp::arrayOp() %s\n", toChars()); 
      35 
      36    if (type->toBasetype()->nextOf()->toBasetype()->ty == Tvoid) 
      37    { 
      38        error("Cannot perform array operations on void[] arrays"); 
      39        return new ErrorExp(); 
      40    } 
      41 
    34    Expressions *arguments = new Expressions(); 42    Expressions *arguments = new Expressions(); 
    35 43 
    36    /* The expression to generate an array operation for is mangled 44    /* The expression to generate an array operation for is mangled 
    37     * into a name to use as the array operation function name. 45     * into a name to use as the array operation function name. 
    38     * Mangle in the operands and operators in RPN order, and type. 46     * Mangle in the operands and operators in RPN order, and type. 
    39     */ 47     */ 
    40    OutBuffer buf; 48    OutBuffer buf; 
    41    buf.writestring("_array"); 49    buf.writestring("_array"); 
    42    buildArrayIdent(&buf, arguments); 50    buildArrayIdent(&buf, arguments); 
    43    buf.writeByte('_'); 51    buf.writeByte('_'); 
    44 52 
    45    /* Append deco of array element type 53    /* Append deco of array element type 
    46     */ 54     */ 
    47#if DMDV2 55#if DMDV2 
    48    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco); 56    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco); 
    49#else 57#else 
    50    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco); 58    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco); 
    51#endif 59#endif 
    52 60 
    53    size_t namelen = buf.offset; 61    size_t namelen = buf.offset; 
      
    271 279 
    272        /* Construct the function 280        /* Construct the function 
    273         */ 281         */ 
    274        TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc); 282        TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc); 
    275        //printf("ftype: %s\n", ftype->toChars()); 283        //printf("ftype: %s\n", ftype->toChars()); 
    276        fd = new FuncDeclaration(0, 0, Lexer::idPool(name), STCundefined, ftype); 284        fd = new FuncDeclaration(0, 0, Lexer::idPool(name), STCundefined, ftype); 
    277        fd->fbody = fbody; 285        fd->fbody = fbody; 
    278        fd->protection = PROTpublic; 286        fd->protection = PROTpublic; 
    279        fd->linkage = LINKd; 287        fd->linkage = LINKd; 
    280 288 
    281        // special attention for array ops 289        // special attention for array ops 
    282        fd->isArrayOp = true; 290        fd->isArrayOp = true; 
    283 291 
    284        sc->module->importedFrom->members->push(fd); 292        sc->module->importedFrom->members->push(fd); 
    285 293 
    286        sc = sc->push(); 294        sc = sc->push(); 
    287        sc->parent = sc->module->importedFrom; 295        sc->parent = sc->module->importedFrom; 
    288        sc->stc = 0; 296        sc->stc = 0; 
    289        sc->linkage = LINKd; 297        sc->linkage = LINKd; 
    290        fd->semantic(sc); 298        fd->semantic(sc); 
      299        fd->semantic2(sc); 
      300        fd->semantic3(sc); 
    291        sc->pop(); 301        sc->pop(); 
    292//     } 302//     } 
    293//     else 303//     else 
    294//     {   /* In library, refer to it. 304//     {   /* In library, refer to it. 
    295//          */ 305//          */ 
    296//         // FIXME 306//         // FIXME 
    297//         fd = FuncDeclaration::genCfunc(NULL, type, name); 307//         fd = FuncDeclaration::genCfunc(NULL, type, name); 
    298//     } 308//     } 
    299    sv->ptrvalue = fd;  // cache symbol in hash table 309    sv->ptrvalue = fd;  // cache symbol in hash table 
    300    } 310    } 
    301 311 
    302    /* Call the function fd(arguments) 312    /* Call the function fd(arguments) 
    303     */ 313     */ 
    304    Expression *ec = new VarExp(0, fd); 314    Expression *ec = new VarExp(0, fd); 
    305    Expression *e = new CallExp(loc, ec, arguments); 315    Expression *e = new CallExp(loc, ec, arguments); 
    306    e->type = type; 316    e->type = type; 
    307    return e; 317    return e; 
    308} 318} 
    309 319 
    310/****************************************** 320/****************************************** 
    311 * Construct the identifier for the array operation function, 321 * Construct the identifier for the array operation function, 
    312 * and build the argument list to pass to it. 322 * and build the argument list to pass to it. 
    313 */ 323 */ 
    314 324 
    315void Expression::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 325void Expression::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 
    316{ 326{ 
    317    buf->writestring("Exp"); 327    buf->writestring("Exp"); 
    318    arguments->shift(this); 328    arguments->shift(this); 
    319} 329} 
    320 330 
      331void CastExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 
      332{ 
      333    Type *tb = type->toBasetype(); 
      334    if (tb->ty == Tarray || tb->ty == Tsarray) 
      335    { 
      336    e1->buildArrayIdent(buf, arguments); 
      337    } 
      338    else 
      339    Expression::buildArrayIdent(buf, arguments); 
      340} 
      341 
    321void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 342void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 
    322{ 343{ 
    323    buf->writestring("Slice"); 344    buf->writestring("Slice"); 
    324    arguments->shift(this); 345    arguments->shift(this); 
    325} 346} 
    326 347 
    327void AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 348void AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 
    328{ 349{ 
    329    /* Evaluate assign expressions right to left 350    /* Evaluate assign expressions right to left 
    330     */ 351     */ 
    331    e2->buildArrayIdent(buf, arguments); 352    e2->buildArrayIdent(buf, arguments); 
    332    e1->buildArrayIdent(buf, arguments); 353    e1->buildArrayIdent(buf, arguments); 
    333    buf->writestring("Assign"); 354    buf->writestring("Assign"); 
    334} 355} 
    335 356 
    336#define X(Str) \ 357#define X(Str) \ 
    337void Str##AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) \ 358void Str##AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) \ 
    338{                           \ 359{                           \ 
    339    /* Evaluate assign expressions right to left    \ 360    /* Evaluate assign expressions right to left    \ 
    340     */                         \ 361     */                         \ 
      
    385X(Xor) 406X(Xor) 
    386X(And) 407X(And) 
    387X(Or) 408X(Or) 
    388 409 
    389#undef X 410#undef X 
    390 411 
    391/****************************************** 412/****************************************** 
    392 * Construct the inner loop for the array operation function, 413 * Construct the inner loop for the array operation function, 
    393 * and build the parameter list. 414 * and build the parameter list. 
    394 */ 415 */ 
    395 416 
    396Expression *Expression::buildArrayLoop(Arguments *fparams) 417Expression *Expression::buildArrayLoop(Arguments *fparams) 
    397{ 418{ 
    398    Identifier *id = Identifier::generateId("c", fparams->dim); 419    Identifier *id = Identifier::generateId("c", fparams->dim); 
    399    Argument *param = new Argument(0, type, id, NULL); 420    Argument *param = new Argument(0, type, id, NULL); 
    400    fparams->shift(param); 421    fparams->shift(param); 
    401    Expression *e = new IdentifierExp(0, id); 422    Expression *e = new IdentifierExp(0, id); 
    402    return e; 423    return e; 
    403} 424} 
    404 425 
      426Expression *CastExp::buildArrayLoop(Arguments *fparams) 
      427{ 
      428    Type *tb = type->toBasetype(); 
      429    if (tb->ty == Tarray || tb->ty == Tsarray) 
      430    { 
      431    return e1->buildArrayLoop(fparams); 
      432    } 
      433    else 
      434    return Expression::buildArrayLoop(fparams); 
      435} 
      436 
    405Expression *SliceExp::buildArrayLoop(Arguments *fparams) 437Expression *SliceExp::buildArrayLoop(Arguments *fparams) 
    406{ 438{ 
    407    Identifier *id = Identifier::generateId("p", fparams->dim); 439    Identifier *id = Identifier::generateId("p", fparams->dim); 
    408    Argument *param = new Argument(STCconst, type, id, NULL); 440    Argument *param = new Argument(STCconst, type, id, NULL); 
    409    fparams->shift(param); 441    fparams->shift(param); 
    410    Expression *e = new IdentifierExp(0, id); 442    Expression *e = new IdentifierExp(0, id); 
    411    Expressions *arguments = new Expressions(); 443    Expressions *arguments = new Expressions(); 
    412    Expression *index = new IdentifierExp(0, Id::p); 444    Expression *index = new IdentifierExp(0, Id::p); 
    413    arguments->push(index); 445    arguments->push(index); 
    414    e = new ArrayExp(0, e, arguments); 446    e = new ArrayExp(0, e, arguments); 
    415    return e; 447    return e; 
    416} 448} 
    417 449 
    418Expression *AssignExp::buildArrayLoop(Arguments *fparams) 450Expression *AssignExp::buildArrayLoop(Arguments *fparams) 
    419{ 451{ 
    420    /* Evaluate assign expressions right to left 452    /* Evaluate assign expressions right to left 
    421     */ 453     */ 
    422    Expression *ex2 = e2->buildArrayLoop(fparams); 454    Expression *ex2 = e2->buildArrayLoop(fparams); 
      455#if DMDV2 
      456    /* Need the cast because: 
      457     *   b = c + p[i]; 
      458     * where b is a byte fails because (c + p[i]) is an int 
      459     * which cannot be implicitly cast to byte. 
      460     */ 
      461    ex2 = new CastExp(0, ex2, e1->type->nextOf()); 
      462#endif 
    423    Expression *ex1 = e1->buildArrayLoop(fparams); 463    Expression *ex1 = e1->buildArrayLoop(fparams); 
    424    Argument *param = (Argument *)fparams->data[0]; 464    Argument *param = (Argument *)fparams->data[0]; 
    425    param->storageClass = 0; 465    param->storageClass = 0; 
    426    Expression *e = new AssignExp(0, ex1, ex2); 466    Expression *e = new AssignExp(0, ex1, ex2); 
    427    return e; 467    return e; 
    428} 468} 
    429 469 
    430#define X(Str) \ 470#define X(Str) \ 
    431Expression *Str##AssignExp::buildArrayLoop(Arguments *fparams)  \ 471Expression *Str##AssignExp::buildArrayLoop(Arguments *fparams)  \ 
    432{                               \ 472{                               \ 
    433    /* Evaluate assign expressions right to left        \ 473    /* Evaluate assign expressions right to left        \ 
    434     */                             \ 474     */                             \ 
    435    Expression *ex2 = e2->buildArrayLoop(fparams);      \ 475    Expression *ex2 = e2->buildArrayLoop(fparams);      \ 
    436    Expression *ex1 = e1->buildArrayLoop(fparams);      \ 476    Expression *ex1 = e1->buildArrayLoop(fparams);      \ 
    437    Argument *param = (Argument *)fparams->data[0];     \ 477    Argument *param = (Argument *)fparams->data[0];     \ 
    438    param->storageClass = 0;                    \ 478    param->storageClass = 0;                    \ 
    439    Expression *e = new Str##AssignExp(0, ex1, ex2);        \ 479    Expression *e = new Str##AssignExp(0, ex1, ex2);        \ 
    440    return e;                           \ 480    return e;                           \ 
    441} 481} 
    442 482 
      
    471    /* Evaluate assign expressions left to right        \ 511    /* Evaluate assign expressions left to right        \ 
    472     */                             \ 512     */                             \ 
    473    Expression *ex1 = e1->buildArrayLoop(fparams);      \ 513    Expression *ex1 = e1->buildArrayLoop(fparams);      \ 
    474    Expression *ex2 = e2->buildArrayLoop(fparams);      \ 514    Expression *ex2 = e2->buildArrayLoop(fparams);      \ 
    475    Expression *e = new Str##Exp(0, ex1, ex2);          \ 515    Expression *e = new Str##Exp(0, ex1, ex2);          \ 
    476    return e;                           \ 516    return e;                           \ 
    477} 517} 
    478 518 
    479X(Add) 519X(Add) 
    480X(Min) 520X(Min) 
    481X(Mul) 521X(Mul) 
    482X(Div) 522X(Div) 
    483X(Mod) 523X(Mod) 
    484X(Xor) 524X(Xor) 
    485X(And) 525X(And) 
    486X(Or) 526X(Or) 
    487 527 
    488#undef X 528#undef X 
    489 529 
    490 530 
      531/*********************************************** 
      532 * Test if operand is a valid array op operand. 
      533 */ 
      534 
      535int Expression::isArrayOperand() 
      536{ 
      537    //printf("Expression::isArrayOperand() %s\n", toChars()); 
      538    if (op == TOKslice) 
      539    return 1; 
      540    if (type->toBasetype()->ty == Tarray) 
      541    { 
      542    switch (op) 
      543    { 
      544        case TOKadd: 
      545        case TOKmin: 
      546        case TOKmul: 
      547        case TOKdiv: 
      548        case TOKmod: 
      549        case TOKxor: 
      550        case TOKand: 
      551        case TOKor: 
      552        case TOKneg: 
      553        case TOKtilde: 
      554        return 1; 
      555 
      556        default: 
      557        break; 
      558    } 
      559    } 
      560    return 0; 
      561} 
  • dmd/attrib.c

    Revision 1392:336faed34424 Revision 1587:def7a1d494fd
    9// See the included readme.txt for details. 9// See the included readme.txt for details. 
    10 10 
    11#include <stdio.h> 11#include <stdio.h> 
    12#include <stdlib.h> 12#include <stdlib.h> 
    13#include <assert.h> 13#include <assert.h> 
    14 14 
    15#include "rmem.h" 15#include "rmem.h" 
    16 16 
    17#include "init.h" 17#include "init.h" 
    18#include "declaration.h" 18#include "declaration.h" 
    19#include "attrib.h" 19#include "attrib.h" 
    20#include "cond.h" 20#include "cond.h" 
    21#include "scope.h" 21#include "scope.h" 
    22#include "id.h" 22#include "id.h" 
    23#include "expression.h" 23#include "expression.h" 
    24#include "dsymbol.h" 24#include "dsymbol.h" 
    25#include "aggregate.h" 25#include "aggregate.h" 
    26#include "module.h" 26#include "module.h" 
    27#include "parse.h" 27#include "parse.h" 
    28#include "template.h" 28#include "template.h" 
      29#if TARGET_NET 
      30 #include "frontend.net/pragma.h" 
      31#endif 
    29 32 
    30#if IN_LLVM 33#if IN_LLVM 
    31#include "../gen/enums.h" 34#include "../gen/enums.h" 
    32 35 
    33#include "llvm/Support/CommandLine.h" 36#include "llvm/Support/CommandLine.h" 
    34 37 
    35static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore", 38static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore", 
    36    llvm::cl::desc("Ignore unsupported pragmas"), 39    llvm::cl::desc("Ignore unsupported pragmas"), 
    37    llvm::cl::ZeroOrMore); 40    llvm::cl::ZeroOrMore); 
    38 41 
    39#endif 42#endif 
    40 43 
    41 44 
    42extern void obj_includelib(const char *name); 45extern void obj_includelib(const char *name); 
    43 46 
    44#if IN_DMD 47#if IN_DMD 
    45void obj_startaddress(Symbol *s); 48void obj_startaddress(Symbol *s); 
    46#endif 49#endif 
    47 50 
    48 51 
      
    55} 58} 
    56 59 
    57Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd) 60Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd) 
    58{ 61{ 
    59    return decl; 62    return decl; 
    60} 63} 
    61 64 
    62int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 65int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 
    63{ 66{ 
    64    int m = 0; 67    int m = 0; 
    65    Array *d = include(sc, sd); 68    Array *d = include(sc, sd); 
    66 69 
    67    if (d) 70    if (d) 
    68    { 71    { 
    69    for (unsigned i = 0; i < d->dim; i++) 72    for (unsigned i = 0; i < d->dim; i++) 
    70    {   Dsymbol *s = (Dsymbol *)d->data[i]; 73    {   Dsymbol *s = (Dsymbol *)d->data[i]; 
    71        m |= s->addMember(sc, sd, m | memnum); 74        m |= s->addMember(sc, sd, m | memnum); 
    72    } 75    } 
    73    } 76    } 
    74    return m; 77    return m; 
      78} 
      79 
      80void AttribDeclaration::setScopeNewSc(Scope *sc, 
      81    unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 
      82    unsigned structalign) 
      83{ 
      84    if (decl) 
      85    { 
      86    Scope *newsc = sc; 
      87    if (stc != sc->stc || 
      88        linkage != sc->linkage || 
      89        protection != sc->protection || 
      90        explicitProtection != sc->explicitProtection || 
      91        structalign != sc->structalign) 
      92    { 
      93        // create new one for changes 
      94        newsc = new Scope(*sc); 
      95        newsc->flags &= ~SCOPEfree; 
      96        newsc->stc = stc; 
      97        newsc->linkage = linkage; 
      98        newsc->protection = protection; 
      99        newsc->explicitProtection = explicitProtection; 
      100        newsc->structalign = structalign; 
      101    } 
      102    for (unsigned i = 0; i < decl->dim; i++) 
      103    {   Dsymbol *s = (Dsymbol *)decl->data[i]; 
      104 
      105        s->setScope(newsc); // yes, the only difference from semanticNewSc() 
      106    } 
      107    if (newsc != sc) 
      108    { 
      109        sc->offset = newsc->offset; 
      110        newsc->pop(); 
      111    } 
      112    } 
      113} 
      114 
      115void AttribDeclaration::semanticNewSc(Scope *sc, 
      116    unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 
      117    unsigned structalign) 
      118{ 
      119    if (decl) 
      120    { 
      121    Scope *newsc = sc; 
      122    if (stc != sc->stc || 
      123        linkage != sc->linkage || 
      124        protection != sc->protection || 
      125        explicitProtection != sc->explicitProtection || 
      126        structalign != sc->structalign) 
      127    { 
      128        // create new one for changes 
      129        newsc = new Scope(*sc); 
      130        newsc->flags &= ~SCOPEfree; 
      131        newsc->stc = stc; 
      132        newsc->linkage = linkage; 
      133        newsc->protection = protection; 
      134        newsc->explicitProtection = explicitProtection; 
      135        newsc->structalign = structalign; 
      136    } 
      137    for (unsigned i = 0; i < decl->dim; i++) 
      138    {   Dsymbol *s = (Dsymbol *)decl->data[i]; 
      139 
      140        s->semantic(newsc); 
      141    } 
      142    if (newsc != sc) 
      143    { 
      144        sc->offset = newsc->offset; 
      145        newsc->pop(); 
      146    } 
      147    } 
    75} 148} 
    76 149 
    77void AttribDeclaration::semantic(Scope *sc) 150void AttribDeclaration::semantic(Scope *sc) 
    78{ 151{ 
    79    Array *d = include(sc, NULL); 152    Array *d = include(sc, NULL); 
    80 153 
    81    //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d); 154    //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d); 
    82    if (d) 155    if (d) 
    83    { 156    { 
    84    for (unsigned i = 0; i < d->dim; i++) 157    for (unsigned i = 0; i < d->dim; i++) 
    85    { 158    { 
    86        Dsymbol *s = (Dsymbol *)d->data[i]; 159        Dsymbol *s = (Dsymbol *)d->data[i]; 
    87 160 
    88        s->semantic(sc); 161        s->semantic(sc); 
    89    } 162    } 
    90    } 163    } 
    91} 164} 
    92 165 
    93void AttribDeclaration::semantic2(Scope *sc) 166void AttribDeclaration::semantic2(Scope *sc) 
    94{ 167{ 
      
    285    buf->writenl(); 358    buf->writenl(); 
    286} 359} 
    287 360 
    288/************************* StorageClassDeclaration ****************************/ 361/************************* StorageClassDeclaration ****************************/ 
    289 362 
    290StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) 363StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) 
    291    : AttribDeclaration(decl) 364    : AttribDeclaration(decl) 
    292{ 365{ 
    293    this->stc = stc; 366    this->stc = stc; 
    294} 367} 
    295 368 
    296Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s) 369Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s) 
    297{ 370{ 
    298    StorageClassDeclaration *scd; 371    StorageClassDeclaration *scd; 
    299 372 
    300    assert(!s); 373    assert(!s); 
    301    scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl)); 374    scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl)); 
    302    return scd; 375    return scd; 
    303} 376} 
    304 377 
      378void StorageClassDeclaration::setScope(Scope *sc) 
      379{ 
      380    if (decl) 
      381    { 
      382    unsigned scstc = sc->stc; 
      383 
      384    /* These sets of storage classes are mutually exclusive, 
      385     * so choose the innermost or most recent one. 
      386     */ 
      387    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
      388        scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
      389    if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 
      390        scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 
      391    if (stc & (STCconst | STCimmutable | STCmanifest)) 
      392        scstc &= ~(STCconst | STCimmutable | STCmanifest); 
      393    if (stc & (STCgshared | STCshared | STCtls)) 
      394        scstc &= ~(STCgshared | STCshared | STCtls); 
      395    scstc |= stc; 
      396 
      397    setScopeNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 
      398    } 
      399} 
      400 
    305void StorageClassDeclaration::semantic(Scope *sc) 401void StorageClassDeclaration::semantic(Scope *sc) 
    306{ 402{ 
    307    if (decl) 403    if (decl) 
    308    {   unsigned stc_save = sc->stc;  404     { 
    309  405     unsigned scstc = sc->stc; 
    310    if (stc & (STCauto | STCscope | STCstatic | STCextern))  406  
    311        sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern);  407     /* These sets of storage classes are mutually exclusive, 
    312    sc->stc |= stc;  408      * so choose the innermost or most recent one. 
    313    for (unsigned i = 0; i < decl->dim; i++)  409      */ 
    314    {  410     if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
    315        Dsymbol *s = (Dsymbol *)decl->data[i];  411         scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
    316  412     if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 
    317        s->semantic(sc);  413         scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 
    318    }  414     if (stc & (STCconst | STCimmutable | STCmanifest)) 
    319    sc->stc = stc_save;  415         scstc &= ~(STCconst | STCimmutable | STCmanifest); 
    320    }  416     if (stc & (STCgshared | STCshared | STCtls)) 
    321    else  417         scstc &= ~(STCgshared | STCshared | STCtls); 
    322    sc->stc = stc;  418     scstc |= stc; 
       419  
       420     semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 
       421     } 
    323} 422} 
    324 423 
    325void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) 424void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) 
    326{ 425{ 
    327    struct SCstring 426    struct SCstring 
    328    { 427    { 
    329    int stc; 428    int stc; 
    330    enum TOK tok; 429    enum TOK tok; 
    331    }; 430    }; 
    332 431 
    333    static SCstring table[] = 432    static SCstring table[] = 
    334    { 433    { 
    335    { STCauto,         TOKauto }, 434    { STCauto,         TOKauto }, 
    336    { STCscope,        TOKscope }, 435    { STCscope,        TOKscope }, 
    337    { STCstatic,       TOKstatic }, 436    { STCstatic,       TOKstatic }, 
    338    { STCextern,       TOKextern }, 437    { STCextern,       TOKextern }, 
    339    { STCconst,        TOKconst }, 438    { STCconst,        TOKconst }, 
    340//  { STCinvariant,    TOKimmutable },   
    341//  { STCshared,       TOKshared },   
    342    { STCfinal,        TOKfinal }, 439    { STCfinal,        TOKfinal }, 
    343    { STCabstract,     TOKabstract }, 440    { STCabstract,     TOKabstract }, 
    344    { STCsynchronized, TOKsynchronized }, 441    { STCsynchronized, TOKsynchronized }, 
    345    { STCdeprecated,   TOKdeprecated }, 442    { STCdeprecated,   TOKdeprecated }, 
    346    { STCoverride,     TOKoverride }, 443    { STCoverride,     TOKoverride }, 
    347//  { STCnothrow,      TOKnothrow },   
    348//  { STCpure,         TOKpure },   
    349//  { STCref,          TOKref },   
    350//  { STCtls,          TOKtls },   
    351    }; 444    }; 
    352 445 
    353    for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) 446    for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) 
    354    { 447    { 
    355    if (stc & table[i].stc) 448    if (stc & table[i].stc) 
    356    { 449    { 
    357        buf->writestring(Token::toChars(table[i].tok)); 450        buf->writestring(Token::toChars(table[i].tok)); 
    358        buf->writeByte(' '); 451        buf->writeByte(' '); 
    359    } 452    } 
    360    } 453    } 
    361} 454} 
    362 455 
    363void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 456void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    364{ 457{ 
    365    stcToCBuffer(buf, stc); 458    stcToCBuffer(buf, stc); 
    366    AttribDeclaration::toCBuffer(buf, hgs); 459    AttribDeclaration::toCBuffer(buf, hgs); 
    367} 460} 
    368 461 
    369/********************************* LinkDeclaration ****************************/ 462/********************************* LinkDeclaration ****************************/ 
    370 463 
    371LinkDeclaration::LinkDeclaration(enum LINK p, Array *decl) 464LinkDeclaration::LinkDeclaration(enum LINK p, Array *decl) 
    372    : AttribDeclaration(decl) 465    : AttribDeclaration(decl) 
    373{ 466{ 
    374    //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl); 467    //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl); 
    375    linkage = p; 468    linkage = p; 
    376} 469} 
    377 470 
    378Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s) 471Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s) 
    379{ 472{ 
    380    LinkDeclaration *ld; 473    LinkDeclaration *ld; 
    381 474 
    382    assert(!s); 475    assert(!s); 
    383    ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl)); 476    ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl)); 
    384    return ld; 477    return ld; 
    385} 478} 
    386 479 
      480void LinkDeclaration::setScope(Scope *sc) 
      481{ 
      482    //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl); 
      483    if (decl) 
      484    { 
      485    setScopeNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 
      486    } 
      487} 
      488 
    387void LinkDeclaration::semantic(Scope *sc) 489void LinkDeclaration::semantic(Scope *sc) 
    388{ 490{ 
    389    //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); 491    //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); 
    390    if (decl) 492    if (decl) 
    391    {   enum LINK linkage_save = sc->linkage; 493    { 
    392 494    semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 
    393    sc->linkage = linkage;   
    394    for (unsigned i = 0; i < decl->dim; i++)   
    395    {   
    396        Dsymbol *s = (Dsymbol *)decl->data[i];   
    397   
    398        s->semantic(sc);   
    399    }   
    400    sc->linkage = linkage_save;   
    401    }   
    402    else   
    403    {   
    404    sc->linkage = linkage;   
    405    } 495    } 
    406} 496} 
    407 497 
    408void LinkDeclaration::semantic3(Scope *sc) 498void LinkDeclaration::semantic3(Scope *sc) 
    409{ 499{ 
    410    //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl); 500    //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl); 
    411    if (decl) 501    if (decl) 
    412    {   enum LINK linkage_save = sc->linkage; 502    {   enum LINK linkage_save = sc->linkage; 
    413 503 
    414    sc->linkage = linkage; 504    sc->linkage = linkage; 
    415    for (unsigned i = 0; i < decl->dim; i++) 505    for (unsigned i = 0; i < decl->dim; i++) 
    416    { 506    { 
    417        Dsymbol *s = (Dsymbol *)decl->data[i]; 507        Dsymbol *s = (Dsymbol *)decl->data[i]; 
    418 508 
    419        s->semantic3(sc); 509        s->semantic3(sc); 
    420    } 510    } 
    421    sc->linkage = linkage_save; 511    sc->linkage = linkage_save; 
    422    } 512    } 
    423    else 513    else 
    424    { 514    { 
      
    456} 546} 
    457 547 
    458/********************************* ProtDeclaration ****************************/ 548/********************************* ProtDeclaration ****************************/ 
    459 549 
    460ProtDeclaration::ProtDeclaration(enum PROT p, Array *decl) 550ProtDeclaration::ProtDeclaration(enum PROT p, Array *decl) 
    461    : AttribDeclaration(decl) 551    : AttribDeclaration(decl) 
    462{ 552{ 
    463    protection = p; 553    protection = p; 
    464    //printf("decl = %p\n", decl); 554    //printf("decl = %p\n", decl); 
    465} 555} 
    466 556 
    467Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s) 557Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s) 
    468{ 558{ 
    469    ProtDeclaration *pd; 559    ProtDeclaration *pd; 
    470 560 
    471    assert(!s); 561    assert(!s); 
    472    pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl)); 562    pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl)); 
    473    return pd; 563    return pd; 
    474} 564} 
    475 565 
      566void ProtDeclaration::setScope(Scope *sc) 
      567{ 
      568    if (decl) 
      569    { 
      570    setScopeNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 
      571    } 
      572} 
      573 
      574void ProtDeclaration::importAll(Scope *sc) 
      575{ 
      576    Scope *newsc = sc; 
      577    if (sc->protection != protection || 
      578       sc->explicitProtection != 1) 
      579    { 
      580       // create new one for changes 
      581       newsc = new Scope(*sc); 
      582       newsc->flags &= ~SCOPEfree; 
      583       newsc->protection = protection; 
      584       newsc->explicitProtection = 1; 
      585    } 
      586 
      587    for (int i = 0; i < decl->dim; i++) 
      588    { 
      589       Dsymbol *s = (Dsymbol *)decl->data[i]; 
      590       s->importAll(newsc); 
      591    } 
      592 
      593    if (newsc != sc) 
      594       newsc->pop(); 
      595} 
      596 
    476void ProtDeclaration::semantic(Scope *sc) 597void ProtDeclaration::semantic(Scope *sc) 
    477{ 598{ 
    478    if (decl) 599    if (decl) 
    479    {   enum PROT protection_save = sc->protection; 600    { 
    480    int explicitProtection_save = sc->explicitProtection; 601    semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 
    481 602    } 
    482    sc->protection = protection; 603
    483    sc->explicitProtection = 1; 604 
    484    for (unsigned i = 0; i < decl->dim; i++) 605void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) 
    485    { 606
    486        Dsymbol *s = (Dsymbol *)decl->data[i]; 607    const char *p; 
    487   
    488        s->semantic(sc);   
    489    }   
    490    sc->protection = protection_save;   
    491    sc->explicitProtection = explicitProtection_save;   
    492    }   
    493    else   
    494    {   sc->protection = protection;   
    495    sc->explicitProtection = 1;   
    496    }   
    497  
    498   
    499void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)   
    500{   const char *p;   
    501 608 
    502    switch (protection) 609    switch (protection) 
    503    { 610    { 
    504    case PROTprivate:   p = "private";      break; 611    case PROTprivate:   p = "private";      break; 
    505    case PROTpackage:   p = "package";      break; 612    case PROTpackage:   p = "package";      break; 
    506    case PROTprotected: p = "protected";    break; 613    case PROTprotected: p = "protected";    break; 
    507    case PROTpublic:    p = "public";       break; 614    case PROTpublic:    p = "public";       break; 
    508    case PROTexport:    p = "export";       break; 615    case PROTexport:    p = "export";       break; 
    509    default: 616    default: 
    510        assert(0); 617        assert(0); 
    511        break; 618        break; 
    512    } 619    } 
    513    buf->writestring(p); 620    buf->writestring(p); 
      621    buf->writeByte(' '); 
      622} 
      623 
      624void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
      625{ 
      626    protectionToCBuffer(buf, protection); 
    514    AttribDeclaration::toCBuffer(buf, hgs); 627    AttribDeclaration::toCBuffer(buf, hgs); 
    515} 628} 
    516 629 
    517/********************************* AlignDeclaration ****************************/ 630/********************************* AlignDeclaration ****************************/ 
    518 631 
    519AlignDeclaration::AlignDeclaration(Loc loc, unsigned sa, Array *decl) 632AlignDeclaration::AlignDeclaration(Loc loc, unsigned sa, Array *decl) 
    520    : AttribDeclaration(decl) 633    : AttribDeclaration(decl) 
    521{ 634{ 
    522    this->loc = loc; 635    this->loc = loc; 
    523    salign = sa; 636    salign = sa; 
    524} 637} 
    525 638 
    526Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s) 639Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s) 
    527{ 640{ 
    528    AlignDeclaration *ad; 641    AlignDeclaration *ad; 
    529 642 
    530    assert(!s); 643    assert(!s); 
    531    ad = new AlignDeclaration(loc, salign, Dsymbol::arraySyntaxCopy(decl)); 644    ad = new AlignDeclaration(loc, salign, Dsymbol::arraySyntaxCopy(decl)); 
    532    return ad; 645    return ad; 
    533} 646} 
    534 647 
      648void AlignDeclaration::setScope(Scope *sc) 
      649{ 
      650    //printf("\tAlignDeclaration::setScope '%s'\n",toChars()); 
      651    if (decl) 
      652    { 
      653    setScopeNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 
      654    } 
      655} 
      656 
    535void AlignDeclaration::semantic(Scope *sc) 657void AlignDeclaration::semantic(Scope *sc) 
    536{ 658{ 
    537// LDC 659// LDC 
    538// we only support packed structs, as from the spec: align(1) struct Packed { ... } 660// we only support packed structs, as from the spec: align(1) struct Packed { ... } 
    539// other alignments are simply ignored. my tests show this is what llvm-gcc does too ... 661// other alignments are simply ignored. my tests show this is what llvm-gcc does too ... 
    540 662    { 
    541    //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); 663    semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 
    542    if (decl) 664    } 
    543    {   unsigned salign_save = sc->structalign;   
    544   
    545    for (unsigned i = 0; i < decl->dim; i++)   
    546    {   
    547        Dsymbol *s = (Dsymbol *)decl->data[i];   
    548   
    549        if (s->isStructDeclaration() && salign == 1)   
    550        {   
    551            sc->structalign = salign;   
    552            s->semantic(sc);   
    553            sc->structalign = salign_save;   
    554        }   
    555        else   
    556        {   
    557            s->semantic(sc);   
    558        }   
    559    }   
    560    sc->structalign = salign_save;   
    561    }   
    562    else   
    563    assert(0 && "what kind of align use triggers this?");   
    564} 665} 
    565 666 
    566 667 
    567void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 668void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    568{ 669{ 
    569    buf->printf("align (%d)", salign); 670    buf->printf("align (%d)", salign); 
    570    AttribDeclaration::toCBuffer(buf, hgs); 671    AttribDeclaration::toCBuffer(buf, hgs); 
    571} 672} 
    572 673 
    573/********************************* AnonDeclaration ****************************/ 674/********************************* AnonDeclaration ****************************/ 
    574 675 
    575AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Array *decl) 676AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Array *decl) 
    576    : AttribDeclaration(decl) 677    : AttribDeclaration(decl) 
    577{ 678{ 
    578    this->loc = loc; 679    this->loc = loc; 
    579    this->isunion = isunion; 680    this->isunion = isunion; 
    580    this->scope = NULL;   
    581    this->sem = 0; 681    this->sem = 0; 
    582} 682} 
    583 683 
    584Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) 684Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) 
    585{ 685{ 
    586    AnonDeclaration *ad; 686    AnonDeclaration *ad; 
    587 687 
    588    assert(!s); 688    assert(!s); 
    589    ad = new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl)); 689    ad = new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl)); 
    590    return ad; 690    return ad; 
    591} 691} 
    592 692 
    593void AnonDeclaration::semantic(Scope *sc) 693void AnonDeclaration::semantic(Scope *sc) 
    594{ 694{ 
    595    //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); 695    //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); 
    596 696 
    597    Scope *scx = NULL; 697    Scope *scx = NULL; 
    598    if (scope) 698    if (scope) 
    599    {   sc = scope; 699    {   sc = scope; 
    600    scx = scope; 700    scx = scope; 
      
    763 863 
    764PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl) 864PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl) 
    765    : AttribDeclaration(decl) 865    : AttribDeclaration(decl) 
    766{ 866{ 
    767    this->loc = loc; 867    this->loc = loc; 
    768    this->ident = ident; 868    this->ident = ident; 
    769    this->args = args; 869    this->args = args; 
    770} 870} 
    771 871 
    772Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) 872Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) 
    773{ 873{ 
    774    //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); 874    //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); 
    775    PragmaDeclaration *pd; 875    PragmaDeclaration *pd; 
    776 876 
    777    assert(!s); 877    assert(!s); 
    778    pd = new PragmaDeclaration(loc, ident, 878    pd = new PragmaDeclaration(loc, ident, 
    779    Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); 879    Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); 
    780    return pd; 880    return pd; 
    781} 881} 
    782 882 
      883void PragmaDeclaration::setScope(Scope *sc) 
      884{ 
      885#if TARGET_NET 
      886    if (ident == Lexer::idPool("assembly")) 
      887    { 
      888        if (!args || args->dim != 1) 
      889        { 
      890            error("pragma has invalid number of arguments"); 
      891        } 
      892        else 
      893        { 
      894            Expression *e = (Expression *)args->data[0]; 
      895            e = e->semantic(sc); 
      896            e = e->optimize(WANTvalue | WANTinterpret); 
      897            args->data[0] = (void *)e; 
      898            if (e->op != TOKstring) 
      899            { 
      900                error("string expected, not '%s'", e->toChars()); 
      901            } 
      902            PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 
      903 
      904            assert(sc); 
      905            pragma->setScope(sc); 
      906 
      907            //add to module members 
      908            assert(sc->module); 
      909            assert(sc->module->members); 
      910            sc->module->members->push(pragma); 
      911        } 
      912    } 
      913#endif // TARGET_NET 
      914} 
      915 
    783void PragmaDeclaration::semantic(Scope *sc) 916void PragmaDeclaration::semantic(Scope *sc) 
    784{   // Should be merged with PragmaStatement 917{   // Should be merged with PragmaStatement 
    785 918 
    786#if IN_LLVM 919#if IN_LLVM 
    787    int llvm_internal = 0; 920    int llvm_internal = 0; 
    788    std::string arg1str; 921    std::string arg1str; 
    789 922 
    790#endif 923#endif 
    791 924 
    792    //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); 925    //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); 
    793    if (ident == Id::msg) 926    if (ident == Id::msg) 
    794    { 927    { 
    795    if (args) 928    if (args) 
    796    { 929    { 
    797        for (size_t i = 0; i < args->dim; i++) 930        for (size_t i = 0; i < args->dim; i++) 
    798        { 931        { 
    799        Expression *e = (Expression *)args->data[i]; 932        Expression *e = (Expression *)args->data[i]; 
    800 933 
    801        e = e->semantic(sc); 934        e = e->semantic(sc); 
    802        e = e->optimize(WANTvalue | WANTinterpret); 935        e = e->optimize(WANTvalue | WANTinterpret); 
    803        if (e->op == TOKstring) 936        if (e->op == TOKstring) 
    804        { 937        { 
    805            StringExp *se = (StringExp *)e; 938            StringExp *se = (StringExp *)e; 
    806            fprintf(stdmsg, "%.*s", (int)se->len, (char*)se->string); 939            fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); 
    807        } 940        } 
    808        else 941        else 
    809            error("string expected for message, not '%s'", e->toChars()); 942            fprintf(stdmsg, e->toChars()); 
    810        } 943        } 
    811        fprintf(stdmsg, "\n"); 944        fprintf(stdmsg, "\n"); 
    812    } 945    } 
    813    goto Lnodecl; 946    goto Lnodecl; 
    814    } 947    } 
    815    else if (ident == Id::lib) 948    else if (ident == Id::lib) 
    816    { 949    { 
    817    if (!args || args->dim != 1) 950    if (!args || args->dim != 1) 
    818        error("string expected for library name"); 951        error("string expected for library name"); 
    819    else 952    else 
    820    { 953    { 
    821        Expression *e = (Expression *)args->data[0]; 954        Expression *e = (Expression *)args->data[0]; 
    822 955 
    823        e = e->semantic(sc); 956        e = e->semantic(sc); 
    824        e = e->optimize(WANTvalue | WANTinterpret); 957        e = e->optimize(WANTvalue | WANTinterpret); 
    825        args->data[0] = (void *)e; 958        args->data[0] = (void *)e; 
    826        if (e->op != TOKstring) 959        if (e->op != TOKstring) 
    827        error("string expected for library name, not '%s'", e->toChars()); 960        error("string expected for library name, not '%s'", e->toChars()); 
    828        else if (global.params.verbose) 961        else if (global.params.verbose) 
    829        { 962        { 
      
    856        if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) 989        if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) 
    857            d = NULL; 990            d = NULL; 
    858        } 991        } 
    859        if (!d) 992        if (!d) 
    860        error("first argument of GNU_asm must be a function or variable declaration"); 993        error("first argument of GNU_asm must be a function or variable declaration"); 
    861 994 
    862        e = (Expression *)args->data[1]; 995        e = (Expression *)args->data[1]; 
    863        e = e->semantic(sc); 996        e = e->semantic(sc); 
    864        e = e->optimize(WANTvalue); 997        e = e->optimize(WANTvalue); 
    865        if (e->op == TOKstring && ((StringExp *)e)->sz == 1) 998        if (e->op == TOKstring && ((StringExp *)e)->sz == 1) 
    866        s = ((StringExp *)e); 999        s = ((StringExp *)e); 
    867        else 1000        else 
    868        error("second argument of GNU_asm must be a char string"); 1001        error("second argument of GNU_asm must be a char string"); 
    869 1002 
    870        if (d && s) 1003        if (d && s) 
    871        d->c_ident = Lexer::idPool((char*) s->string); 1004        d->c_ident = Lexer::idPool((char*) s->string); 
    872    } 1005    } 
    873    goto Lnodecl; 1006    goto Lnodecl; 
    874    } 1007    } 
    875#endif 1008#endif 
      1009#if TARGET_NET 
      1010    else if (ident == Lexer::idPool("assembly")) 
      1011    { 
      1012        if (!args || args->dim != 1) 
      1013            error("pragma has invalid number of arguments"); 
      1014        else 
      1015        { 
      1016            Expression *e = (Expression *)args->data[0]; 
      1017            e = e->semantic(sc); 
      1018            e = e->optimize(WANTvalue | WANTinterpret); 
      1019            args->data[0] = (void *)e; 
      1020            if (e->op != TOKstring) 
      1021            { 
      1022                error("string expected, not '%s'", e->toChars()); 
      1023            } 
      1024            PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 
      1025            decl = new Array; 
      1026            decl->push(pragma); 
      1027        } 
      1028    } 
      1029#endif // TARGET_NET 
    876 1030 
    877// LDC 1031// LDC 
    878#if IN_LLVM 1032#if IN_LLVM 
    879 1033 
    880    // pragma(intrinsic, "string") { funcdecl(s) } 1034    // pragma(intrinsic, "string") { funcdecl(s) } 
    881    else if (ident == Id::intrinsic) 1035    else if (ident == Id::intrinsic) 
    882    { 1036    { 
    883        Expression* expr = (Expression *)args->data[0]; 1037        Expression* expr = (Expression *)args->data[0]; 
    884        expr = expr->semantic(sc); 1038        expr = expr->semantic(sc); 
    885        if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) 1039        if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) 
    886        { 1040        { 
    887             error("requires exactly 1 string literal parameter"); 1041             error("requires exactly 1 string literal parameter"); 
    888             fatal(); 1042             fatal(); 
    889        } 1043        } 
    890        llvm_internal = LLVMintrinsic; 1044        llvm_internal = LLVMintrinsic; 
    891    } 1045    } 
    892 1046 
    893    // pragma(notypeinfo) { typedecl(s) } 1047    // pragma(notypeinfo) { typedecl(s) } 
    894    else if (ident == Id::no_typeinfo) 1048    else if (ident == Id::no_typeinfo) 
    895    { 1049    { 
      
    1281    /* If generating doc comment, be careful because if we're inside 1436    /* If generating doc comment, be careful because if we're inside 
    1282     * a template, then include(NULL, NULL) will fail. 1437     * a template, then include(NULL, NULL) will fail. 
    1283     */ 1438     */ 
    1284    Array *d = decl ? decl : elsedecl; 1439    Array *d = decl ? decl : elsedecl; 
    1285    for (unsigned i = 0; i < d->dim; i++) 1440    for (unsigned i = 0; i < d->dim; i++) 
    1286    {   Dsymbol *s = (Dsymbol *)d->data[i]; 1441    {   Dsymbol *s = (Dsymbol *)d->data[i]; 
    1287        s->emitComment(sc); 1442        s->emitComment(sc); 
    1288    } 1443    } 
    1289    } 1444    } 
    1290} 1445} 
    1291 1446 
    1292// Decide if 'then' or 'else' code should be included 1447// Decide if 'then' or 'else' code should be included 
    1293 1448 
    1294Array *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd) 1449Array *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd) 
    1295{ 1450{ 
    1296    //printf("ConditionalDeclaration::include()\n"); 1451    //printf("ConditionalDeclaration::include()\n"); 
    1297    assert(condition); 1452    assert(condition); 
    1298    return condition->include(sc, sd) ? decl : elsedecl; 1453    return condition->include(sc, sd) ? decl : elsedecl; 
    1299} 1454} 
    1300 1455 
      1456void ConditionalDeclaration::setScope(Scope *sc) 
      1457{ 
      1458    Array *d = include(sc, NULL); 
      1459 
      1460    //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d); 
      1461    if (d) 
      1462    { 
      1463       for (unsigned i = 0; i < d->dim; i++) 
      1464       { 
      1465           Dsymbol *s = (Dsymbol *)d->data[i]; 
      1466 
      1467           s->setScope(sc); 
      1468       } 
      1469    } 
      1470} 
      1471 
      1472void ConditionalDeclaration::importAll(Scope *sc) 
      1473{ 
      1474    Array *d = include(sc, NULL); 
      1475 
      1476    //printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d); 
      1477    if (d) 
      1478    { 
      1479       for (unsigned i = 0; i < d->dim; i++) 
      1480       { 
      1481           Dsymbol *s = (Dsymbol *)d->data[i]; 
      1482 
      1483           s->importAll(sc); 
      1484       } 
      1485    } 
      1486} 
    1301 1487 
    1302void ConditionalDeclaration::addComment(unsigned char *comment) 1488void ConditionalDeclaration::addComment(unsigned char *comment) 
    1303{ 1489{ 
    1304    /* Because addComment is called by the parser, if we called 1490    /* Because addComment is called by the parser, if we called 
    1305     * include() it would define a version before it was used. 1491     * include() it would define a version before it was used. 
    1306     * But it's no problem to drill down to both decl and elsedecl, 1492     * But it's no problem to drill down to both decl and elsedecl, 
    1307     * so that's the workaround. 1493     * so that's the workaround. 
    1308     */ 1494     */ 
    1309 1495 
    1310    if (comment) 1496    if (comment) 
    1311    { 1497    { 
    1312    Array *d = decl; 1498    Array *d = decl; 
    1313 1499 
    1314    for (int j = 0; j < 2; j++) 1500    for (int j = 0; j < 2; j++) 
    1315    { 1501    { 
    1316        if (d) 1502        if (d) 
    1317        { 1503        { 
    1318        for (unsigned i = 0; i < d->dim; i++) 1504        for (unsigned i = 0; i < d->dim; i++) 
    1319        {   Dsymbol *s; 1505        {   Dsymbol *s; 
    1320 1506 
      
    1401     * in the same scope, such as: 1587     * in the same scope, such as: 
    1402     * 1588     * 
    1403     * template Foo(int i) 1589     * template Foo(int i) 
    1404     * { 1590     * { 
    1405     *     const int j = i + 1; 1591     *     const int j = i + 1; 
    1406     *     static if (j == 3) 1592     *     static if (j == 3) 
    1407     *         const int k; 1593     *         const int k; 
    1408     * } 1594     * } 
    1409     */ 1595     */ 
    1410    this->sd = sd; 1596    this->sd = sd; 
    1411    int m = 0; 1597    int m = 0; 
    1412 1598 
    1413    if (memnum == 0) 1599    if (memnum == 0) 
    1414    {   m = AttribDeclaration::addMember(sc, sd, memnum); 1600    {   m = AttribDeclaration::addMember(sc, sd, memnum); 
    1415    addisdone = 1; 1601    addisdone = 1; 
    1416    } 1602    } 
    1417    return m; 1603    return m; 
    1418} 1604} 
    1419 1605 
    1420 1606 
      1607void StaticIfDeclaration::importAll(Scope *sc) 
      1608{ 
      1609    // do not evaluate condition before semantic pass 
      1610} 
      1611 
      1612void StaticIfDeclaration::setScope(Scope *sc) 
      1613{ 
      1614    // do not evaluate condition before semantic pass 
      1615} 
      1616 
    1421void StaticIfDeclaration::semantic(Scope *sc) 1617void StaticIfDeclaration::semantic(Scope *sc) 
    1422{ 1618{ 
    1423    Array *d = include(sc, sd); 1619    Array *d = include(sc, sd); 
    1424 1620 
    1425    //printf("\tStaticIfDeclaration::semantic '%s', d = %p\n",toChars(), d); 1621    //printf("\tStaticIfDeclaration::semantic '%s', d = %p\n",toChars(), d); 
    1426    if (d) 1622    if (d) 
    1427    { 1623    { 
    1428    if (!addisdone) 1624    if (!addisdone) 
    1429    {   AttribDeclaration::addMember(sc, sd, 1); 1625    {   AttribDeclaration::addMember(sc, sd, 1); 
    1430        addisdone = 1; 1626        addisdone = 1; 
    1431    } 1627    } 
    1432 1628 
    1433    for (unsigned i = 0; i < d->dim; i++) 1629    for (unsigned i = 0; i < d->dim; i++) 
    1434    { 1630    { 
    1435        Dsymbol *s = (Dsymbol *)d->data[i]; 1631        Dsymbol *s = (Dsymbol *)d->data[i]; 
    1436 1632 
    1437        s->semantic(sc); 1633        s->semantic(sc); 
    1438    } 1634    } 
    1439    } 1635    } 
    1440} 1636} 
  • dmd/attrib.h

    Revision 1228:79758fd2f48a Revision 1587:def7a1d494fd
    1 1 
    2// Compiler implementation of the D programming language 2// Compiler implementation of the D programming language 
    3// Copyright (c) 1999-2007 by Digital Mars 3// Copyright (c) 1999-2009 by Digital Mars 
    4// All Rights Reserved 4// All Rights Reserved 
    5// written by Walter Bright 5// written by Walter Bright 
    6// http://www.digitalmars.com 6// http://www.digitalmars.com 
    7// License for redistribution is by either the Artistic License 7// License for redistribution is by either the Artistic License 
    8// in artistic.txt, or the GNU General Public License in gnu.txt. 8// in artistic.txt, or the GNU General Public License in gnu.txt. 
    9// See the included readme.txt for details. 9// See the included readme.txt for details. 
    10 10 
    11#ifndef DMD_ATTRIB_H 11#ifndef DMD_ATTRIB_H 
    12#define DMD_ATTRIB_H 12#define DMD_ATTRIB_H 
    13 13 
    14#ifdef __DMC__ 14#ifdef __DMC__ 
    15#pragma once 15#pragma once 
    16#endif /* __DMC__ */ 16#endif /* __DMC__ */ 
    17 17 
    18#include "dsymbol.h" 18#include "dsymbol.h" 
    19 19 
    20struct Expression; 20struct Expression; 
    21struct Statement; 21struct Statement; 
    22struct LabelDsymbol; 22struct LabelDsymbol; 
    23struct Initializer; 23struct Initializer; 
    24struct Module; 24struct Module; 
    25struct Condition; 25struct Condition; 
    26#ifdef _DH 26#ifdef _DH 
    27struct HdrGenState; 27struct HdrGenState; 
    28#endif 28#endif 
    29 29 
    30/**************************************************************/ 30/**************************************************************/ 
    31 31 
    32struct AttribDeclaration : Dsymbol 32struct AttribDeclaration : Dsymbol 
    33{ 33{ 
    34    Array *decl;    // array of Dsymbol's 34    Array *decl;    // array of Dsymbol's 
    35 35 
    36    AttribDeclaration(Array *decl); 36    AttribDeclaration(Array *decl); 
    37    virtual Array *include(Scope *sc, ScopeDsymbol *s); 37    virtual Array *include(Scope *sc, ScopeDsymbol *s); 
    38    int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 38    int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 
      39    void setScopeNewSc(Scope *sc, 
      40    unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 
      41    unsigned structalign); 
      42    void semanticNewSc(Scope *sc, 
      43    unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 
      44    unsigned structalign); 
    39    void semantic(Scope *sc); 45    void semantic(Scope *sc); 
    40    void semantic2(Scope *sc); 46    void semantic2(Scope *sc); 
    41    void semantic3(Scope *sc); 47    void semantic3(Scope *sc); 
    42    void inlineScan(); 48    void inlineScan(); 
    43    void addComment(unsigned char *comment); 49    void addComment(unsigned char *comment); 
    44    void emitComment(Scope *sc); 50    void emitComment(Scope *sc); 
    45    const char *kind(); 51    const char *kind(); 
    46    int oneMember(Dsymbol **ps); 52    int oneMember(Dsymbol **ps); 
    47    int hasPointers(); 53    int hasPointers(); 
    48    void checkCtorConstInit(); 54    void checkCtorConstInit(); 
    49    void addLocalClass(ClassDeclarations *); 55    void addLocalClass(ClassDeclarations *); 
    50    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 56    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
      57    void toJsonBuffer(OutBuffer *buf); 
    51    AttribDeclaration *isAttribDeclaration() { return this; } 58    AttribDeclaration *isAttribDeclaration() { return this; } 
    52 59 
    53#if IN_DMD 60#if IN_DMD 
    54    virtual void toObjFile(int multiobj);           // compile to .obj file 61    virtual void toObjFile(int multiobj);           // compile to .obj file 
    55    int cvMember(unsigned char *p); 62    int cvMember(unsigned char *p); 
    56#endif 63#endif 
    57 64 
    58#if IN_LLVM 65#if IN_LLVM 
    59    virtual void codegen(Ir*); 66    virtual void codegen(Ir*); 
    60#endif 67#endif 
    61}; 68}; 
    62 69 
    63struct StorageClassDeclaration: AttribDeclaration 70struct StorageClassDeclaration: AttribDeclaration 
    64{ 71{ 
    65    unsigned stc; 72    unsigned stc; 
    66 73 
    67    StorageClassDeclaration(unsigned stc, Array *decl); 74    StorageClassDeclaration(unsigned stc, Array *decl); 
    68    Dsymbol *syntaxCopy(Dsymbol *s); 75    Dsymbol *syntaxCopy(Dsymbol *s); 
      76    void setScope(Scope *sc); 
    69    void semantic(Scope *sc); 77    void semantic(Scope *sc); 
    70    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 78    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    71 79 
    72    static void stcToCBuffer(OutBuffer *buf, int stc); 80    static void stcToCBuffer(OutBuffer *buf, int stc); 
    73}; 81}; 
    74 82 
    75struct LinkDeclaration : AttribDeclaration 83struct LinkDeclaration : AttribDeclaration 
    76{ 84{ 
    77    enum LINK linkage; 85    enum LINK linkage; 
    78 86 
    79    LinkDeclaration(enum LINK p, Array *decl); 87    LinkDeclaration(enum LINK p, Array *decl); 
    80    Dsymbol *syntaxCopy(Dsymbol *s); 88    Dsymbol *syntaxCopy(Dsymbol *s); 
      89    void setScope(Scope *sc); 
    81    void semantic(Scope *sc); 90    void semantic(Scope *sc); 
    82    void semantic3(Scope *sc); 91    void semantic3(Scope *sc); 
    83    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 92    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    84    char *toChars(); 93    char *toChars(); 
    85}; 94}; 
    86 95 
    87struct ProtDeclaration : AttribDeclaration 96struct ProtDeclaration : AttribDeclaration 
    88{ 97{ 
    89    enum PROT protection; 98    enum PROT protection; 
    90 99 
    91    ProtDeclaration(enum PROT p, Array *decl); 100    ProtDeclaration(enum PROT p, Array *decl); 
    92    Dsymbol *syntaxCopy(Dsymbol *s); 101    Dsymbol *syntaxCopy(Dsymbol *s); 
    93    void semantic(Scope *sc);  102     void importAll(Scope *sc); 
    94    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);  103     void setScope(Scope *sc); 
       104     void semantic(Scope *sc); 
       105     void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
       106  
       107     static void protectionToCBuffer(OutBuffer *buf, enum PROT protection); 
    95}; 108}; 
    96 109 
    97struct AlignDeclaration : AttribDeclaration 110struct AlignDeclaration : AttribDeclaration 
    98{ 111{ 
    99    unsigned salign; 112    unsigned salign; 
    100 113 
    101    AlignDeclaration(Loc loc, unsigned sa, Array *decl); 114    AlignDeclaration(Loc loc, unsigned sa, Array *decl); 
    102    Dsymbol *syntaxCopy(Dsymbol *s); 115    Dsymbol *syntaxCopy(Dsymbol *s); 
      116    void setScope(Scope *sc); 
    103    void semantic(Scope *sc); 117    void semantic(Scope *sc); 
    104    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 118    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    105}; 119}; 
    106 120 
    107struct AnonDeclaration : AttribDeclaration 121struct AnonDeclaration : AttribDeclaration 
    108{ 122{ 
    109    int isunion; 123    int isunion; 
    110    Scope *scope;       // !=NULL means context to use   
    111    int sem;            // 1 if successful semantic() 124    int sem;            // 1 if successful semantic() 
    112 125 
    113    AnonDeclaration(Loc loc, int isunion, Array *decl); 126    AnonDeclaration(Loc loc, int isunion, Array *decl); 
    114    Dsymbol *syntaxCopy(Dsymbol *s); 127    Dsymbol *syntaxCopy(Dsymbol *s); 
    115    void semantic(Scope *sc); 128    void semantic(Scope *sc); 
    116    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 129    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    117    const char *kind(); 130    const char *kind(); 
    118}; 131}; 
    119 132 
    120struct PragmaDeclaration : AttribDeclaration 133struct PragmaDeclaration : AttribDeclaration 
    121{ 134{ 
    122    Expressions *args;      // array of Expression's 135    Expressions *args;      // array of Expression's 
    123 136 
    124    PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl); 137    PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl); 
    125    Dsymbol *syntaxCopy(Dsymbol *s); 138    Dsymbol *syntaxCopy(Dsymbol *s); 
    126    void semantic(Scope *sc); 139    void semantic(Scope *sc); 
      140    void setScope(Scope *sc); 
    127    int oneMember(Dsymbol **ps); 141    int oneMember(Dsymbol **ps); 
    128    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 142    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    129    const char *kind(); 143    const char *kind(); 
    130 144 
    131#if IN_DMD 145#if IN_DMD 
    132    void toObjFile(int multiobj);           // compile to .obj file 146    void toObjFile(int multiobj);           // compile to .obj file 
    133#endif 147#endif 
    134 148 
    135#if IN_LLVM 149#if IN_LLVM 
    136    void codegen(Ir*); 150    void codegen(Ir*); 
    137#endif 151#endif 
    138}; 152}; 
    139 153 
    140struct ConditionalDeclaration : AttribDeclaration 154struct ConditionalDeclaration : AttribDeclaration 
    141{ 155{ 
    142    Condition *condition; 156    Condition *condition; 
    143    Array *elsedecl;    // array of Dsymbol's for else block 157    Array *elsedecl;    // array of Dsymbol's for else block 
    144 158 
    145    ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl); 159    ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl); 
    146    Dsymbol *syntaxCopy(Dsymbol *s); 160    Dsymbol *syntaxCopy(Dsymbol *s); 
    147    int oneMember(Dsymbol **ps); 161    int oneMember(Dsymbol **ps); 
    148    void emitComment(Scope *sc); 162    void emitComment(Scope *sc); 
    149    Array *include(Scope *sc, ScopeDsymbol *s); 163    Array *include(Scope *sc, ScopeDsymbol *s); 
    150    void addComment(unsigned char *comment); 164    void addComment(unsigned char *comment); 
    151    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 165    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
      166    void toJsonBuffer(OutBuffer *buf); 
      167    void importAll(Scope *sc); 
      168    void setScope(Scope *sc); 
    152}; 169}; 
    153 170 
    154struct StaticIfDeclaration : ConditionalDeclaration 171struct StaticIfDeclaration : ConditionalDeclaration 
    155{ 172{ 
    156    ScopeDsymbol *sd; 173    ScopeDsymbol *sd; 
    157    int addisdone; 174    int addisdone; 
    158 175 
    159    StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl); 176    StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl); 
    160    Dsymbol *syntaxCopy(Dsymbol *s); 177    Dsymbol *syntaxCopy(Dsymbol *s); 
    161    int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 178    int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 
    162    void semantic(Scope *sc); 179    void semantic(Scope *sc); 
      180    void importAll(Scope *sc); 
      181    void setScope(Scope *sc); 
    163    const char *kind(); 182    const char *kind(); 
    164}; 183}; 
    165 184 
    166// Mixin declarations 185// Mixin declarations 
    167 186 
    168struct CompileDeclaration : AttribDeclaration 187struct CompileDeclaration : AttribDeclaration 
    169{ 188{ 
    170    Expression *exp; 189    Expression *exp; 
    171 190 
    172    ScopeDsymbol *sd; 191    ScopeDsymbol *sd; 
    173    int compiled; 192    int compiled; 
    174 193 
    175    CompileDeclaration(Loc loc, Expression *exp); 194    CompileDeclaration(Loc loc, Expression *exp); 
    176    Dsymbol *syntaxCopy(Dsymbol *s); 195    Dsymbol *syntaxCopy(Dsymbol *s); 
    177    int addMember(Scope *sc, ScopeDsymbol *sd, int memnum); 196    int addMember(Scope *sc, ScopeDsymbol *sd, int memnum); 
    178    void compileIt(Scope *sc); 197    void compileIt(Scope *sc); 
    179    void semantic(Scope *sc); 198    void semantic(Scope *sc); 
    180    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 199    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    181}; 200}; 
    182 201 
  • dmd/cast.c

    Revision 1367:8026319762be Revision 1587:def7a1d494fd
    1061    e->values = (Expressions *)values->copy(); 1061    e->values = (Expressions *)values->copy(); 
    1062    assert(keys->dim == values->dim); 1062    assert(keys->dim == values->dim); 
    1063    for (size_t i = 0; i < keys->dim; i++) 1063    for (size_t i = 0; i < keys->dim; i++) 
    1064    {   Expression *ex = (Expression *)values->data[i]; 1064    {   Expression *ex = (Expression *)values->data[i]; 
    1065        ex = ex->castTo(sc, tb->nextOf()); 1065        ex = ex->castTo(sc, tb->nextOf()); 
    1066        e->values->data[i] = (void *)ex; 1066        e->values->data[i] = (void *)ex; 
    1067 1067 
    1068        ex = (Expression *)keys->data[i]; 1068        ex = (Expression *)keys->data[i]; 
    1069        ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 1069        ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 
    1070        e->keys->data[i] = (void *)ex; 1070        e->keys->data[i] = (void *)ex; 
    1071    } 1071    } 
    1072    e->type = t; 1072    e->type = t; 
    1073    return e; 1073    return e; 
    1074    } 1074    } 
    1075L1: 1075L1: 
    1076    return e->Expression::castTo(sc, t); 1076    return e->Expression::castTo(sc, t); 
    1077} 1077} 
    1078 1078 
    1079Expression *SymOffExp::castTo(Scope *sc, Type *t) 1079Expression *SymOffExp::castTo(Scope *sc, Type *t) 
    1080{ 1080{ 
    1081    Type *tb;   
    1082   
    1083#if 0 1081#if 0 
    1084    printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 1082    printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 
    1085    toChars(), type->toChars(), t->toChars()); 1083    toChars(), type->toChars(), t->toChars()); 
    1086#endif 1084#endif 
    1087    Expression *e = this; 1085    Expression *e = this; 
    1088 1086 
    1089    tb = t->toBasetype(); 1087    Type *tb = t->toBasetype(); 
    1090    type = type->toBasetype(); 1088    Type *typeb = type->toBasetype(); 
    1091    if (tb != type1089    if (tb != typeb
    1092    { 1090    { 
    1093    // Look for pointers to functions where the functions are overloaded. 1091    // Look for pointers to functions where the functions are overloaded. 
    1094    FuncDeclaration *f; 1092    FuncDeclaration *f; 
    1095 1093 
    1096    if (type->ty == Tpointer && type->next->ty == Tfunction && 1094    if (typeb->ty == Tpointer && typeb->next->ty == Tfunction && 
    1097        tb->ty == Tpointer && tb->next->ty == Tfunction) 1095        tb->ty == Tpointer && tb->next->ty == Tfunction) 
    1098    { 1096    { 
    1099        f = var->isFuncDeclaration(); 1097        f = var->isFuncDeclaration(); 
    1100        if (f) 1098        if (f) 
    1101        { 1099        { 
    1102        f = f->overloadExactMatch(tb->next, m); 1100        f = f->overloadExactMatch(tb->next, m); 
    1103        if (f) 1101        if (f) 
    1104        { 1102        { 
    1105            e = new SymOffExp(loc, f, 0);  1103 #if DMDV2 
    1106            e->type = t;  1104             if (tb->ty == Tdelegate) 
       1105             { 
       1106             if (f->needThis() && hasThis(sc)) 
       1107             { 
       1108                 e = new DelegateExp(loc, new ThisExp(loc), f); 
       1109                 e = e->semantic(sc); 
       1110             } 
       1111             else if (f->isNested()) 
       1112             { 
       1113                 e = new DelegateExp(loc, new IntegerExp(0), f); 
       1114                 e = e->semantic(sc); 
       1115             } 
       1116             else if (f->needThis()) 
       1117             {   error("no 'this' to create delegate for %s", f->toChars()); 
       1118                 e = new ErrorExp(); 
       1119             } 
       1120             else 
       1121             {   error("cannot cast from function pointer to delegate"); 
       1122                 e = new ErrorExp(); 
       1123             } 
       1124             } 
       1125             else 
       1126 #endif 
       1127             { 
       1128             e = new SymOffExp(loc, f, 0); 
       1129             e->type = t; 
       1130             } 
       1131 #if DMDV2 
       1132             f->tookAddressOf++; 
       1133 #endif 
    1107            return e; 1134            return e; 
    1108        } 1135        } 
    1109        } 1136        } 
    1110    } 1137    } 
    1111    e = Expression::castTo(sc, t); 1138    e = Expression::castTo(sc, t); 
    1112    } 1139    } 
    1113    e->type = t;  1140     else 
       1141     { 
       1142     e->type = t; 
       1143     } 
    1114    return e; 1144    return e; 
    1115} 1145} 
    1116 1146 
    1117Expression *DelegateExp::castTo(Scope *sc, Type *t) 1147Expression *DelegateExp::castTo(Scope *sc, Type *t) 
    1118{ 1148{ 
    1119    Type *tb; 1149    Type *tb; 
    1120#if 0 1150#if 0 
    1121    printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 1151    printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 
    1122    toChars(), type->toChars(), t->toChars()); 1152    toChars(), type->toChars(), t->toChars()); 
    1123#endif 1153#endif 
    1124    Expression *e = this; 1154    Expression *e = this; 
    1125    static char msg[] = "cannot form delegate due to covariant return type"; 1155    static char msg[] = "cannot form delegate due to covariant return type"; 
    1126 1156 
    1127    tb = t->toBasetype(); 1157    tb = t->toBasetype(); 
    1128    type = type->toBasetype(); 1158    type = type->toBasetype(); 
    1129    if (tb != type) 1159    if (tb != type) 
    1130    { 1160    { 
    1131    // Look for delegates to functions where the functions are overloaded. 1161    // Look for delegates to functions where the functions are overloaded. 
    1132    FuncDeclaration *f; 1162    FuncDeclaration *f; 
    1133 1163 
      
    1467    else if (t1->ty == Tsarray && t2->ty == Tsarray && 1497    else if (t1->ty == Tsarray && t2->ty == Tsarray && 
    1468         e2->implicitConvTo(t1->nextOf()->arrayOf())) 1498         e2->implicitConvTo(t1->nextOf()->arrayOf())) 
    1469    { 1499    { 
    1470     Lx1: 1500     Lx1: 
    1471    t = t1->nextOf()->arrayOf(); 1501    t = t1->nextOf()->arrayOf(); 
    1472    e1 = e1->castTo(sc, t); 1502    e1 = e1->castTo(sc, t); 
    1473    e2 = e2->castTo(sc, t); 1503    e2 = e2->castTo(sc, t); 
    1474    } 1504    } 
    1475    else if (t1->ty == Tsarray && t2->ty == Tsarray && 1505    else if (t1->ty == Tsarray && t2->ty == Tsarray && 
    1476         e1->implicitConvTo(t2->nextOf()->arrayOf())) 1506         e1->implicitConvTo(t2->nextOf()->arrayOf())) 
    1477    { 1507    { 
    1478     Lx2: 1508     Lx2: 
    1479    t = t2->nextOf()->arrayOf(); 1509    t = t2->nextOf()->arrayOf(); 
    1480    e1 = e1->castTo(sc, t); 1510    e1 = e1->castTo(sc, t); 
    1481    e2 = e2->castTo(sc, t); 1511    e2 = e2->castTo(sc, t); 
    1482    } 1512    } 
    1483    else if (t1->isintegral() && t2->isintegral()) 1513    else if (t1->isintegral() && t2->isintegral()) 
    1484    { 1514    { 
    1485    assert(0); 1515    assert(0); 
    1486    } 1516    } 
    1487    else if (e1->op == TOKslice && t1->ty == Tarray && 1517    else if (e1->isArrayOperand() && t1->ty == Tarray && 
    1488         e2->implicitConvTo(t1->nextOf())) 1518         e2->implicitConvTo(t1->nextOf())) 
    1489    {   // T[] op T 1519    {   // T[] op T 
    1490    e2 = e2->castTo(sc, t1->nextOf()); 1520    e2 = e2->castTo(sc, t1->nextOf()); 
    1491    t = t1->nextOf()->arrayOf(); 1521    t = t1->nextOf()->arrayOf(); 
    1492    } 1522    } 
    1493    else if (e2->op == TOKslice && t2->ty == Tarray && 1523    else if (e2->isArrayOperand() && t2->ty == Tarray && 
    1494         e1->implicitConvTo(t2->nextOf())) 1524         e1->implicitConvTo(t2->nextOf())) 
    1495    {   // T op T[] 1525    {   // T op T[] 
    1496    e1 = e1->castTo(sc, t2->nextOf()); 1526    e1 = e1->castTo(sc, t2->nextOf()); 
    1497    t = t2->nextOf()->arrayOf(); 1527    t = t2->nextOf()->arrayOf(); 
    1498 1528 
    1499    //printf("test %s\n", e->toChars()); 1529    //printf("test %s\n", e->toChars()); 
    1500    e1 = e1->optimize(WANTvalue); 1530    e1 = e1->optimize(WANTvalue); 
    1501    if (isCommutative() && e1->isConst()) 1531    if (isCommutative() && e1->isConst()) 
    1502    {   /* Swap operands to minimize number of functions generated 1532    {   /* Swap operands to minimize number of functions generated 
    1503         */ 1533         */ 
    1504        //printf("swap %s\n", e->toChars()); 1534        //printf("swap %s\n", e->toChars()); 
    1505        Expression *tmp = e1; 1535        Expression *tmp = e1; 
    1506        e1 = e2; 1536        e1 = e2; 
    1507        e2 = tmp; 1537        e2 = tmp; 
    1508    } 1538    } 
    1509    } 1539    } 
    1510    else 1540    else 
    1511    { 1541    { 
    1512     Lincompatible: 1542     Lincompatible: 
    1513    incompatibleTypes(); 1543    incompatibleTypes(); 
  • dmd/class.c

    Revision 1530:05c235309d6f Revision 1587:def7a1d494fd
    1 1 
    2// Compiler implementation of the D programming language 2// Compiler implementation of the D programming language 
    3// Copyright (c) 1999-2008 by Digital Mars 3// Copyright (c) 1999-2009 by Digital Mars 
    4// All Rights Reserved 4// All Rights Reserved 
    5// written by Walter Bright 5// written by Walter Bright 
    6// http://www.digitalmars.com 6// http://www.digitalmars.com 
    7// License for redistribution is by either the Artistic License 7// License for redistribution is by either the Artistic License 
    8// in artistic.txt, or the GNU General Public License in gnu.txt. 8// in artistic.txt, or the GNU General Public License in gnu.txt. 
    9// See the included readme.txt for details. 9// See the included readme.txt for details. 
    10 10 
    11#include <stdio.h> 11#include <stdio.h> 
    12#include <stdlib.h> 12#include <stdlib.h> 
    13#include <assert.h> 13#include <assert.h> 
    14 14 
    15#include "root.h" 15#include "root.h" 
    16#include "rmem.h" 16#include "rmem.h" 
    17 17 
    18#include "enum.h" 18#include "enum.h" 
    19#include "init.h" 19#include "init.h" 
    20#include "attrib.h" 20#include "attrib.h" 
    21#include "declaration.h" 21#include "declaration.h" 
    22#include "aggregate.h" 22#include "aggregate.h" 
    23#include "id.h" 23#include "id.h" 
      
    144        } 144        } 
    145 145 
    146        if (id == Id::TypeInfo_Tuple) 146        if (id == Id::TypeInfo_Tuple) 
    147        {   if (Type::typeinfotypelist) 147        {   if (Type::typeinfotypelist) 
    148            Type::typeinfotypelist->error("%s", msg); 148            Type::typeinfotypelist->error("%s", msg); 
    149        Type::typeinfotypelist = this; 149        Type::typeinfotypelist = this; 
    150        } 150        } 
    151 151 
    152#if DMDV2 152#if DMDV2 
    153        if (id == Id::TypeInfo_Const) 153        if (id == Id::TypeInfo_Const) 
    154        {   if (Type::typeinfoconst) 154        {   if (Type::typeinfoconst) 
    155            Type::typeinfoconst->error("%s", msg); 155            Type::typeinfoconst->error("%s", msg); 
    156        Type::typeinfoconst = this; 156        Type::typeinfoconst = this; 
    157        } 157        } 
    158 158 
    159        if (id == Id::TypeInfo_Invariant) 159        if (id == Id::TypeInfo_Invariant) 
    160        {   if (Type::typeinfoinvariant) 160        {   if (Type::typeinfoinvariant) 
    161            Type::typeinfoinvariant->error("%s", msg); 161            Type::typeinfoinvariant->error("%s", msg); 
    162        Type::typeinfoinvariant = this; 162        Type::typeinfoinvariant = this; 
    163        } 163        } 
      164 
      165        if (id == Id::TypeInfo_Shared) 
      166        {   if (Type::typeinfoshared) 
      167            Type::typeinfoshared->error("%s", msg); 
      168        Type::typeinfoshared = this; 
      169        } 
    164#endif 170#endif 
    165    } 171    } 
    166 172 
    167    if (id == Id::Object) 173    if (id == Id::Object) 
    168    {   if (object) 174    {   if (object) 
    169        object->error("%s", msg); 175        object->error("%s", msg); 
    170        object = this; 176        object = this; 
    171    } 177    } 
    172 178 
    173    if (id == Id::ClassInfo) 179    if (id == Id::ClassInfo) 
    174    {   if (classinfo) 180    {   if (classinfo) 
    175        classinfo->error("%s", msg); 181        classinfo->error("%s", msg); 
    176        classinfo = this; 182        classinfo = this; 
    177    } 183    } 
    178 184 
    179    if (id == Id::ModuleInfo) 185    if (id == Id::ModuleInfo) 
    180    {   if (Module::moduleinfo) 186    {   if (Module::moduleinfo) 
    181        Module::moduleinfo->error("%s", msg); 187        Module::moduleinfo->error("%s", msg); 
    182        Module::moduleinfo = this; 188        Module::moduleinfo = this; 
    183    } 189    } 
      
    209    BaseClass *b = (BaseClass *)this->baseclasses.data[i]; 215    BaseClass *b = (BaseClass *)this->baseclasses.data[i]; 
    210    BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); 216    BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); 
    211    cd->baseclasses.data[i] = b2; 217    cd->baseclasses.data[i] = b2; 
    212    } 218    } 
    213 219 
    214    ScopeDsymbol::syntaxCopy(cd); 220    ScopeDsymbol::syntaxCopy(cd); 
    215    return cd; 221    return cd; 
    216} 222} 
    217 223 
    218void ClassDeclaration::semantic(Scope *sc) 224void ClassDeclaration::semantic(Scope *sc) 
    219{   int i; 225{   int i; 
    220    unsigned offset; 226    unsigned offset; 
    221 227 
    222    //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 228    //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 
    223    //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); 229    //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); 
    224    //printf("sc->stc = %x\n", sc->stc); 230    //printf("sc->stc = %x\n", sc->stc); 
    225 231 
    226    //{ static int n;  if (++n == 20) *(char*)0=0; } 232    //{ static int n;  if (++n == 20) *(char*)0=0; } 
    227 233 
    228    if (!ident)     // if anonymous class 234    if (!ident)     // if anonymous class 
    229    {   char *id = "__anonclass"; 235    {   const char *id = "__anonclass"; 
    230 236 
    231    ident = Identifier::generateId(id); 237    ident = Identifier::generateId(id); 
    232    } 238    } 
    233 239 
    234    if (!scope240    if (!sc
    235    { 241    sc = scope; 
    236   if (!parent && sc->parent && !sc->parent->isModule()) 242    if (!parent && sc->parent && !sc->parent->isModule()) 
    237        parent = sc->parent; 243    parent = sc->parent; 
    238 244 
    239   type = type->semantic(loc, sc); 245    type = type->semantic(loc, sc); 
    240   handle = handle->semantic(loc, sc)246    handle = type
    241    } 247 
    242    if (!members)           // if forward reference 248    if (!members)           // if forward reference 
    243    {   //printf("\tclass '%s' is forward referenced\n", toChars()); 249    {   //printf("\tclass '%s' is forward referenced\n", toChars()); 
    244    return; 250    return; 
    245    } 251    } 
    246    if (symtab) 252    if (symtab) 
    247    {   if (!scope) 253    {   if (!scope) 
    248    {   //printf("\tsemantic for '%s' is already completed\n", toChars()); 254    {   //printf("\tsemantic for '%s' is already completed\n", toChars()); 
    249        return;     // semantic() already completed 255        return;     // semantic() already completed 
    250    } 256    } 
    251    } 257    } 
    252    else 258    else 
    253    symtab = new DsymbolTable(); 259    symtab = new DsymbolTable(); 
    254 260 
    255    Scope *scx = NULL; 261    Scope *scx = NULL; 
    256    if (scope) 262    if (scope) 
    257    {   sc = scope; 263    {   sc = scope; 
    258    scx = scope;        // save so we don't make redundant copies 264    scx = scope;        // save so we don't make redundant copies 
    259    scope = NULL; 265    scope = NULL; 
    260    } 266    } 
    261#ifdef IN_GCC 267#ifdef IN_GCC 
      
    312            // Deriving from deprecated class makes this one deprecated too 318            // Deriving from deprecated class makes this one deprecated too 
    313            isdeprecated = 1; 319            isdeprecated = 1; 
    314 320 
    315            tc->checkDeprecated(loc, sc); 321            tc->checkDeprecated(loc, sc); 
    316        } 322        } 
    317        } 323        } 
    318 324 
    319        if (tc->sym->isInterfaceDeclaration()) 325        if (tc->sym->isInterfaceDeclaration()) 
    320        ; 326        ; 
    321        else 327        else 
    322        { 328        { 
    323        for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) 329        for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) 
    324        { 330        { 
    325            if (cdb == this) 331            if (cdb == this) 
    326            { 332            { 
    327            error("circular inheritance"); 333            error("circular inheritance"); 
    328            baseclasses.remove(0); 334            baseclasses.remove(0); 
    329            goto L7; 335            goto L7; 
    330            } 336            } 
    331        } 337        } 
      338        if (!tc->sym->symtab || tc->sym->sizeok == 0) 
      339        {   // Try to resolve forward reference 
      340            if (sc->mustsemantic && tc->sym->scope) 
      341            tc->sym->semantic(NULL); 
      342        } 
    332        if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 343        if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 
    333        { 344        { 
      345            //printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars()); 
    334            //error("forward reference of base class %s", baseClass->toChars()); 346            //error("forward reference of base class %s", baseClass->toChars()); 
    335            // Forward reference of base class, try again later 347            // Forward reference of base class, try again later 
    336            //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); 348            //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); 
    337            scope = scx ? scx : new Scope(*sc); 349            scope = scx ? scx : new Scope(*sc); 
    338            scope->setNoFree(); 350            scope->setNoFree(); 
      351            if (tc->sym->scope) 
      352                tc->sym->scope->module->addDeferredSemantic(tc->sym); 
    339            scope->module->addDeferredSemantic(this); 353            scope->module->addDeferredSemantic(this); 
    340            return; 354            return; 
    341        } 355        } 
    342        else 356        else 
    343        {   baseClass = tc->sym; 357        {   baseClass = tc->sym; 
    344            b->base = baseClass; 358            b->base = baseClass; 
    345        } 359        } 
    346         L7: ; 360         L7: ; 
    347        } 361        } 
    348    } 362    } 
    349    } 363    } 
    350 364 
    351    // Treat the remaining entries in baseclasses as interfaces 365    // Treat the remaining entries in baseclasses as interfaces 
    352    // Check for errors, handle forward references 366    // Check for errors, handle forward references 
    353    for (i = (baseClass ? 1 : 0); i < baseclasses.dim; ) 367    for (i = (baseClass ? 1 : 0); i < baseclasses.dim; ) 
    354    {   TypeClass *tc; 368    {   TypeClass *tc; 
    355    BaseClass *b; 369    BaseClass *b; 
    356    Type *tb; 370    Type *tb; 
    357 371 
    358    b = (BaseClass *)baseclasses.data[i]; 372    b = (BaseClass *)baseclasses.data[i]; 
      
    372    { 386    { 
    373        if (tc->sym->isDeprecated()) 387        if (tc->sym->isDeprecated()) 
    374        { 388        { 
    375        if (!isDeprecated()) 389        if (!isDeprecated()) 
    376        { 390        { 
    377            // Deriving from deprecated class makes this one deprecated too 391            // Deriving from deprecated class makes this one deprecated too 
    378            isdeprecated = 1; 392            isdeprecated = 1; 
    379 393 
    380            tc->checkDeprecated(loc, sc); 394            tc->checkDeprecated(loc, sc); 
    381        } 395        } 
    382        } 396        } 
    383 397 
    384        // Check for duplicate interfaces 398        // Check for duplicate interfaces 
    385        for (size_t j = (baseClass ? 1 : 0); j < i; j++) 399        for (size_t j = (baseClass ? 1 : 0); j < i; j++) 
    386        { 400        { 
    387        BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 401        BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 
    388        if (b2->base == tc->sym) 402        if (b2->base == tc->sym) 
    389            error("inherits from duplicate interface %s", b2->base->toChars()); 403            error("inherits from duplicate interface %s", b2->base->toChars()); 
    390        } 404        } 
    391 405 
      406        if (!tc->sym->symtab) 
      407        {   // Try to resolve forward reference 
      408        if (sc->mustsemantic && tc->sym->scope) 
      409            tc->sym->semantic(NULL); 
      410        } 
      411 
    392        b->base = tc->sym; 412        b->base = tc->sym; 
    393        if (!b->base->symtab || b->base->scope) 413        if (!b->base->symtab || b->base->scope) 
    394        { 414        { 
    395        //error("forward reference of base class %s", baseClass->toChars()); 415        //error("forward reference of base class %s", baseClass->toChars()); 
    396        // Forward reference of base, try again later 416        // Forward reference of base, try again later 
    397        //printf("\ttry later, forward reference of base %s\n", baseClass->toChars()); 417        //printf("\ttry later, forward reference of base %s\n", baseClass->toChars()); 
    398        scope = scx ? scx : new Scope(*sc); 418        scope = scx ? scx : new Scope(*sc); 
    399        scope->setNoFree(); 419        scope->setNoFree(); 
      420        if (tc->sym->scope) 
      421            tc->sym->scope->module->addDeferredSemantic(tc->sym); 
    400        scope->module->addDeferredSemantic(this); 422        scope->module->addDeferredSemantic(this); 
    401        return; 423        return; 
    402        } 424        } 
    403    } 425    } 
    404    i++; 426    i++; 
    405    } 427    } 
    406 428 
    407 429 
    408    // If no base class, and this is not an Object, use Object as base class 430    // If no base class, and this is not an Object, use Object as base class 
    409    if (!baseClass && ident != Id::Object) 431    if (!baseClass && ident != Id::Object) 
    410    { 432    { 
    411    // BUG: what if Object is redefined in an inner scope? 433    // BUG: what if Object is redefined in an inner scope? 
    412    Type *tbase = new TypeIdentifier(0, Id::Object); 434    Type *tbase = new TypeIdentifier(0, Id::Object); 
    413    BaseClass *b; 435    BaseClass *b; 
    414    TypeClass *tc; 436    TypeClass *tc; 
    415    Type *bt; 437    Type *bt; 
    416 438 
    417    if (!object) 439    if (!object) 
    418    { 440    { 
    419        error("missing or corrupt object.d"); 441        error("missing or corrupt object.d"); 
      
    483        if (toParent2()) 505        if (toParent2()) 
    484        { 506        { 
    485            error("is nested within %s, but super class %s is nested within %s", 507            error("is nested within %s, but super class %s is nested within %s", 
    486            toParent2()->toChars(), 508            toParent2()->toChars(), 
    487            baseClass->toChars(), 509            baseClass->toChars(), 
    488            baseClass->toParent2()->toChars()); 510            baseClass->toParent2()->toChars()); 
    489        } 511        } 
    490        else 512        else 
    491        { 513        { 
    492            error("is not nested, but super class %s is nested within %s", 514            error("is not nested, but super class %s is nested within %s", 
    493            baseClass->toChars(), 515            baseClass->toChars(), 
    494            baseClass->toParent2()->toChars()); 516            baseClass->toParent2()->toChars()); 
    495        } 517        } 
    496        isnested = 0; 518        isnested = 0; 
    497        } 519        } 
    498    } 520    } 
    499    else if (!(storage_class & STCstatic)) 521    else if (!(storage_class & STCstatic)) 
    500    {   Dsymbol *s = toParent2(); 522    {   Dsymbol *s = toParent2(); 
    501        if (s) 523        if (s) 
    502        { 524        { 
    503        ClassDeclaration *cd = s->isClassDeclaration(); 525        AggregateDeclaration *ad = s->isClassDeclaration(); 
    504        FuncDeclaration *fd = s->isFuncDeclaration(); 526        FuncDeclaration *fd = s->isFuncDeclaration(); 
    505 527 
    506 528 
    507        if (cd || fd) 529        if (ad || fd) 
    508        {   isnested = 1; 530        {   isnested = 1; 
    509            Type *t; 531            Type *t; 
    510            if (cd) 532            if (ad) 
    511            t = cd->type; 533            t = ad->handle; 
    512            else if (fd) 534            else if (fd) 
    513            {   AggregateDeclaration *ad = fd->isMember2(); 535            {   AggregateDeclaration *ad = fd->isMember2(); 
    514            if (ad) 536            if (ad) 
    515                t = ad->handle; 537                t = ad->handle; 
    516            else 538            else 
    517            { 539            { 
    518                t = new TypePointer(Type::tvoid); 540                t = new TypePointer(Type::tvoid); 
    519                t = t->semantic(0, sc); 541                t = t->semantic(0, sc); 
    520            } 542            } 
    521            } 543            } 
    522            else 544            else 
    523            assert(0); 545            assert(0); 
    524            assert(!vthis); 546            assert(!vthis); 
    525            vthis = new ThisDeclaration(loc, t); 547            vthis = new ThisDeclaration(loc, t); 
    526            members->push(vthis); 548            members->push(vthis); 
    527        } 549        } 
    528        } 550        } 
    529    } 551    } 
    530    } 552    } 
    531 553 
      
    547#if _WIN32 569#if _WIN32 
    548    sc->linkage = LINKwindows; 570    sc->linkage = LINKwindows; 
    549#else 571#else 
    550    /* This enables us to use COM objects under Linux and 572    /* This enables us to use COM objects under Linux and 
    551     * work with things like XPCOM 573     * work with things like XPCOM 
    552     */ 574     */ 
    553    sc->linkage = LINKc; 575    sc->linkage = LINKc; 
    554#endif 576#endif 
    555    } 577    } 
    556    sc->protection = PROTpublic; 578    sc->protection = PROTpublic; 
    557    sc->explicitProtection = 0; 579    sc->explicitProtection = 0; 
    558    sc->structalign = 8; 580    sc->structalign = 8; 
    559    structalign = sc->structalign; 581    structalign = sc->structalign; 
    560    if (baseClass) 582    if (baseClass) 
    561    {   sc->offset = baseClass->structsize; 583    {   sc->offset = baseClass->structsize; 
    562    alignsize = baseClass->alignsize; 584    alignsize = baseClass->alignsize; 
    563//  if (isnested) 585//  if (isnested) 
    564//      sc->offset += PTRSIZE;  // room for uplevel context pointer 586//      sc->offset += PTRSIZE;  // room for uplevel context pointer 
    565    } 587    } 
    566    else 588    else 
    567    {   sc->offset = PTRSIZE * 2;   // allow room for vptr[] and monitor 589    {   sc->offset = PTRSIZE * 2;   // allow room for __vptr and __monitor 
    568    alignsize = PTRSIZE; 590    alignsize = PTRSIZE; 
    569    } 591    } 
    570    structsize = sc->offset; 592    structsize = sc->offset; 
    571    Scope scsave = *sc; 593    Scope scsave = *sc; 
    572    int members_dim = members->dim; 594    int members_dim = members->dim; 
    573    sizeok = 0; 595    sizeok = 0; 
    574    for (i = 0; i < members_dim; i++) 596    for (i = 0; i < members_dim; i++) 
    575    { 597    { 
    576    Dsymbol *s = (Dsymbol *)members->data[i]; 598    Dsymbol *s = (Dsymbol *)members->data[i]; 
    577    s->semantic(sc); 599    s->semantic(sc); 
    578    } 600    } 
    579 601 
    580    if (sizeok == 2) 602    if (sizeok == 2) 
    581    {   // semantic() failed because of forward references. 603    {   // semantic() failed because of forward references. 
    582    // Unwind what we did, and defer it for later 604    // Unwind what we did, and defer it for later 
    583    fields.setDim(0); 605    fields.setDim(0); 
    584    structsize = 0; 606    structsize = 0; 
    585    alignsize = 0; 607    alignsize = 0; 
    586    structalign = 0; 608    structalign = 0; 
    587 609 
      
    686} 708} 
    687 709 
    688void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 710void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    689{ 711{ 
    690    if (!isAnonymous()) 712    if (!isAnonymous()) 
    691    { 713    { 
    692    buf->printf("%s ", kind()); 714    buf->printf("%s ", kind()); 
    693    buf->writestring(toChars()); 715    buf->writestring(toChars()); 
    694    if (baseclasses.dim) 716    if (baseclasses.dim) 
    695        buf->writestring(" : "); 717        buf->writestring(" : "); 
    696    } 718    } 
    697    for (int i = 0; i < baseclasses.dim; i++) 719    for (int i = 0; i < baseclasses.dim; i++) 
    698    { 720    { 
    699    BaseClass *b = (BaseClass *)baseclasses.data[i]; 721    BaseClass *b = (BaseClass *)baseclasses.data[i]; 
    700 722 
    701    if (i) 723    if (i) 
    702        buf->writeByte(','); 724        buf->writeByte(','); 
    703    //buf->writestring(b->base->ident->toChars()); 725    //buf->writestring(b->base->ident->toChars()); 
    704    b->type->toCBuffer(buf, NULL, hgs); 726    b->type->toCBuffer(buf, NULL, hgs); 
    705    } 727    } 
    706    buf->writenl();  728     if (members) 
    707    buf->writeByte('{');  729     { 
    708    buf->writenl();  730     buf->writenl(); 
    709    for (int i = 0; i < members->dim; i++)  731     buf->writeByte('{'); 
    710    {  732     buf->writenl(); 
    711    Dsymbol *s = (Dsymbol *)members->data[i];  733     for (int i = 0; i < members->dim; i++) 
    712  734     { 
    713    buf->writestring("    ");  735         Dsymbol *s = (Dsymbol *)members->data[i]; 
    714    s->toCBuffer(buf, hgs);  736  
    715    }  737         buf->writestring("    "); 
    716    buf->writestring("}");  738         s->toCBuffer(buf, hgs); 
       739     } 
       740     buf->writestring("}"); 
       741     } 
       742     else 
       743     buf->writeByte(';'); 
    717    buf->writenl(); 744    buf->writenl(); 
    718} 745} 
    719 746 
    720#if 0 747#if 0 
    721void ClassDeclaration::defineRef(Dsymbol *s) 748void ClassDeclaration::defineRef(Dsymbol *s) 
    722{ 749{ 
    723    ClassDeclaration *cd; 750    ClassDeclaration *cd; 
    724 751 
    725    AggregateDeclaration::defineRef(s); 752    AggregateDeclaration::defineRef(s); 
    726    cd = s->isClassDeclaration(); 753    cd = s->isClassDeclaration(); 
    727    baseType = cd->baseType; 754    baseType = cd->baseType; 
    728    cd->baseType = NULL; 755    cd->baseType = NULL; 
    729} 756} 
    730#endif 757#endif 
    731 758 
    732/********************************************* 759/********************************************* 
    733 * Determine if 'this' is a base class of cd. 760 * Determine if 'this' is a base class of cd. 
    734 * This is used to detect circular inheritance only. 761 * This is used to detect circular inheritance only. 
    735 */ 762 */ 
    736 763 
      
    763        return 1; 790        return 1; 
    764 791 
    765    /* cd->baseClass might not be set if cd is forward referenced. 792    /* cd->baseClass might not be set if cd is forward referenced. 
    766     */ 793     */ 
    767    if (!cd->baseClass && cd->baseclasses.dim && !cd->isInterfaceDeclaration()) 794    if (!cd->baseClass && cd->baseclasses.dim && !cd->isInterfaceDeclaration()) 
    768    { 795    { 
    769        cd->error("base class is forward referenced by %s", toChars()); 796        cd->error("base class is forward referenced by %s", toChars()); 
    770    } 797    } 
    771 798 
    772    cd = cd->baseClass; 799    cd = cd->baseClass; 
    773    } 800    } 
    774    return 0; 801    return 0; 
    775} 802} 
    776 803 
    777Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 804Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 
    778{ 805{ 
    779    Dsymbol *s; 806    Dsymbol *s; 
    780 807    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 
    781    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 808 
    782    if (scope) 809    if (scope) 
    783    semantic(scope);  810     {   Scope *sc = scope; 
       811     sc->mustsemantic++; 
       812     semantic(sc); 
       813     sc->mustsemantic--; 
       814     } 
    784 815 
    785    if (!members || !symtab || scope) 816    if (!members || !symtab || scope) 
    786    {   error("is forward referenced when looking for '%s'", ident->toChars());  817     { 
       818     error("is forward referenced when looking for '%s'", ident->toChars()); 
    787    //*(char*)0=0; 819    //*(char*)0=0; 
    788    return NULL; 820    return NULL; 
    789    } 821    } 
    790 822 
    791    s = ScopeDsymbol::search(loc, ident, flags); 823    s = ScopeDsymbol::search(loc, ident, flags); 
    792    if (!s) 824    if (!s) 
    793    { 825    { 
    794    // Search bases classes in depth-first, left to right order 826    // Search bases classes in depth-first, left to right order 
    795 827 
    796    int i; 828    int i; 
    797 829 
    798    for (i = 0; i < baseclasses.dim; i++) 830    for (i = 0; i < baseclasses.dim; i++) 
    799    { 831    { 
    800        BaseClass *b = (BaseClass *)baseclasses.data[i]; 832        BaseClass *b = (BaseClass *)baseclasses.data[i]; 
    801 833 
    802        if (b->base) 834        if (b->base) 
    803        { 835        { 
    804        if (!b->base->symtab) 836        if (!b->base->symtab) 
    805            error("base %s is forward referenced", b->base->ident->toChars()); 837            error("base %s is forward referenced", b->base->ident->toChars()); 
    806        else 838        else 
      
    814        } 846        } 
    815    } 847    } 
    816    } 848    } 
    817    return s; 849    return s; 
    818} 850} 
    819 851 
    820/********************************************************** 852/********************************************************** 
    821 * fd is in the vtbl[] for this class. 853 * fd is in the vtbl[] for this class. 
    822 * Return 1 if function is hidden (not findable through search). 854 * Return 1 if function is hidden (not findable through search). 
    823 */ 855 */ 
    824 856 
    825#if DMDV2 857#if DMDV2 
    826int isf(void *param, FuncDeclaration *fd) 858int isf(void *param, FuncDeclaration *fd) 
    827{ 859{ 
    828    //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); 860    //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); 
    829    return param == fd; 861    return param == fd; 
    830} 862} 
    831 863 
    832int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 864int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 
    833{ 865{ 
    834    //printf("ClassDeclaration::isFuncHidden(%s)\n", fd->toChars()); 866    //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars()); 
    835    Dsymbol *s = search(0, fd->ident, 4|2); 867    Dsymbol *s = search(0, fd->ident, 4|2); 
    836    if (!s) 868    if (!s) 
    837    {   //printf("not found\n"); 869    {   //printf("not found\n"); 
    838    /* Because, due to a hack, if there are multiple definitions 870    /* Because, due to a hack, if there are multiple definitions 
    839     * of fd->ident, NULL is returned. 871     * of fd->ident, NULL is returned. 
    840     */ 872     */ 
    841    return 0; 873    return 0; 
    842    } 874    } 
    843    FuncDeclaration *fdstart = s->toAlias()->isFuncDeclaration(); 875    FuncDeclaration *fdstart = s->toAlias()->isFuncDeclaration(); 
    844    //printf("%s fdstart = %p\n", s->kind(), fdstart); 876    //printf("%s fdstart = %p\n", s->kind(), fdstart); 
    845    return !overloadApply(getModule(), fdstart, &isf, fd); 877    return !overloadApply(getModule(), fdstart, &isf, fd); 
    846} 878} 
    847#endif 879#endif 
    848 880 
    849/**************** 881/**************** 
    850 * Find virtual function matching identifier and type. 882 * Find virtual function matching identifier and type. 
    851 * Used to build virtual function tables for interface implementations. 883 * Used to build virtual function tables for interface implementations. 
    852 */ 884 */ 
    853 885 
    854FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) 886FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) 
      
    899        com = 1; 931        com = 1; 
    900 932 
    901    vtblInterfaces->push(b); 933    vtblInterfaces->push(b); 
    902    b->copyBaseInterfaces(vtblInterfaces); 934    b->copyBaseInterfaces(vtblInterfaces); 
    903    } 935    } 
    904} 936} 
    905 937 
    906/**************************************** 938/**************************************** 
    907 */ 939 */ 
    908 940 
    909int ClassDeclaration::isCOMclass() 941int ClassDeclaration::isCOMclass() 
    910{ 942{ 
    911    return com; 943    return com; 
    912} 944} 
    913 945 
    914int ClassDeclaration::isCOMinterface() 946int ClassDeclaration::isCOMinterface() 
    915{ 947{ 
    916    return 0; 948    return 0; 
    917} 949} 
    918 950 
      951#if DMDV2 
      952int ClassDeclaration::isCPPinterface() 
      953{ 
      954    return 0; 
      955} 
      956#endif 
      957 
    919 958 
    920/**************************************** 959/**************************************** 
    921 */ 960 */ 
    922 961 
    923int ClassDeclaration::isAbstract() 962int ClassDeclaration::isAbstract() 
    924{ 963{ 
    925    if (isabstract) 964    if (isabstract) 
    926    return TRUE; 965    return TRUE; 
    927    for (int i = 1; i < vtbl.dim; i++) 966    for (int i = 1; i < vtbl.dim; i++) 
    928    { 967    { 
    929    FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration(); 968    FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration(); 
    930 969 
    931    //printf("\tvtbl[%d] = %p\n", i, fd); 970    //printf("\tvtbl[%d] = %p\n", i, fd); 
    932    if (!fd || fd->isAbstract()) 971    if (!fd || fd->isAbstract()) 
    933    { 972    { 
    934        isabstract |= 1; 973        isabstract |= 1; 
    935        return TRUE; 974        return TRUE; 
    936    } 975    } 
    937    } 976    } 
    938    return FALSE; 977    return FALSE; 
      
    989 1028 
    990Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) 1029Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) 
    991{ 1030{ 
    992    InterfaceDeclaration *id; 1031    InterfaceDeclaration *id; 
    993 1032 
    994    if (s) 1033    if (s) 
    995    id = (InterfaceDeclaration *)s; 1034    id = (InterfaceDeclaration *)s; 
    996    else 1035    else 
    997    id = new InterfaceDeclaration(loc, ident, NULL); 1036    id = new InterfaceDeclaration(loc, ident, NULL); 
    998 1037 
    999    ClassDeclaration::syntaxCopy(id); 1038    ClassDeclaration::syntaxCopy(id); 
    1000    return id; 1039    return id; 
    1001} 1040} 
    1002 1041 
    1003void InterfaceDeclaration::semantic(Scope *sc) 1042void InterfaceDeclaration::semantic(Scope *sc) 
    1004{   int i; 1043{   int i; 
    1005 1044 
    1006    //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1045    //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 
    1007    if (inuse) 1046    if (inuse) 
    1008    return; 1047    return; 
    1009    if (!scope)  1048  
    1010    {   type = type->semantic(loc, sc);  1049     if (!sc) 
    1011    handle = handle->semantic(loc, sc);  1050     sc = scope; 
    1012    }  1051     if (!parent && sc->parent && !sc->parent->isModule()) 
       1052     parent = sc->parent; 
       1053  
       1054     type = type->semantic(loc, sc); 
       1055     handle = type; 
       1056  
    1013    if (!members)           // if forward reference 1057    if (!members)           // if forward reference 
    1014    {   //printf("\tinterface '%s' is forward referenced\n", toChars()); 1058    {   //printf("\tinterface '%s' is forward referenced\n", toChars()); 
    1015    return; 1059    return; 
    1016    } 1060    } 
    1017    if (symtab)         // if already done 1061    if (symtab)         // if already done 
    1018    {   if (!scope) 1062    {   if (!scope) 
    1019        return; 1063        return; 
    1020    } 1064    } 
    1021    else 1065    else 
    1022    symtab = new DsymbolTable(); 1066    symtab = new DsymbolTable(); 
    1023 1067 
    1024    Scope *scx = NULL; 1068    Scope *scx = NULL; 
    1025    if (scope) 1069    if (scope) 
    1026    {   sc = scope; 1070    {   sc = scope; 
    1027    scx = scope;        // save so we don't make redundant copies 1071    scx = scope;        // save so we don't make redundant copies 
    1028    scope = NULL; 1072    scope = NULL; 
    1029    } 1073    } 
    1030 1074 
    1031    if (sc->stc & STCdeprecated) 1075    if (sc->stc & STCdeprecated) 
    1032    { 1076    { 
      
    1072        error("base type must be interface, not %s", b->type->toChars()); 1116        error("base type must be interface, not %s", b->type->toChars()); 
    1073        baseclasses.remove(i); 1117        baseclasses.remove(i); 
    1074        continue; 1118        continue; 
    1075    } 1119    } 
    1076    else 1120    else 
    1077    { 1121    { 
    1078        // Check for duplicate interfaces 1122        // Check for duplicate interfaces 
    1079        for (size_t j = 0; j < i; j++) 1123        for (size_t j = 0; j < i; j++) 
    1080        { 1124        { 
    1081        BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 1125        BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 
    1082        if (b2->base == tc->sym) 1126        if (b2->base == tc->sym) 
    1083            error("inherits from duplicate interface %s", b2->base->toChars()); 1127            error("inherits from duplicate interface %s", b2->base->toChars()); 
    1084        } 1128        } 
    1085 1129 
    1086        b->base = tc->sym; 1130        b->base = tc->sym; 
    1087        if (b->base == this || isBaseOf2(b->base)) 1131        if (b->base == this || isBaseOf2(b->base)) 
    1088        { 1132        { 
    1089        error("circular inheritance of interface"); 1133        error("circular inheritance of interface"); 
    1090        baseclasses.remove(i); 1134        baseclasses.remove(i); 
    1091        continue; 1135        continue; 
      1136        } 
      1137        if (!b->base->symtab) 
      1138        {   // Try to resolve forward reference 
      1139        if (sc->mustsemantic && b->base->scope) 
      1140            b->base->semantic(NULL); 
    1092        } 1141        } 
    1093        if (!b->base->symtab || b->base->scope || b->base->inuse) 1142        if (!b->base->symtab || b->base->scope || b->base->inuse) 
    1094        { 1143        { 
    1095        //error("forward reference of base class %s", baseClass->toChars()); 1144        //error("forward reference of base class %s", baseClass->toChars()); 
    1096        // Forward reference of base, try again later 1145        // Forward reference of base, try again later 
    1097        //printf("\ttry later, forward reference of base %s\n", b->base->toChars()); 1146        //printf("\ttry later, forward reference of base %s\n", b->base->toChars()); 
    1098        scope = scx ? scx : new Scope(*sc); 1147        scope = scx ? scx : new Scope(*sc); 
    1099        scope->setNoFree(); 1148        scope->setNoFree(); 
    1100        scope->module->addDeferredSemantic(this); 1149        scope->module->addDeferredSemantic(this); 
    1101        return; 1150        return; 
    1102        } 1151        } 
    1103    } 1152    } 
    1104    i++; 1153    i++; 
    1105    } 1154    } 
    1106 1155 
    1107    interfaces_dim = baseclasses.dim; 1156    interfaces_dim = baseclasses.dim; 
    1108    interfaces = (BaseClass **)baseclasses.data; 1157    interfaces = (BaseClass **)baseclasses.data; 
    1109 1158 
    1110    interfaceSemantic(sc); 1159    interfaceSemantic(sc); 
    1111 1160 
      
    1245 1294 
    1246/**************************************** 1295/**************************************** 
    1247 * Determine if slot 0 of the vtbl[] is reserved for something else. 1296 * Determine if slot 0 of the vtbl[] is reserved for something else. 
    1248 * For class objects, yes, this is where the ClassInfo ptr goes. 1297 * For class objects, yes, this is where the ClassInfo ptr goes. 
    1249 * For COM interfaces, no. 1298 * For COM interfaces, no. 
    1250 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1299 * For non-COM interfaces, yes, this is where the Interface ptr goes. 
    1251 */ 1300 */ 
    1252 1301 
    1253int InterfaceDeclaration::vtblOffset() 1302int InterfaceDeclaration::vtblOffset() 
    1254{ 1303{ 
    1255    if (isCOMinterface()) 1304    if (isCOMinterface()) 
    1256    return 0; 1305    return 0; 
    1257    return 1; 1306    return 1; 
    1258} 1307} 
    1259 1308 
    1260int InterfaceDeclaration::isCOMinterface() 1309int InterfaceDeclaration::isCOMinterface() 
    1261{ 1310{ 
    1262    return com; 1311    return com; 
    1263} 1312} 
    1264 1313 
      1314#if DMDV2 
      1315int InterfaceDeclaration::isCPPinterface() 
      1316{ 
      1317    return cpp; 
      1318} 
      1319#endif 
      1320 
    1265/******************************************* 1321/******************************************* 
    1266 */ 1322 */ 
    1267 1323 
    1268const char *InterfaceDeclaration::kind() 1324const char *InterfaceDeclaration::kind() 
    1269{ 1325{ 
    1270    return "interface"; 1326    return "interface"; 
    1271} 1327} 
    1272 1328 
    1273 1329 
    1274/******************************** BaseClass *****************************/ 1330/******************************** BaseClass *****************************/ 
    1275 1331 
    1276BaseClass::BaseClass() 1332BaseClass::BaseClass() 
    1277{ 1333{ 
    1278    memset(this, 0, sizeof(BaseClass)); 1334    memset(this, 0, sizeof(BaseClass)); 
    1279} 1335} 
    1280 1336 
    1281BaseClass::BaseClass(Type *type, enum PROT protection) 1337BaseClass::BaseClass(Type *type, enum PROT protection) 
    1282{ 1338{ 
    1283    //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); 1339    //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); 
    1284    this->type = type; 1340    this->type = type; 
  • dmd/constfold.c

    Revision 1367:8026319762be Revision 1587:def7a1d494fd
    53 53 
    54/* ================================== isConst() ============================== */ 54/* ================================== isConst() ============================== */ 
    55 55 
    56int Expression::isConst() 56int Expression::isConst() 
    57{ 57{ 
    58    //printf("Expression::isConst(): %s\n", toChars()); 58    //printf("Expression::isConst(): %s\n", toChars()); 
    59    return 0; 59    return 0; 
    60} 60} 
    61 61 
    62int IntegerExp::isConst() 62int IntegerExp::isConst() 
    63{ 63{ 
    64    return 1; 64    return 1; 
    65} 65} 
    66 66 
    67int RealExp::isConst() 67int RealExp::isConst() 
    68{ 68{ 
    69    return 1; 69    return 1; 
    70} 70} 
    71 71 
    72int ComplexExp::isConst() 72int ComplexExp::isConst() 
      73{ 
      74    return 1; 
      75} 
      76 
      77int NullExp::isConst() 
    73{ 78{ 
    74    return 1; 79    return 1; 
    75} 80} 
    76 81 
    77int SymOffExp::isConst() 82int SymOffExp::isConst() 
    78{ 83{ 
    79    return 2; 84    return 2; 
    80} 85} 
    81 86 
    82/* =============================== constFold() ============================== */ 87/* =============================== constFold() ============================== */ 
    83 88 
    84/* The constFold() functions were redundant with the optimize() ones, 89/* The constFold() functions were redundant with the optimize() ones, 
    85 * and so have been folded in with them. 90 * and so have been folded in with them. 
    86 */ 91 */ 
    87 92 
    88/* ========================================================================== */ 93/* ========================================================================== */ 
    89 94 
    90Expression *Neg(Type *type, Expression *e1) 95Expression *Neg(Type *type, Expression *e1) 
    91{   Expression *e; 96{   Expression *e; 
    92    Loc loc = e1->loc; 97    Loc loc = e1->loc; 
      
    828    r1 = e1->toImaginary(); 833    r1 = e1->toImaginary(); 
    829    r2 = e2->toImaginary(); 834    r2 = e2->toImaginary(); 
    830     L1: 835     L1: 
    831#if __DMC__ 836#if __DMC__ 
    832    cmp = (r1 == r2); 837    cmp = (r1 == r2); 
    833#else 838#else 
    834    if (Port::isNan(r1) || Port::isNan(r2)) // if unordered 839    if (Port::isNan(r1) || Port::isNan(r2)) // if unordered 
    835    { 840    { 
    836        cmp = 0; 841        cmp = 0; 
    837    } 842    } 
    838    else 843    else 
    839    { 844    { 
    840        cmp = (r1 == r2); 845        cmp = (r1 == r2); 
    841    } 846    } 
    842#endif 847#endif 
    843    } 848    } 
    844    else if (e1->type->iscomplex()) 849    else if (e1->type->iscomplex()) 
    845    { 850    { 
    846    cmp = e1->toComplex() == e2->toComplex(); 851    cmp = e1->toComplex() == e2->toComplex(); 
    847    } 852    } 
    848    else if (e1->type->isintegral()853    else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer
    849    { 854    { 
    850    cmp = (e1->toInteger() == e2->toInteger()); 855    cmp = (e1->toInteger() == e2->toInteger()); 
    851    } 856    } 
    852    else 857    else 
    853    return EXP_CANT_INTERPRET; 858    return EXP_CANT_INTERPRET; 
    854    if (op == TOKnotequal) 859    if (op == TOKnotequal) 
    855    cmp ^= 1; 860    cmp ^= 1; 
    856    e = new IntegerExp(loc, cmp, type); 861    e = new IntegerExp(loc, cmp, type); 
    857    return e; 862    return e; 
    858} 863} 
    859 864 
    860Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) 865Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) 
    861{   Expression *e; 866{   Expression *e; 
    862    Loc loc = e1->loc; 867    Loc loc = e1->loc; 
    863    int cmp; 868    int cmp; 
    864 869 
    865    if (e1->op == TOKnull && e2->op == TOKnull)  870     if (e1->op == TOKnull) 
    866    {  871     { 
    867    cmp = 1;  872     cmp = (e2->op == TOKnull); 
       873     } 
       874     else if (e2->op == TOKnull) 
       875     { 
       876     cmp = 0; 
    868    } 877    } 
    869    else if (e1->op == TOKsymoff && e2->op == TOKsymoff) 878    else if (e1->op == TOKsymoff && e2->op == TOKsymoff) 
    870    { 879    { 
    871    SymOffExp *es1 = (SymOffExp *)e1; 880    SymOffExp *es1 = (SymOffExp *)e1; 
    872    SymOffExp *es2 = (SymOffExp *)e2; 881    SymOffExp *es2 = (SymOffExp *)e2; 
    873 882 
    874    cmp = (es1->var == es2->var && es1->offset == es2->offset); 883    cmp = (es1->var == es2->var && es1->offset == es2->offset); 
    875    } 884    } 
    876    else if (e1->isConst() == 1 && e2->isConst() == 1) 885    else if (e1->isConst() == 1 && e2->isConst() == 1) 
    877    return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, 886    return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, 
    878        type, e1, e2); 887        type, e1, e2); 
    879    else 888    else 
    880    assert(0); 889    assert(0); 
    881    if (op == TOKnotidentity) 890    if (op == TOKnotidentity) 
    882    cmp ^= 1; 891    cmp ^= 1; 
    883    return new IntegerExp(loc, cmp, type); 892    return new IntegerExp(loc, cmp, type); 
    884} 893} 
    885 894 
    886 895 
    887Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) 896Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) 
      
    1029    } 1038    } 
    1030    e = new IntegerExp(loc, n, type); 1039    e = new IntegerExp(loc, n, type); 
    1031    return e; 1040    return e; 
    1032} 1041} 
    1033 1042 
    1034/* Also returns EXP_CANT_INTERPRET if cannot be computed. 1043/* Also returns EXP_CANT_INTERPRET if cannot be computed. 
    1035 *  to: type to cast to 1044 *  to: type to cast to 
    1036 *  type: type to paint the result 1045 *  type: type to paint the result 
    1037 */ 1046 */ 
    1038 1047 
    1039Expression *Cast(Type *type, Type *to, Expression *e1) 1048Expression *Cast(Type *type, Type *to, Expression *e1) 
    1040{   Expression *e = EXP_CANT_INTERPRET; 1049{   Expression *e = EXP_CANT_INTERPRET; 
    1041    Loc loc = e1->loc; 1050    Loc loc = e1->loc; 
    1042 1051 
    1043    //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); 1052    //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); 
    1044    //printf("e1->type = %s\n", e1->type->toChars()); 1053    //printf("e1->type = %s\n", e1->type->toChars()); 
    1045    if (type->equals(e1->type) && to->equals(type)) 1054    if (type->equals(e1->type) && to->equals(type)) 
    1046    return e1; 1055    return e1; 
    1047 1056 
    1048    Type *tb = to->toBasetype(); 1057    Type *tb = to->toBasetype(); 
    1049    Type *typeb = type->toBasetype(); 1058 
    1050 1059    /* Allow casting from one string type to another 
    1051    // LDC: ported from D2 to allow char[] ~ char[n] arguments in CTFE 1060    */ 
    1052    if (e1->op == TOKstring) 1061    if (e1->op == TOKstring) 
    1053    { 1062    { 
      1063    Type *typeb = type->toBasetype(); 
    1054    if (tb->ty == Tarray && typeb->ty == Tarray && 1064    if (tb->ty == Tarray && typeb->ty == Tarray && 
    1055        tb->nextOf()->size() == typeb->nextOf()->size()) 1065        tb->nextOf()->size() == typeb->nextOf()->size()) 
    1056    { 1066    { 
    1057        return expType(to, e1); 1067        return expType(to, e1); 
    1058    } 1068    } 
    1059    } 1069    } 
    1060 1070 
    1061    if (e1->isConst() != 1) 1071    if (e1->isConst() != 1) 
    1062    return EXP_CANT_INTERPRET; 1072    return EXP_CANT_INTERPRET; 
    1063 1073 
    1064    if (tb->ty == Tbool) 1074    if (tb->ty == Tbool) 
    1065    e = new IntegerExp(loc, e1->toInteger() != 0, type); 1075    e = new IntegerExp(loc, e1->toInteger() != 0, type); 
    1066    else if (type->isintegral()) 1076    else if (type->isintegral()) 
    1067    { 1077    { 
    1068    if (e1->type->isfloating()) 1078    if (e1->type->isfloating()) 
    1069    {   dinteger_t result; 1079    {   dinteger_t result; 
    1070        real_t r = e1->toReal(); 1080        real_t r = e1->toReal(); 
    1071 1081 
    1072        switch (typeb->ty) 1082        switch (type->toBasetype()->ty) 
    1073        { 1083        { 
    1074        case Tint8: result = (d_int8)r; break; 1084        case Tint8: result = (d_int8)r; break; 
    1075        case Tchar: 1085        case Tchar: 
    1076        case Tuns8: result = (d_uns8)r; break; 1086        case Tuns8: result = (d_uns8)r; break; 
    1077        case Tint16:    result = (d_int16)r;    break; 1087        case Tint16:    result = (d_int16)r;    break; 
    1078        case Twchar: 1088        case Twchar: 
    1079        case Tuns16:    result = (d_uns16)r;    break; 1089        case Tuns16:    result = (d_uns16)r;    break; 
    1080        case Tint32:    result = (d_int32)r;    break; 1090        case Tint32:    result = (d_int32)r;    break; 
    1081        case Tdchar: 1091        case Tdchar: 
    1082        case Tuns32:    result = (d_uns32)r;    break; 1092        case Tuns32:    result = (d_uns32)r;    break; 
    1083        case Tint64:    result = (d_int64)r;    break; 1093        case Tint64:    result = (d_int64)r;    break; 
    1084        case Tuns64:    result = (d_uns64)r;    break; 1094        case Tuns64:    result = (d_uns64)r;    break; 
    1085        default: 1095        default: 
    1086            assert(0); 1096            assert(0); 
    1087        } 1097        } 
    1088 1098 
    1089        e = new IntegerExp(loc, result, type); 1099        e = new IntegerExp(loc, result, type); 
    1090    } 1100    } 
    1091    else if (type->isunsigned()) 1101    else if (type->isunsigned()) 
    1092        e = new IntegerExp(loc, e1->toUInteger(), type); 1102        e = new IntegerExp(loc, e1->toUInteger(), type); 
  • dmd/declaration.c

    Revision 1538:e4ff2e15cf5f Revision 1587:def7a1d494fd
    50    assert(type); 50    assert(type); 
    51    return type->size(); 51    return type->size(); 
    52} 52} 
    53 53 
    54int Declaration::isStaticConstructor() 54int Declaration::isStaticConstructor() 
    55{ 55{ 
    56    return FALSE; 56    return FALSE; 
    57} 57} 
    58 58 
    59int Declaration::isStaticDestructor() 59int Declaration::isStaticDestructor() 
    60{ 60{ 
    61    return FALSE; 61    return FALSE; 
    62} 62} 
    63 63 
    64int Declaration::isDelete() 64int Declaration::isDelete() 
    65{ 65{ 
    66    return FALSE; 66    return FALSE; 
    67} 67} 
    68 68 
    69int Declaration::isDataseg() 69int Declaration::isDataseg() 
      70{ 
      71    return FALSE; 
      72} 
      73 
      74int Declaration::isThreadlocal() 
    70{ 75{ 
    71    return FALSE; 76    return FALSE; 
    72} 77} 
    73 78 
    74int Declaration::isCodeseg() 79int Declaration::isCodeseg() 
    75{ 80{ 
    76    return FALSE; 81    return FALSE; 
    77} 82} 
    78 83 
    79enum PROT Declaration::prot() 84enum PROT Declaration::prot() 
    80{ 85{ 
    81    return protection; 86    return protection; 
    82} 87} 
    83 88 
    84/************************************* 89/************************************* 
    85 * Check to see if declaration can be modified in this context (sc). 90 * Check to see if declaration can be modified in this context (sc). 
    86 * Issue error if not. 91 * Issue error if not. 
    87 */ 92 */ 
    88 93 
    89#if DMDV2 94#if DMDV2 
      
    115        { 120        { 
    116        if (s) 121        if (s) 
    117        {   s = s->toParent2(); 122        {   s = s->toParent2(); 
    118            continue; 123            continue; 
    119        } 124        } 
    120        else 125        else 
    121        { 126        { 
    122            const char *p = isStatic() ? "static " : ""; 127            const char *p = isStatic() ? "static " : ""; 
    123            error(loc, "can only initialize %sconst %s inside %sconstructor", 128            error(loc, "can only initialize %sconst %s inside %sconstructor", 
    124            p, toChars(), p); 129            p, toChars(), p); 
    125        } 130        } 
    126        } 131        } 
    127        break; 132        break; 
    128    } 133    } 
    129    } 134    } 
    130    else 135    else 
    131    { 136    { 
    132    VarDeclaration *v = isVarDeclaration(); 137    VarDeclaration *v = isVarDeclaration(); 
    133    if (v && v->canassign == 0) 138    if (v && v->canassign == 0) 
    134    { 139    { 
    135        char *p = NULL; 140        const char *p = NULL; 
    136        if (isConst()) 141        if (isConst()) 
    137        p = "const"; 142        p = "const"; 
    138        else if (isInvariant()) 143        else if (isInvariant()) 
    139        p = "invariant"; 144        p = "immutable"; 
    140        else if (storage_class & STCmanifest) 145        else if (storage_class & STCmanifest) 
    141        p = "manifest constant"; 146        p = "enum"; 
    142        else if (!t->isAssignable()) 147        else if (!t->isAssignable()) 
    143        p = "struct with immutable members"; 148        p = "struct with immutable members"; 
    144        if (p) 149        if (p) 
    145        {   error(loc, "cannot modify %s", p); 150        {   error(loc, "cannot modify %s", p); 
    146        halt();   
    147        } 151        } 
    148    } 152    } 
    149    } 153    } 
    150} 154} 
    151#endif 155#endif 
    152 156 
    153 157 
    154/********************************* TupleDeclaration ****************************/ 158/********************************* TupleDeclaration ****************************/ 
    155 159 
    156TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) 160TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) 
    157    : Declaration(id) 161    : Declaration(id) 
    158{ 162{ 
    159    this->type = NULL; 163    this->type = NULL; 
    160    this->objects = objects; 164    this->objects = objects; 
    161    this->isexp = 0; 165    this->isexp = 0; 
    162    this->tupletype = NULL; 166    this->tupletype = NULL; 
    163} 167} 
    164 168 
    165Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) 169Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) 
    166{ 170{ 
      
    183    return NULL; 187    return NULL; 
    184    if (!tupletype) 188    if (!tupletype) 
    185    { 189    { 
    186    /* It's only a type tuple if all the Object's are types 190    /* It's only a type tuple if all the Object's are types 
    187     */ 191     */ 
    188    for (size_t i = 0; i < objects->dim; i++) 192    for (size_t i = 0; i < objects->dim; i++) 
    189    {   Object *o = (Object *)objects->data[i]; 193    {   Object *o = (Object *)objects->data[i]; 
    190 194 
    191        if (o->dyncast() != DYNCAST_TYPE) 195        if (o->dyncast() != DYNCAST_TYPE) 
    192        { 196        { 
    193        //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); 197        //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); 
    194        return NULL; 198        return NULL; 
    195        } 199        } 
    196    } 200    } 
    197 201 
    198    /* We know it's a type tuple, so build the TypeTuple 202    /* We know it's a type tuple, so build the TypeTuple 
    199     */ 203     */ 
    200    Arguments *args = new Arguments(); 204    Arguments *args = new Arguments(); 
    201    args->setDim(objects->dim); 205    args->setDim(objects->dim); 
    202    OutBuffer buf; 206    OutBuffer buf; 
      207    int hasdeco = 1; 
    203    for (size_t i = 0; i < objects->dim; i++) 208    for (size_t i = 0; i < objects->dim; i++) 
    204    {   Type *t = (Type *)objects->data[i]; 209    {   Type *t = (Type *)objects->data[i]; 
    205 210 
    206        //printf("type = %s\n", t->toChars()); 211        //printf("type = %s\n", t->toChars()); 
    207#if 0 212#if 0 
    208        buf.printf("_%s_%d", ident->toChars(), i); 213        buf.printf("_%s_%d", ident->toChars(), i); 
    209        char *name = (char *)buf.extractData(); 214        char *name = (char *)buf.extractData(); 
    210        Identifier *id = new Identifier(name, TOKidentifier); 215        Identifier *id = new Identifier(name, TOKidentifier); 
    211        Argument *arg = new Argument(STCin, t, id, NULL); 216        Argument *arg = new Argument(STCin, t, id, NULL); 
    212#else 217#else 
    213        Argument *arg = new Argument(STCin, t, NULL, NULL); 218        Argument *arg = new Argument(STCin, t, NULL, NULL); 
    214#endif 219#endif 
    215        args->data[i] = (void *)arg; 220        args->data[i] = (void *)arg; 
      221        if (!t->deco) 
      222        hasdeco = 0; 
    216    } 223    } 
    217 224 
    218    tupletype = new TypeTuple(args); 225    tupletype = new TypeTuple(args); 
      226    if (hasdeco) 
      227        return tupletype->semantic(0, NULL); 
    219    } 228    } 
    220 229 
    221    return tupletype; 230    return tupletype; 
    222} 231} 
    223 232 
    224int TupleDeclaration::needThis() 233int TupleDeclaration::needThis() 
    225{ 234{ 
    226    //printf("TupleDeclaration::needThis(%s)\n", toChars()); 235    //printf("TupleDeclaration::needThis(%s)\n", toChars()); 
    227    for (size_t i = 0; i < objects->dim; i++) 236    for (size_t i = 0; i < objects->dim; i++) 
    228    {   Object *o = (Object *)objects->data[i]; 237    {   Object *o = (Object *)objects->data[i]; 
    229    if (o->dyncast() == DYNCAST_EXPRESSION) 238    if (o->dyncast() == DYNCAST_EXPRESSION) 
    230    {   Expression *e = (Expression *)o; 239    {   Expression *e = (Expression *)o; 
    231        if (e->op == TOKdsymbol) 240        if (e->op == TOKdsymbol) 
    232        {   DsymbolExp *ve = (DsymbolExp *)e; 241        {   DsymbolExp *ve = (DsymbolExp *)e; 
    233        Declaration *d = ve->s->isDeclaration(); 242        Declaration *d = ve->s->isDeclaration(); 
    234        if (d && d->needThis()) 243        if (d && d->needThis()) 
    235        { 244        { 
    236            return 1; 245            return 1; 
    237        } 246        } 
    238        } 247        } 
      
    439 448 
    440    // Given: 449    // Given: 
    441    //  alias foo.bar.abc def; 450    //  alias foo.bar.abc def; 
    442    // it is not knowable from the syntax whether this is an alias 451    // it is not knowable from the syntax whether this is an alias 
    443    // for a type or an alias for a symbol. It is up to the semantic() 452    // for a type or an alias for a symbol. It is up to the semantic() 
    444    // pass to distinguish. 453    // pass to distinguish. 
    445    // If it is a type, then type is set and getType() will return that 454    // If it is a type, then type is set and getType() will return that 
    446    // type. If it is a symbol, then aliassym is set and type is NULL - 455    // type. If it is a symbol, then aliassym is set and type is NULL - 
    447    // toAlias() will return aliasssym. 456    // toAlias() will return aliasssym. 
    448 457 
    449    Dsymbol *s; 458    Dsymbol *s; 
    450    Type *t; 459    Type *t; 
    451    Expression *e; 460    Expression *e; 
    452 461 
    453    /* This section is needed because resolve() will: 462    /* This section is needed because resolve() will: 
    454     *   const x = 3; 463     *   const x = 3; 
    455     *   alias x y; 464     *   alias x y; 
    456     * try to alias y to 3. 465     * try to alias y to 3. 
    457     */ 466     */ 
    458    s = type->toDsymbol(sc); 467    s = type->toDsymbol(sc); 
    459    if (s)  468     if (s 
       469 #if DMDV2 
       470 `   && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) 
       471 #endif 
       472     ) 
    460    goto L2;            // it's a symbolic alias 473    goto L2;            // it's a symbolic alias 
    461 474 
    462    //printf("alias type is %s\n", type->toChars());  475 #if DMDV2 
    463    type->resolve(loc, sc, &e, &t, &s);  476     if (storage_class & (STCref | STCnothrow | STCpure)) 
       477     {   // For 'ref' to be attached to function types, and picked 
       478     // up by Type::resolve(), it has to go into sc. 
       479     sc = sc->push(); 
       480     sc->stc |= storage_class & (STCref | STCnothrow | STCpure); 
       481     type->resolve(loc, sc, &e, &t, &s); 
       482     sc = sc->pop(); 
       483     } 
       484     else 
       485 #endif 
       486     type->resolve(loc, sc, &e, &t, &s); 
    464    if (s) 487    if (s) 
    465    { 488    { 
    466    goto L2; 489    goto L2; 
    467    } 490    } 
    468    else if (e) 491    else if (e) 
    469    { 492    { 
    470    // Try to convert Expression to Dsymbol 493    // Try to convert Expression to Dsymbol 
    471        if (e->op == TOKvar) 494        if (e->op == TOKvar) 
    472    {   s = ((VarExp *)e)->var; 495    {   s = ((VarExp *)e)->var; 
    473        goto L2; 496        goto L2; 
    474    } 497    } 
    475        else if (e->op == TOKfunction) 498        else if (e->op == TOKfunction) 
    476    {   s = ((FuncExp *)e)->fd; 499    {   s = ((FuncExp *)e)->fd; 
    477        goto L2; 500        goto L2; 
    478    } 501    } 
    479        else 502        else 
    480    {   error("cannot alias an expression %s", e->toChars()); 503    {   error("cannot alias an expression %s", e->toChars()); 
    481        t = e->type; 504        t = e->type; 
    482    } 505    } 
    483    } 506    } 
      
    506    { 529    { 
    507        if (overnext) 530        if (overnext) 
    508        { 531        { 
    509        FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); 532        FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); 
    510        fa->importprot = importprot; 533        fa->importprot = importprot; 
    511        if (!fa->overloadInsert(overnext)) 534        if (!fa->overloadInsert(overnext)) 
    512            ScopeDsymbol::multiplyDefined(0, f, overnext); 535            ScopeDsymbol::multiplyDefined(0, f, overnext); 
    513        overnext = NULL; 536        overnext = NULL; 
    514        s = fa; 537        s = fa; 
    515        s->parent = sc->parent; 538        s->parent = sc->parent; 
    516        } 539        } 
    517    } 540    } 
    518    if (overnext) 541    if (overnext) 
    519        ScopeDsymbol::multiplyDefined(0, s, overnext); 542        ScopeDsymbol::multiplyDefined(0, s, overnext); 
    520    if (s == this) 543    if (s == this) 
    521    { 544    { 
    522        assert(global.errors); 545        assert(global.errors); 
    523        s = NULL; 546        s = NULL; 
    524    } 547    } 
    525    } 548    } 
    526    aliassym = s;  549     if (!aliassym) 
       550     aliassym = s; 
    527    this->inSemantic = 0; 551    this->inSemantic = 0; 
    528} 552} 
    529 553 
    530int AliasDeclaration::overloadInsert(Dsymbol *s) 554int AliasDeclaration::overloadInsert(Dsymbol *s) 
    531{ 555{ 
    532    /* Don't know yet what the aliased symbol is, so assume it can 556    /* Don't know yet what the aliased symbol is, so assume it can 
    533     * be overloaded and check later for correctness. 557     * be overloaded and check later for correctness. 
    534     */ 558     */ 
    535 559 
    536    //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 560    //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 
    537    if (overnext == NULL) 561    if (overnext == NULL) 
    538    {   overnext = s;  562     { 
       563     if (s == this) 
       564     { 
       565         return TRUE; 
       566     } 
       567     overnext = s; 
    539    return TRUE; 568    return TRUE; 
    540    } 569    } 
    541    else 570    else 
    542    { 571    { 
    543    return overnext->overloadInsert(s); 572    return overnext->overloadInsert(s); 
    544    } 573    } 
    545} 574} 
    546 575 
    547const char *AliasDeclaration::kind() 576const char *AliasDeclaration::kind() 
    548{ 577{ 
    549    return "alias"; 578    return "alias"; 
    550} 579} 
    551 580 
    552Type *AliasDeclaration::getType() 581Type *AliasDeclaration::getType() 
    553{ 582{ 
      583    //printf("AliasDeclaration::getType() %s\n", type->toChars()); 
      584#if 0 
      585    if (!type->deco && scope) 
      586    semantic(scope); 
      587    if (type && !type->deco) 
      588    error("forward reference to alias %s\n", toChars()); 
      589#endif 
    554    return type; 590    return type; 
    555} 591} 
    556 592 
    557Dsymbol *AliasDeclaration::toAlias() 593Dsymbol *AliasDeclaration::toAlias() 
    558{ 594{ 
    559    //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 595    //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 
    560    assert(this != aliassym); 596    assert(this != aliassym); 
    561    //static int count; if (++count == 10) *(char*)0=0; 597    //static int count; if (++count == 75) exit(0); //*(char*)0=0; 
    562    if (inSemantic) 598    if (inSemantic) 
    563    {   error("recursive alias declaration"); 599    {   error("recursive alias declaration"); 
    564    aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL); 600    aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL); 
    565    } 601    } 
    566    Dsymbol *s = aliassym ? aliassym->toAlias() : this; 602    Dsymbol *s = aliassym ? aliassym->toAlias() : this; 
    567    return s; 603    return s; 
    568} 604} 
    569 605 
    570void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 606void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    571{ 607{ 
    572    buf->writestring("alias "); 608    buf->writestring("alias "); 
    573#if 0 && _DH 609#if 0 && _DH 
    574    if (hgs->hdrgen) 610    if (hgs->hdrgen) 
    575    { 611    { 
    576    if (haliassym) 612    if (haliassym) 
    577    { 613    { 
    578        buf->writestring(haliassym->toChars()); 614        buf->writestring(haliassym->toChars()); 
    579        buf->writeByte(' '); 615        buf->writeByte(' '); 
    580        buf->writestring(ident->toChars()); 616        buf->writestring(ident->toChars()); 
    581    } 617    } 
      
    603VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 639VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 
    604    : Declaration(id) 640    : Declaration(id) 
    605{ 641{ 
    606    //printf("VarDeclaration('%s')\n", id->toChars()); 642    //printf("VarDeclaration('%s')\n", id->toChars()); 
    607#ifdef DEBUG 643#ifdef DEBUG 
    608    if (!type && !init) 644    if (!type && !init) 
    609    {   printf("VarDeclaration('%s')\n", id->toChars()); 645    {   printf("VarDeclaration('%s')\n", id->toChars()); 
    610    //*(char*)0=0; 646    //*(char*)0=0; 
    611    } 647    } 
    612#endif 648#endif 
    613    assert(type || init); 649    assert(type || init); 
    614    this->type = type; 650    this->type = type; 
    615    this->init = init; 651    this->init = init; 
    616#ifdef _DH 652#ifdef _DH 
    617    this->htype = NULL; 653    this->htype = NULL; 
    618    this->hinit = NULL; 654    this->hinit = NULL; 
    619#endif 655#endif 
    620    this->loc = loc; 656    this->loc = loc; 
    621    offset = 0; 657    offset = 0; 
    622    noscope = 0; 658    noscope = 0; 
      659#if DMDV1 
    623    nestedref = 0; 660    nestedref = 0; 
      661#endif 
    624    ctorinit = 0; 662    ctorinit = 0; 
    625    aliassym = NULL; 663    aliassym = NULL; 
    626    onstack = 0; 664    onstack = 0; 
    627    canassign = 0; 665    canassign = 0; 
    628    value = NULL; 666    value = NULL; 
    629 667 
    630#if IN_LLVM 668#if IN_LLVM 
    631    aggrIndex = 0; 669    aggrIndex = 0; 
    632 670 
    633    // LDC 671    // LDC 
    634    anonDecl = NULL; 672    anonDecl = NULL; 
    635    offset2 = 0; 673    offset2 = 0; 
    636 674 
    637    nakedUse = false; 675    nakedUse = false; 
    638 676 
    639    availableExternally = true; // assume this unless proven otherwise 677    availableExternally = true; // assume this unless proven otherwise 
    640#endif 678#endif 
    641} 679} 
    642 680 
    643Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 681Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 
      
    667    {   htype = type->syntaxCopy(); 705    {   htype = type->syntaxCopy(); 
    668        sv->htype = type->syntaxCopy(); 706        sv->htype = type->syntaxCopy(); 
    669    } 707    } 
    670    } 708    } 
    671    else            // Make copy of original for new instance 709    else            // Make copy of original for new instance 
    672        sv->htype = htype->syntaxCopy(); 710        sv->htype = htype->syntaxCopy(); 
    673    if (!hinit) 711    if (!hinit) 
    674    {   if (init) 712    {   if (init) 
    675    {   hinit = init->syntaxCopy(); 713    {   hinit = init->syntaxCopy(); 
    676        sv->hinit = init->syntaxCopy(); 714        sv->hinit = init->syntaxCopy(); 
    677    } 715    } 
    678    } 716    } 
    679    else 717    else 
    680        sv->hinit = hinit->syntaxCopy(); 718        sv->hinit = hinit->syntaxCopy(); 
    681#endif 719#endif 
    682    return sv; 720    return sv; 
    683} 721} 
    684 722 
    685void VarDeclaration::semantic(Scope *sc) 723void VarDeclaration::semantic(Scope *sc) 
    686{ 724{ 
    687    //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());  725 #if 0 
    688    //printf(" type = %s\n", type ? type->toChars() : "null");  726     printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 
    689    //printf(" stc = x%x\n", sc->stc);  727     printf(" type = %s\n", type ? type->toChars() : "null"); 
    690    //printf(" storage_class = x%x\n", storage_class);  728     printf(" stc = x%x\n", sc->stc); 
    691    //printf("linkage = %d\n", sc->linkage);  729     printf(" storage_class = x%x\n", storage_class); 
       730     printf("linkage = %d\n", sc->linkage); 
    692    //if (strcmp(toChars(), "mul") == 0) halt(); 731    //if (strcmp(toChars(), "mul") == 0) halt(); 
      732#endif 
    693 733 
    694    storage_class |= sc->stc; 734    storage_class |= sc->stc; 
    695    if (storage_class & STCextern && init) 735    if (storage_class & STCextern && init) 
    696    error("extern symbols cannot have initializers"); 736    error("extern symbols cannot have initializers"); 
    697 737 
    698    /* If auto type inference, do the inference 738    /* If auto type inference, do the inference 
    699     */ 739     */ 
    700    int inferred = 0; 740    int inferred = 0; 
    701    if (!type) 741    if (!type) 
    702    {   inuse++; 742    {   inuse++; 
    703    type = init->inferType(sc); 743    type = init->inferType(sc); 
    704    inuse--; 744    inuse--; 
    705    inferred = 1; 745    inferred = 1; 
    706 746 
    707    /* This is a kludge to support the existing syntax for RAII 747    /* This is a kludge to support the existing syntax for RAII 
    708     * declarations. 748     * declarations. 
    709     */ 749     */ 
    710    storage_class &= ~STCauto; 750    storage_class &= ~STCauto; 
    711    originalType = type; 751    originalType = type; 
    712    } 752    } 
    713    else 753    else 
    714    {   if (!originalType) 754    {   if (!originalType) 
    715        originalType = type; 755        originalType = type; 
    716    type = type->semantic(loc, sc); 756    type = type->semantic(loc, sc); 
    717    } 757    } 
    718    //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 758    //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 
    719 759 
    720    type->checkDeprecated(loc, sc); 760    type->checkDeprecated(loc, sc); 
    721    linkage = sc->linkage; 761    linkage = sc->linkage; 
    722    this->parent = sc->parent; 762    this->parent = sc->parent; 
    723    //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); 763    //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); 
    724    protection = sc->protection; 764    protection = sc->protection; 
    725    //printf("sc->stc = %x\n", sc->stc); 765    //printf("sc->stc = %x\n", sc->stc); 
    726    //printf("storage_class = x%x\n", storage_class); 766    //printf("storage_class = x%x\n", storage_class); 
      767 
      768#if DMDV2 
      769    if (storage_class & STCgshared && global.params.safe && !sc->module->safe) 
      770    { 
      771    error("__gshared not allowed in safe mode; use shared"); 
      772    } 
      773#endif 
    727 774 
    728    Dsymbol *parent = toParent(); 775    Dsymbol *parent = toParent(); 
    729    FuncDeclaration *fd = parent->isFuncDeclaration(); 776    FuncDeclaration *fd = parent->isFuncDeclaration(); 
    730 777 
    731    Type *tb = type->toBasetype(); 778    Type *tb = type->toBasetype(); 
    732    if (tb->ty == Tvoid && !(storage_class & STClazy)) 779    if (tb->ty == Tvoid && !(storage_class & STClazy)) 
    733    {   error("voids have no value"); 780    {   error("voids have no value"); 
    734    type = Type::terror; 781    type = Type::terror; 
    735    tb = type; 782    tb = type; 
    736    } 783    } 
    737    if (tb->ty == Tfunction) 784    if (tb->ty == Tfunction) 
    738    {   error("cannot be declared to be a function"); 785    {   error("cannot be declared to be a function"); 
    739    type = Type::terror; 786    type = Type::terror; 
    740    tb = type; 787    tb = type; 
    741    } 788    } 
    742    if (tb->ty == Tstruct) 789    if (tb->ty == Tstruct) 
    743    {   TypeStruct *ts = (TypeStruct *)tb; 790    {   TypeStruct *ts = (TypeStruct *)tb; 
    744 791 
    745    if (!ts->sym->members) 792    if (!ts->sym->members) 
    746    { 793    { 
      
    815    error("variable %s cannot be synchronized", toChars()); 862    error("variable %s cannot be synchronized", toChars()); 
    816    } 863    } 
    817    else if (isOverride()) 864    else if (isOverride()) 
    818    { 865    { 
    819    error("override cannot be applied to variable"); 866    error("override cannot be applied to variable"); 
    820    } 867    } 
    821    else if (isAbstract()) 868    else if (isAbstract()) 
    822    { 869    { 
    823    error("abstract cannot be applied to variable"); 870    error("abstract cannot be applied to variable"); 
    824    } 871    } 
    825    else if (storage_class & STCtemplateparameter) 872    else if (storage_class & STCtemplateparameter) 
    826    { 873    { 
    827    } 874    } 
    828    else 875    else 
    829    { 876    { 
    830    AggregateDeclaration *aad = sc->anonAgg; 877    AggregateDeclaration *aad = sc->anonAgg; 
    831    if (!aad) 878    if (!aad) 
    832        aad = parent->isAggregateDeclaration(); 879        aad = parent->isAggregateDeclaration(); 
    833    if (aad) 880    if (aad) 
    834    { 881    { 
    835        aad->addField(sc, this);  882 #if DMDV2 
       883         assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); 
       884  
       885         if (storage_class & (STCconst | STCimmutable) && init) 
       886         { 
       887         if (!type->toBasetype()->isTypeBasic()) 
       888             storage_class |= STCstatic; 
       889         } 
       890         else 
       891 #endif 
       892         aad->addField(sc, this); 
    836    } 893    } 
    837 894 
    838    InterfaceDeclaration *id = parent->isInterfaceDeclaration(); 895    InterfaceDeclaration *id = parent->isInterfaceDeclaration(); 
    839    if (id) 896    if (id) 
    840    { 897    { 
    841        error("field not allowed in interface"); 898        error("field not allowed in interface"); 
    842    } 899    } 
    843 900 
    844    /* Templates cannot add fields to aggregates 901    /* Templates cannot add fields to aggregates 
    845     */ 902     */ 
    846    TemplateInstance *ti = parent->isTemplateInstance(); 903    TemplateInstance *ti = parent->isTemplateInstance(); 
    847    if (ti) 904    if (ti) 
    848    { 905    { 
    849        // Take care of nested templates 906        // Take care of nested templates 
    850        while (1) 907        while (1) 
    851        { 908        { 
    852        TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 909        TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 
    853        if (!ti2) 910        if (!ti2) 
    854            break; 911            break; 
    855        ti = ti2; 912        ti = ti2; 
    856        } 913        } 
    857 914 
    858        // If it's a member template 915        // If it's a member template 
    859        AggregateDeclaration *ad = ti->tempdecl->isMember(); 916        AggregateDeclaration *ad = ti->tempdecl->isMember(); 
    860        if (ad && storage_class != STCundefined) 917        if (ad && storage_class != STCundefined) 
    861        { 918        { 
    862        error("cannot use template to add field to aggregate '%s'", ad->toChars()); 919        error("cannot use template to add field to aggregate '%s'", ad->toChars()); 
    863        } 920        } 
    864    } 921    } 
    865    } 922    } 
    866 923 
      924#if DMDV2 
      925    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 
      926    ident != Id::This) 
      927    { 
      928    error("only parameters or foreach declarations can be ref"); 
      929    } 
      930#endif 
      931 
    867    if (type->isscope() && !noscope) 932    if (type->isscope() && !noscope) 
    868    { 933    { 
    869    if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 934    if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 
    870    { 935    { 
    871        error("globals, statics, fields, ref and out parameters cannot be scope"); 936        error("globals, statics, fields, ref and out parameters cannot be scope"); 
    872    } 937    } 
    873 938 
    874    if (!(storage_class & STCscope)) 939    if (!(storage_class & STCscope)) 
    875    { 940    { 
    876        if (!(storage_class & STCparameter) && ident != Id::withSym) 941        if (!(storage_class & STCparameter) && ident != Id::withSym) 
    877        error("reference to scope class must be scope"); 942        error("reference to scope class must be scope"); 
    878    } 943    } 
    879    } 944    } 
    880 945 
      946    enum TOK op = TOKconstruct; 
    881    if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 947    if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 
    882    !(storage_class & (STCfield | STCin | STCforeach)) && 948    !(storage_class & (STCfield | STCin | STCforeach)) && 
    883    type->size() != 0) 949    type->size() != 0) 
    884    { 950    { 
    885    // Provide a default initializer 951    // Provide a default initializer 
    886    //printf("Providing default initializer for '%s'\n", toChars()); 952    //printf("Providing default initializer for '%s'\n", toChars()); 
    887    if (type->ty == Tstruct && 953    if (type->ty == Tstruct && 
    888        ((TypeStruct *)type)->sym->zeroInit == 1) 954        ((TypeStruct *)type)->sym->zeroInit == 1) 
    889    {   /* If a struct is all zeros, as a special case 955    {   /* If a struct is all zeros, as a special case 
    890         * set it's initializer to the integer 0. 956         * set it's initializer to the integer 0. 
    891         * In AssignExp::toElem(), we check for this and issue 957         * In AssignExp::toElem(), we check for this and issue 
    892         * a memset() to initialize the struct. 958         * a memset() to initialize the struct. 
    893         * Must do same check in interpreter. 959         * Must do same check in interpreter. 
    894         */ 960         */ 
    895        Expression *e = new IntegerExp(loc