Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 183

Show
Ignore:
Timestamp:
07/03/09 07:32:24 (15 years ago)
Author:
braddr
Message:

dmd 2.026

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/access.c

    r169 r183  
    11 
    22// Copyright (c) 1999-2006 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    1515#include "root.h" 
    16 #include "mem.h" 
     16#include "rmem.h" 
    1717 
    1818#include "enum.h" 
    1919#include "aggregate.h" 
    2020#include "init.h" 
    2121#include "attrib.h" 
    2222#include "scope.h" 
    2323#include "id.h" 
    2424#include "mtype.h" 
    2525#include "declaration.h" 
    2626#include "aggregate.h" 
    2727#include "expression.h" 
    2828#include "module.h" 
    2929 
    3030#define LOG 0 
    3131 
    3232/* Code to do access checks 
    3333 */ 
    3434 
    3535int hasPackageAccess(Scope *sc, Dsymbol *s); 
    3636 
  • trunk/src/aggregate.h

    r177 r183  
    3535 
    3636 
    3737struct AggregateDeclaration : ScopeDsymbol 
    3838{ 
    3939    Type *type; 
    4040    unsigned storage_class; 
    4141    enum PROT protection; 
    4242    Type *handle;       // 'this' type 
    4343    unsigned structsize;    // size of struct 
    4444    unsigned alignsize;     // size of struct for alignment purposes 
    4545    unsigned structalign;   // struct member alignment in effect 
    4646    int hasUnions;      // set if aggregate has overlapping fields 
    4747    Array fields;       // VarDeclaration fields 
    4848    unsigned sizeok;        // set when structsize contains valid data 
    4949                // 0: no size 
    5050                // 1: size is correct 
    5151                // 2: cannot determine size; fwd referenced 
    5252    int isdeprecated;       // !=0 if deprecated 
    5353    Scope *scope;       // !=NULL means context to use 
    5454 
     55    int isnested;       // !=0 if is nested 
     56    VarDeclaration *vthis;  // 'this' parameter if this aggregate is nested 
     57 
    5558    // Special member functions 
    5659    InvariantDeclaration *inv;      // invariant 
    5760    NewDeclaration *aggNew;     // allocator 
    5861    DeleteDeclaration *aggDelete;   // deallocator 
    5962 
    6063#if V2 
    6164    CtorDeclaration *ctor; 
    6265    CtorDeclaration *defaultCtor;   // default constructor 
    6366#endif 
    6467 
    6568    FuncDeclarations dtors; // Array of destructors 
    6669    FuncDeclaration *dtor;  // aggregate destructor 
    6770 
    6871#ifdef IN_GCC 
    6972    Array methods;              // flat list of all methods for debug information 
    7073#endif 
    7174 
    7275    AggregateDeclaration(Loc loc, Identifier *id); 
    7376    void semantic2(Scope *sc); 
    7477    void semantic3(Scope *sc); 
    7578    void inlineScan(); 
    7679    unsigned size(Loc loc); 
    7780    static void alignmember(unsigned salign, unsigned size, unsigned *poffset); 
    7881    Type *getType(); 
    7982    void addField(Scope *sc, VarDeclaration *v); 
    8083    int isDeprecated();     // is aggregate deprecated? 
    8184    FuncDeclaration *buildDtor(Scope *sc); 
     85    int isNested(); 
    8286 
    8387    void emitComment(Scope *sc); 
    8488    void toDocBuffer(OutBuffer *buf); 
    8589 
    8690    // For access checking 
    8791    virtual PROT getAccess(Dsymbol *smember);   // determine access to smember 
    8892    int isFriendOf(AggregateDeclaration *cd); 
    8993    int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? 
    9094    void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); 
    9195 
    9296    enum PROT prot(); 
    9397 
    9498    // Back end 
    9599    Symbol *stag;       // tag symbol for debug data 
    96100    Symbol *sinit; 
    97101    Symbol *toInitializer(); 
    98102 
    99103    AggregateDeclaration *isAggregateDeclaration() { return this; } 
    100104}; 
    101105 
     
    187191    FuncDeclaration *staticDtor; 
    188192    Array vtbl;             // Array of FuncDeclaration's making up the vtbl[] 
    189193    Array vtblFinal;            // More FuncDeclaration's that aren't in vtbl[] 
    190194 
    191195    BaseClasses baseclasses;        // Array of BaseClass's; first is super, 
    192196                    // rest are Interface's 
    193197 
    194198    int interfaces_dim; 
    195199    BaseClass **interfaces;     // interfaces[interfaces_dim] for this class 
    196200                    // (does not include baseClass) 
    197201 
    198202    BaseClasses *vtblInterfaces;    // array of base interfaces that have 
    199203                    // their own vtbl[] 
    200204 
    201205    ClassInfoDeclaration *vclassinfo;   // the ClassInfo object for this ClassDeclaration 
    202206    int com;                // !=0 if this is a COM class (meaning 
    203207                    // it derives from IUnknown) 
    204208    int isauto;             // !=0 if this is an auto class 
    205209    int isabstract;         // !=0 if abstract class 
    206210 
    207     int isnested;           // !=0 if is nested 
    208     VarDeclaration *vthis;      // 'this' parameter if this class is nested 
    209  
    210211    int inuse;              // to prevent recursive attempts 
    211212 
    212213    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    213214    Dsymbol *syntaxCopy(Dsymbol *s); 
    214215    void semantic(Scope *sc); 
    215216    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    216217    int isBaseOf2(ClassDeclaration *cd); 
    217218 
    218219    #define OFFSET_RUNTIME 0x76543210 
    219220    virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 
    220221 
    221222    Dsymbol *search(Loc, Identifier *ident, int flags); 
    222223#if V2 
    223224    int isFuncHidden(FuncDeclaration *fd); 
    224225#endif 
    225226    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 
    226227    void interfaceSemantic(Scope *sc); 
    227     int isNested(); 
    228228    int isCOMclass(); 
    229229    virtual int isCOMinterface(); 
    230230#if V2 
    231231    virtual int isCPPinterface(); 
    232232#endif 
    233233    int isAbstract(); 
    234234    virtual int vtblOffset(); 
    235235    const char *kind(); 
    236236    char *mangle(); 
    237237    void toDocBuffer(OutBuffer *buf); 
    238238 
    239239    PROT getAccess(Dsymbol *smember);   // determine access to smember 
    240240 
    241241    void addLocalClass(ClassDeclarations *); 
    242242 
    243243    // Back end 
    244244    void toObjFile(int multiobj);           // compile to .obj file 
    245245    void toDebug(); 
    246246    unsigned baseVtblOffset(BaseClass *bc); 
    247247    Symbol *toSymbol(); 
  • trunk/src/arrayop.c

    r177 r183  
    11 
    22// Copyright (c) 1999-2008 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010#include <stdio.h> 
    1111#include <string.h> 
    1212#include <assert.h> 
    1313 
    14 #if _WIN32 || IN_GCC 
    15 #include "mem.h" 
    16 #else 
    17 #include "../root/mem.h" 
    18 #endif 
     14#include "rmem.h" 
    1915 
    2016#include "stringtable.h" 
    2117 
    2218#include "expression.h" 
    2319#include "statement.h" 
    2420#include "mtype.h" 
    2521#include "declaration.h" 
    2622#include "scope.h" 
    2723#include "id.h" 
    2824#include "module.h" 
    2925#include "init.h" 
    3026 
    3127extern int binary(const char *p , const char **tab, int high); 
    3228 
    3329/************************************** 
    3430 * Hash table of array op functions already generated or known about. 
    3531 */ 
    3632 
    3733StringTable arrayfuncs; 
    3834 
  • trunk/src/attrib.c

    r182 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    15 #if _WIN32 || IN_GCC 
    16 #include "mem.h" 
    17 #elif linux || __APPLE__ 
    18 #include "../root/mem.h" 
    19 #endif 
     15#include "rmem.h" 
    2016 
    2117#include "init.h" 
    2218#include "declaration.h" 
    2319#include "attrib.h" 
    2420#include "cond.h" 
    2521#include "scope.h" 
    2622#include "id.h" 
    2723#include "expression.h" 
    2824#include "dsymbol.h" 
    2925#include "aggregate.h" 
    3026#include "module.h" 
    3127#include "parse.h" 
    3228#include "template.h" 
    3329 
    3430extern void obj_includelib(const char *name); 
    3531void obj_startaddress(Symbol *s); 
    3632 
    3733 
    3834/********************************* AttribDeclaration ****************************/ 
    3935 
  • trunk/src/backend/elfobj.c

    r182 r183  
    1  
    2 //_ elfobj.c    Modified by: Walter Bright 
    3 // Copyright (c) 1984-2009 by Digital Mars, http://www.digitalmars.com 
     1// Copyright (C) ?-1998 by Symantec 
     2// Copyright (C) 2000-2009 by Digital Mars 
    43// All Rights Reserved 
    5 // Written by Walter Bright 
     4// http://www.digitalmars.com 
     5/* 
     6 * This source file is made available for personal use 
     7 * only. The license is in /dmd/src/dmd/backendlicense.txt 
     8 * For any other uses, please contact Digital Mars. 
     9 */ 
     10 
     11 
    612// Output to ELF object files 
    713 
    814#if SCPP || MARS 
    915#include    <stdio.h> 
    1016#include    <string.h> 
    1117#include    <stdlib.h> 
    1218#include    <malloc.h> 
    1319#include    <sys/types.h> 
    1420#include    <sys/stat.h> 
    1521#include    <fcntl.h> 
    1622#include    <ctype.h> 
    1723 
    1824#if linux || __APPLE__ 
    1925#include    <signal.h> 
    2026#include    <unistd.h> 
    2127#endif 
    2228 
    2329#include    "cc.h" 
    2430#include    "global.h" 
    2531#include    "code.h" 
     
    14641470    if (s->Sfl == FLdata || s->Sfl == FLtlsdata) 
    14651471    { 
    14661472    objpubdef(s->Sseg,s,0); 
    14671473    searchfixlist(s);       // backpatch any refs to this symbol 
    14681474    } 
    14691475    return s->Sseg; 
    14701476} 
    14711477 
    14721478/******************************** 
    14731479 * Get a segment for a segment name. 
    14741480 * Input: 
    14751481 *  name        name of segment, if NULL then revert to default name 
    14761482 *  suffix      append to name 
    14771483 *  align       alignment 
    14781484 * Returns: 
    14791485 *  segment index of found or newly created segment 
    14801486 */ 
    14811487 
    14821488int elf_getsegment2(IDXSEC shtidx, IDXSYM symidx, IDXSEC relidx) 
    14831489{ 
     1490    //printf("SegData = %p\n", SegData); 
    14841491    int seg = ++seg_count; 
    14851492    if (seg_count >= seg_max) 
    14861493    {               // need more room in segment table 
    14871494    seg_max += OB_SEG_INC; 
    14881495    SegData = (seg_data **)mem_realloc(SegData,seg_max * sizeof(seg_data *)); 
    1489     memset(&SegData[seg_count], 0, OB_SEG_INC * sizeof(seg_data *)); 
     1496    memset(&SegData[seg_count], 0, (seg_max - seg_count) * sizeof(seg_data *)); 
    14901497    } 
    14911498    assert(seg_count < seg_max); 
    14921499    if (!SegData[seg]) 
    14931500    {   SegData[seg] = (seg_data *)mem_calloc(sizeof(seg_data)); 
     1501    //printf("test2: SegData[%d] = %p\n", seg, SegData[seg]); 
    14941502    } 
    14951503 
    14961504    seg_data *pseg = SegData[seg]; 
    14971505    pseg->SDseg = seg; 
    14981506    pseg->SDshtidx = shtidx; 
    14991507    pseg->SDoffset = 0; 
    15001508    if (pseg->SDbuf) 
    15011509    pseg->SDbuf->setsize(0); 
    15021510    else 
    15031511    {   if (SecHdrTab[shtidx].sh_type != SHT_NOBITS) 
    15041512    {   pseg->SDbuf = new Outbuffer(OB_XTRA_STR); 
    15051513        pseg->SDbuf->reserve(1024); 
    15061514    } 
    15071515    } 
    15081516    if (pseg->SDrel) 
    15091517    pseg->SDrel->setsize(0); 
    15101518    pseg->SDsymidx = symidx; 
    15111519    pseg->SDrelidx = relidx; 
    15121520    pseg->SDrelmaxoff = 0; 
    15131521    pseg->SDrelindex = 0; 
     
    17191727        if (tyfunc(s->ty()) && !variadic(s->Stype)) 
    17201728#else 
    17211729        if (!(config.flags4 & CFG4oldstdmangle) && 
    17221730        config.exe == EX_NT && tyfunc(s->ty()) && 
    17231731        !variadic(s->Stype)) 
    17241732#endif 
    17251733        { 
    17261734        char *pstr = unsstr(type_paramsize(s->Stype)); 
    17271735        size_t pstrlen = strlen(pstr); 
    17281736        size_t destlen = len + 1 + pstrlen + 1; 
    17291737 
    17301738        if (destlen > DEST_LEN) 
    17311739            dest = (char *)mem_malloc(destlen); 
    17321740        memcpy(dest,name,len); 
    17331741        dest[len] = '@'; 
    17341742        memcpy(dest + 1 + len, pstr, pstrlen + 1); 
    17351743        break; 
    17361744        } 
    17371745    case mTYman_cpp: 
    17381746    case mTYman_c: 
    1739     case mTYman_java
     1747    case mTYman_d
    17401748    case mTYman_sys: 
    17411749    case 0: 
    17421750        if (len >= DEST_LEN) 
    17431751        dest = (char *)mem_malloc(len + 1); 
    17441752        memcpy(dest,name,len+1);// copy in name and trailing 0 
    17451753        break; 
    17461754 
    17471755    default: 
    17481756#ifdef DEBUG 
    17491757        printf("mangling %x\n",type_mangle(s->Stype)); 
    17501758        symbol_print(s); 
    17511759#endif 
    17521760        printf("%d\n", type_mangle(s->Stype)); 
    17531761        assert(0); 
    17541762    } 
    17551763    //dbg_printf("\t %s\n",dest); 
    17561764    return dest; 
    17571765} 
    17581766 
    17591767/******************************* 
  • trunk/src/backend/html.c

    r125 r183  
    11 
    2 // Copyright (c) 1999-2006 by Digital Mars 
     2// Copyright (c) 1999-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010 
    1111/* HTML parser 
    1212 */ 
    1313 
    1414#include <stdio.h> 
    1515#include <string.h> 
    1616#include <ctype.h> 
    1717#include <stdarg.h> 
    1818#include <errno.h> 
    1919#include <wchar.h> 
    2020 
    21 #include "mars.h" 
    2221#include "html.h" 
    2322 
     23#if MARS 
    2424#include <assert.h> 
    2525#include "root.h" 
    26 #include "../mars/mars.h" 
     26//#include "../mars/mars.h" 
     27#else 
     28#include "outbuf.h" 
     29#include "msgs2.h" 
     30 
     31extern void html_err(const char *, unsigned, unsigned, ...); 
     32 
     33static char __file__[] = __FILE__;  /* for tassert.h        */ 
     34#include    "tassert.h" 
     35#endif 
     36 
     37#if __GNUC__ 
     38int memicmp(const char *s1, const char *s2, int n); 
     39#if 0 
     40
     41    int result = 0; 
     42 
     43    for (int i = 0; i < n; i++) 
     44    {   char c1 = s1[i]; 
     45    char c2 = s2[i]; 
     46 
     47    result = c1 - c2; 
     48    if (result) 
     49    { 
     50        if ('A' <= c1 && c1 <= 'Z') 
     51        c1 += 'a' - 'A'; 
     52        if ('A' <= c2 && c2 <= 'Z') 
     53        c2 += 'a' - 'A'; 
     54        result = c1 - c2; 
     55        if (result) 
     56        break; 
     57    } 
     58    } 
     59    return result; 
     60
     61#endif 
     62#endif 
    2763 
    2864extern int HtmlNamedEntity(unsigned char *p, int length); 
    2965 
    3066static int isLineSeparator(const unsigned char* p); 
    3167 
    3268/********************************** 
    3369 * Determine if beginning of tag identifier 
    3470 * or a continuation of a tag identifier. 
    3571 */ 
    3672 
    3773inline int istagstart(int c) 
    3874{ 
    3975    return (isalpha(c) || c == '_'); 
    4076} 
    4177 
    4278inline int istag(int c) 
    4379{ 
    4480    return (isalnum(c) || c == '_'); 
    4581} 
    4682 
     
    4884 */ 
    4985 
    5086Html::Html(const char *sourcename, unsigned char *base, unsigned length) 
    5187{ 
    5288    //printf("Html::Html()\n"); 
    5389    this->sourcename = sourcename; 
    5490    this->base = base; 
    5591    p = base; 
    5692    end = base + length; 
    5793    linnum = 1; 
    5894    dbuf = NULL; 
    5995    inCode = 0; 
    6096} 
    6197 
    6298/********************************************** 
    6399 * Print error & quit. 
    64100 */ 
    65101 
    66102void Html::error(const char *format, ...) 
    67103{ 
    68     if (!global.gag) 
    69     { 
    70     printf("%s(%d) : HTML Error: ", sourcename, linnum); 
    71  
    72     va_list ap; 
    73     va_start(ap, format); 
    74     vprintf(format, ap); 
    75     va_end(ap); 
    76  
    77     printf("\n"); 
    78     fflush(stdout); 
    79     } 
    80  
    81     global.errors++; 
     104    printf("%s(%d) : HTML Error: ", sourcename, linnum); 
     105 
     106    va_list ap; 
     107    va_start(ap, format); 
     108    vprintf(format, ap); 
     109    va_end(ap); 
     110 
     111    printf("\n"); 
     112    fflush(stdout); 
     113 
     114//#if MARS 
     115//    global.errors++; 
     116//#else 
     117    exit(EXIT_FAILURE); 
     118//#endif 
    82119} 
    83120 
    84121/********************************************** 
    85122 * Extract all the code from an HTML file, 
    86123 * concatenate it all together, and store in buf. 
    87124 */ 
    88125 
     126#if MARS 
    89127void Html::extractCode(OutBuffer *buf) 
     128#else 
     129void Html::extractCode(Outbuffer *buf) 
     130#endif 
    90131{ 
    91132    //printf("Html::extractCode()\n"); 
    92133    dbuf = buf;         // save for other routines 
    93134    buf->reserve(end - p); 
    94135    inCode = 0; 
    95136    while (1) 
    96137    { 
    97138    //printf("p = %p, *p = x%x\n", p, *p); 
    98139    switch (*p) 
    99140    { 
    100141#if 0 // strings are not recognized outside of tags 
    101142        case '"': 
    102143        case '\'': 
    103144        skipString(); 
    104145        continue; 
    105146#endif 
    106147        case '<': 
    107148        if (p[1] == '!' && isCommentStart()) 
    108149        {   // Comments start with <!-- 
    109150            scanComment(); 
     
    113154            scanCDATA(); 
    114155        } 
    115156        else if (p[1] == '/' && istagstart(*skipWhite(p + 2))) 
    116157            skipTag(); 
    117158        else if (istagstart(*skipWhite(p + 1))) 
    118159            skipTag(); 
    119160        else 
    120161            goto Ldefault; 
    121162        continue; 
    122163 
    123164        case 0: 
    124165        case 0x1a: 
    125166        break;      // end of file 
    126167 
    127168        case '&': 
    128169        if (inCode) 
    129170        {   // Translate character entity into ascii for D parser 
    130171            int c; 
    131172 
    132173            c = charEntity(); 
     174#if MARS 
    133175            buf->writeUTF8(c); 
     176#else 
     177            buf->writeByte(c); 
     178#endif 
    134179        } 
    135180        else 
    136181            p++; 
    137182        continue; 
    138183 
    139184        case '\r': 
    140185        if (p[1] == '\n') 
    141186            goto Ldefault; 
    142187        case '\n': 
    143188        linnum++; 
    144189        // Always extract new lines, so that D lexer counts the 
    145190        // lines right. 
    146191        buf->writeByte(*p); 
    147192        p++; 
    148193        continue; 
    149194 
    150195        default: 
    151196        Ldefault: 
    152197        if (inCode) 
    153198            buf->writeByte(*p); 
    154199        p++; 
    155200        continue; 
    156201    } 
    157202    break; 
    158203    } 
    159204    buf->writeByte(0);              // ending sentinel 
     205#if SCPP 
     206    //printf("Code is: '%s'\n", buf->toString() + 3); 
     207#endif 
     208#if MARS 
    160209    //printf("D code is: '%s'\n", (char *)buf->data); 
     210#endif 
    161211} 
    162212 
    163213/*********************************************** 
    164214 * Scan to end of <> tag. 
    165215 * Look for <code> and </code> tags to start/stop D processing. 
    166216 * Input: 
    167217 *  p is on opening '<' of tag; it's already verified that 
    168218 *  it's a tag by lookahead 
    169219 * Output: 
    170220 *  p is past closing '>' of tag 
    171221 */ 
    172222 
    173223void Html::skipTag() 
    174224{ 
    175225    enum TagState   // what parsing state we're in 
    176226    { 
    177227    TStagstart, // start of tag name 
    178228    TStag,      // in a tag name 
    179229    TSrest,     // following tag name 
    180230    }; 
     
    514564    p += len; 
    515565    return 1; 
    516566    } 
    517567    else 
    518568    { 
    519569    return 0; 
    520570    } 
    521571} 
    522572 
    523573void Html::scanCDATA() 
    524574{ 
    525575    while(*p && *p != 0x1A) 
    526576    { 
    527577    int lineSepLength = isLineSeparator(p); 
    528578    if (lineSepLength>0) 
    529579    { 
    530580        /* Always extract new lines, so that D lexer counts the lines 
    531581         * right. 
    532582         */ 
    533583        linnum++; 
    534         dbuf->writeUTF8('\n'); 
     584        dbuf->writeByte('\n'); 
    535585        p += lineSepLength; 
    536586        continue; 
    537587        } 
    538588    else if (p[0] == ']' && p[1] == ']' && p[2] == '>') 
    539589    { 
    540590        /* end of CDATA section */ 
    541591        p += 3; 
    542592        return; 
    543593    } 
    544594    else if (inCode) 
    545595    { 
    546596        /* this CDATA section contains D code */ 
    547597        dbuf->writeByte(*p); 
    548598    } 
    549599 
    550600    p++; 
    551601    } 
    552602} 
    553603 
    554604/******************************************** 
  • trunk/src/backend/html.h

    r125 r183  
    11 
    2 // Compiler implementation of the D programming language 
    32// Copyright (c) 1999-2006 by Digital Mars 
    43// All Rights Reserved 
    54// written by Walter Bright 
    6 // http://www.digitalmars.com 
     5// www.digitalmars.com 
    76// License for redistribution is by either the Artistic License 
    87// in artistic.txt, or the GNU General Public License in gnu.txt. 
    98// See the included readme.txt for details. 
    109 
    11 #ifndef DMD_HTML_H 
    12 #define DMD_HTML_H 1 
    1310 
     11#if MARS 
    1412struct OutBuffer; 
     13#else 
     14struct Outbuffer; 
     15#endif 
    1516 
    1617struct Html 
    1718{ 
    1819    const char *sourcename; 
    1920 
    2021    unsigned char *base;    // pointer to start of buffer 
    2122    unsigned char *end;     // past end of buffer 
    2223    unsigned char *p;       // current character 
    2324    unsigned linnum;        // current line number 
     25#if MARS 
    2426    OutBuffer *dbuf;        // code source buffer 
     27#else 
     28    Outbuffer *dbuf;        // code source buffer 
     29#endif 
    2530    int inCode;         // !=0 if in code 
    2631 
    2732 
    2833    Html(const char *sourcename, unsigned char *base, unsigned length); 
    2934 
    3035    void error(const char *format, ...); 
     36#if MARS 
    3137    void extractCode(OutBuffer *buf); 
     38#else 
     39    void extractCode(Outbuffer *buf); 
     40#endif 
    3241    void skipTag(); 
    3342    void skipString(); 
    3443    unsigned char *skipWhite(unsigned char *q); 
    3544    void scanComment(); 
    3645    int isCommentStart(); 
    3746    void scanCDATA(); 
    3847    int isCDATAStart(); 
    3948    int charEntity(); 
    4049    static int namedEntity(unsigned char *p, int length); 
    4150}; 
    42  
    43 #endif 
  • trunk/src/backend/machobj.c

    r182 r183  
    11 
    2 //_ machobj.c   Modified by: Walter Bright 
    3 // Copyright (c) 2009 by Digital Mars, http://www.digitalmars.com 
     2// Copyright (c) 2009 by Digital Mars 
    43// All Rights Reserved 
    5 // Written by Walter Bright 
    6 // Output to Mach-O object files 
     4// written by Walter Bright 
     5// http://www.digitalmars.com 
     6// License for redistribution is by either the Artistic License 
     7// in artistic.txt, or the GNU General Public License in gnu.txt. 
     8// See the included readme.txt for details. 
     9 
    710 
    811#if SCPP || MARS 
    912#include    <stdio.h> 
    1013#include    <string.h> 
    1114#include    <stdlib.h> 
    1215#include    <sys/types.h> 
    1316#include    <sys/stat.h> 
    1417#include    <fcntl.h> 
    1518#include    <ctype.h> 
    1619 
    1720#if _WIN32 || linux 
    1821#include    <malloc.h> 
    1922#endif 
    2023 
    2124#if linux || __APPLE__ 
    2225#include    <signal.h> 
    2326#include    <unistd.h> 
    2427#endif 
    2528 
    2629#include    "cc.h" 
     
    14071410 *  segment index of found or newly created segment 
    14081411 */ 
    14091412 
    14101413int mach_getsegment(const char *sectname, const char *segname, 
    14111414    int align, int flags) 
    14121415{ 
    14131416    assert(strlen(sectname) <= 16); 
    14141417    assert(strlen(segname)  <= 16); 
    14151418    for (int seg = 1; seg <= seg_count; seg++) 
    14161419    {   seg_data *pseg = SegData[seg]; 
    14171420    if (strncmp(SecHdrTab[pseg->SDshtidx].sectname, sectname, 16) == 0 && 
    14181421        strncmp(SecHdrTab[pseg->SDshtidx].segname, segname, 16) == 0) 
    14191422        return seg;     // return existing segment 
    14201423    } 
    14211424 
    14221425    int seg = ++seg_count; 
    14231426    if (seg_count >= seg_max) 
    14241427    {               // need more room in segment table 
    14251428    seg_max += 10; 
    14261429    SegData = (seg_data **)mem_realloc(SegData,seg_max * sizeof(seg_data *)); 
    1427     memset(&SegData[seg_count], 0, 10 * sizeof(seg_data *)); 
     1430    memset(&SegData[seg_count], 0, (seg_max - seg_count) * sizeof(seg_data *)); 
    14281431    } 
    14291432    assert(seg_count < seg_max); 
    14301433    if (SegData[seg]) 
    14311434    {   seg_data *pseg = SegData[seg]; 
    14321435    Outbuffer *b1 = pseg->SDbuf; 
    14331436    Outbuffer *b2 = pseg->SDrel; 
    14341437    memset(pseg, 0, sizeof(seg_data)); 
    14351438    if (b1) 
    14361439        b1->setsize(0); 
    14371440    if (b2) 
    14381441        b2->setsize(0); 
    14391442    pseg->SDbuf = b1; 
    14401443    pseg->SDrel = b2; 
    14411444    } 
    14421445    else 
    14431446    { 
    14441447    seg_data *pseg = (seg_data *)mem_calloc(sizeof(seg_data)); 
    14451448    SegData[seg] = pseg; 
    14461449    if (flags != S_ZEROFILL) 
    14471450    {   pseg->SDbuf = new Outbuffer(4096); 
     
    16081611#if TARGET_LINUX || TARGET_OSX 
    16091612        if (tyfunc(s->ty()) && !variadic(s->Stype)) 
    16101613#else 
    16111614        if (!(config.flags4 & CFG4oldstdmangle) && 
    16121615        config.exe == EX_NT && tyfunc(s->ty()) && 
    16131616        !variadic(s->Stype)) 
    16141617#endif 
    16151618        { 
    16161619        char *pstr = unsstr(type_paramsize(s->Stype)); 
    16171620        size_t pstrlen = strlen(pstr); 
    16181621        size_t destlen = len + 1 + pstrlen + 1; 
    16191622 
    16201623        if (destlen > DEST_LEN) 
    16211624            dest = (char *)mem_malloc(destlen); 
    16221625        memcpy(dest,name,len); 
    16231626        dest[len] = '@'; 
    16241627        memcpy(dest + 1 + len, pstr, pstrlen + 1); 
    16251628        break; 
    16261629        } 
    16271630    case mTYman_cpp: 
    1628     case mTYman_java
     1631    case mTYman_d
    16291632    case mTYman_sys: 
    16301633    case 0: 
    16311634        if (len >= DEST_LEN) 
    16321635        dest = (char *)mem_malloc(len + 1); 
    16331636        memcpy(dest,name,len+1);// copy in name and trailing 0 
    16341637        break; 
    16351638 
    16361639    case mTYman_c: 
    16371640        if (len >= DEST_LEN - 1) 
    16381641        dest = (char *)mem_malloc(1 + len + 1); 
    16391642        dest[0] = '_'; 
    16401643        memcpy(dest + 1,name,len+1);// copy in name and trailing 0 
    16411644        break; 
    16421645 
    16431646 
    16441647    default: 
    16451648#ifdef DEBUG 
    16461649        printf("mangling %x\n",type_mangle(s->Stype)); 
    16471650        symbol_print(s); 
    16481651#endif 
  • trunk/src/builtin.c

    r163 r183  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <assert.h> 
    1313#include <math.h> 
    1414 
    1515#include "mars.h" 
    1616#include "declaration.h" 
    1717#include "attrib.h" 
    1818#include "expression.h" 
    1919#include "scope.h" 
    2020#include "mtype.h" 
    2121#include "aggregate.h" 
    2222#include "identifier.h" 
    2323#include "id.h" 
    2424#include "module.h" 
    2525 
     26#if V2 
     27 
    2628/********************************** 
    2729 * Determine if function is a builtin one. 
    2830 */ 
    2931enum BUILTIN FuncDeclaration::isBuiltin() 
    3032{ 
    31     static const char FeZe[] = "FeZe"; // real function(real) 
     33    static const char FeZe[] = "FNaNbeZe"; // pure nothrow real function(real) 
    3234 
    3335    //printf("FuncDeclaration::isBuiltin() %s\n", toChars()); 
    3436    if (builtin == BUILTINunknown) 
    3537    { 
    3638    builtin = BUILTINnot; 
    3739    if (parent && parent->isModule()) 
    3840    { 
    3941        if (parent->ident == Id::math && 
    4042        parent->parent && parent->parent->ident == Id::std && 
    4143        !parent->parent->parent) 
    4244        { 
     45        //printf("deco = %s\n", type->deco); 
    4346        if (strcmp(type->deco, FeZe) == 0) 
    4447        { 
    4548            if (ident == Id::sin) 
    4649            builtin = BUILTINsin; 
    4750            else if (ident == Id::cos) 
    4851            builtin = BUILTINcos; 
    4952            else if (ident == Id::tan) 
    5053            builtin = BUILTINtan; 
    5154            else if (ident == Id::_sqrt) 
    5255            builtin = BUILTINsqrt; 
    5356            else if (ident == Id::fabs) 
    5457            builtin = BUILTINfabs; 
    5558            //printf("builtin = %d\n", builtin); 
    5659        } 
     60        else if (strcmp(type->deco, "FNaNbdZd") == 0 || 
     61             strcmp(type->deco, "FNaNbfZf") == 0) 
     62            builtin = BUILTINsqrt; 
    5763        } 
    5864    } 
    5965    } 
    6066    return builtin; 
    6167} 
    6268 
    6369 
    6470/************************************** 
    6571 * Evaluate builtin function. 
    6672 * Return result; NULL if cannot evaluate it. 
    6773 */ 
    6874 
    6975Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments) 
    7076{ 
    7177    assert(arguments && arguments->dim); 
    7278    Expression *arg0 = (Expression *)arguments->data[0]; 
    7379    Expression *e = NULL; 
    7480    switch (builtin) 
    7581    { 
    7682    case BUILTINsin: 
     
    8389        e = new RealExp(0, cosl(arg0->toReal()), Type::tfloat80); 
    8490        break; 
    8591 
    8692    case BUILTINtan: 
    8793        if (arg0->op == TOKfloat64) 
    8894        e = new RealExp(0, tanl(arg0->toReal()), Type::tfloat80); 
    8995        break; 
    9096 
    9197    case BUILTINsqrt: 
    9298        if (arg0->op == TOKfloat64) 
    9399        e = new RealExp(0, sqrtl(arg0->toReal()), Type::tfloat80); 
    94100        break; 
    95101 
    96102    case BUILTINfabs: 
    97103        if (arg0->op == TOKfloat64) 
    98104        e = new RealExp(0, fabsl(arg0->toReal()), Type::tfloat80); 
    99105        break; 
    100106    } 
    101107    return e; 
    102108} 
     109 
     110#endif 
  • trunk/src/cast.c

    r181 r183  
    11 
    22// Copyright (c) 1999-2008 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010#include <stdio.h> 
    1111#include <assert.h> 
    1212 
    13 #if _WIN32 || IN_GCC 
    14 #include "mem.h" 
    15 #else 
    16 #include "../root/mem.h" 
    17 #endif 
     13#include "rmem.h" 
    1814 
    1915#include "expression.h" 
    2016#include "mtype.h" 
    2117#include "utf.h" 
    2218#include "declaration.h" 
    2319#include "aggregate.h" 
    2420 
    2521/* ==================== implicitCast ====================== */ 
    2622 
    2723/************************************** 
    2824 * Do an implicit cast. 
    2925 * Issue error if it can't be done. 
    3026 */ 
    3127 
    3228Expression *Expression::implicitCastTo(Scope *sc, Type *t) 
    3329{ 
    3430    //printf("Expression::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars()); 
    3531 
    3632    MATCH match = implicitConvTo(t); 
    3733    if (match) 
     
    4440        Expression *e = optimize(WANTflags | WANTvalue); 
    4541 
    4642        if (e->op == TOKint64) 
    4743        return e->implicitCastTo(sc, t); 
    4844 
    4945        if (tyfrom == Tint32 && 
    5046        (op == TOKadd || op == TOKmin || 
    5147         op == TOKand || op == TOKor || op == TOKxor) 
    5248           ) 
    5349        { 
    5450        /* This is really only a semi-kludge fix, 
    5551         * we really should look at the operands of op 
    5652         * and see if they are narrower types. 
    5753         * For example, b=b|b and b=b|7 and s=b+b should be allowed, 
    5854         * but b=b|i should be an error. 
    5955         */ 
    6056        ; 
    6157        } 
    6258        else 
    6359        { 
    64         fprintf(stdmsg, "warning - "); 
    65         error("implicit conversion of expression (%s) of type %s to %s can cause loss of data", 
     60        warning("implicit conversion of expression (%s) of type %s to %s can cause loss of data", 
    6661            toChars(), type->toChars(), t->toChars()); 
    6762        } 
    6863    } 
    6964#if V2 
    7065    if (match == MATCHconst && t == type->constOf()) 
    7166    { 
    7267        Expression *e = copy(); 
    7368        e->type = t; 
    7469        return e; 
    7570    } 
    7671#endif 
    7772    return castTo(sc, t); 
    7873    } 
    7974 
    8075    Expression *e = optimize(WANTflags | WANTvalue); 
    8176    if (e != this) 
    8277    return e->implicitCastTo(sc, t); 
    8378 
    8479#if 0 
    8580printf("ty = %d\n", type->ty); 
     
    17081703        break; 
    17091704 
    17101705    case Tint8: 
    17111706    case Tuns8: 
    17121707    case Tint16: 
    17131708    case Tuns16: 
    17141709    case Tbit: 
    17151710    case Tbool: 
    17161711    case Tchar: 
    17171712    case Twchar: 
    17181713        e = e->castTo(sc, Type::tint32); 
    17191714        break; 
    17201715 
    17211716    case Tdchar: 
    17221717        e = e->castTo(sc, Type::tuns32); 
    17231718        break; 
    17241719    } 
    17251720    return e; 
    17261721} 
    17271722 
     1723/*********************************** 
     1724 * See if both types are arrays that can be compared 
     1725 * for equality. Return !=0 if so. 
     1726 * If they are arrays, but incompatible, issue error. 
     1727 * This is to enable comparing things like an immutable 
     1728 * array with a mutable one. 
     1729 */ 
     1730 
     1731int arrayTypeCompatible(Loc loc, Type *t1, Type *t2) 
     1732{ 
     1733    t1 = t1->toBasetype(); 
     1734    t2 = t2->toBasetype(); 
     1735 
     1736    if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 
     1737    (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 
     1738    { 
     1739    if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 
     1740        t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 
     1741        (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 
     1742    { 
     1743        error("array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 
     1744    } 
     1745    return 1; 
     1746    } 
     1747    return 0; 
     1748} 
  • trunk/src/class.c

    r180 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    1515#include "root.h" 
    16 #include "mem.h" 
     16#include "rmem.h" 
    1717 
    1818#include "enum.h" 
    1919#include "init.h" 
    2020#include "attrib.h" 
    2121#include "declaration.h" 
    2222#include "aggregate.h" 
    2323#include "id.h" 
    2424#include "mtype.h" 
    2525#include "scope.h" 
    2626#include "module.h" 
    2727#include "expression.h" 
    2828#include "statement.h" 
    2929 
    3030/********************************* ClassDeclaration ****************************/ 
    3131 
    3232ClassDeclaration *ClassDeclaration::classinfo; 
    3333ClassDeclaration *ClassDeclaration::object; 
    3434 
    3535ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses) 
    3636    : AggregateDeclaration(loc, id) 
     
    171171        object->error("%s", msg); 
    172172        object = this; 
    173173    } 
    174174 
    175175    if (id == Id::ClassInfo) 
    176176    {   if (classinfo) 
    177177        classinfo->error("%s", msg); 
    178178        classinfo = this; 
    179179    } 
    180180 
    181181    if (id == Id::ModuleInfo) 
    182182    {   if (Module::moduleinfo) 
    183183        Module::moduleinfo->error("%s", msg); 
    184184        Module::moduleinfo = this; 
    185185    } 
    186186    } 
    187187 
    188188    com = 0; 
    189189    isauto = 0; 
    190190    isabstract = 0; 
    191     isnested = 0; 
    192     vthis = NULL; 
    193191    inuse = 0; 
    194192} 
    195193 
    196194Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) 
    197195{ 
    198196    ClassDeclaration *cd; 
    199197 
    200198    //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars()); 
    201199    if (s) 
    202200    cd = (ClassDeclaration *)s; 
    203201    else 
    204202    cd = new ClassDeclaration(loc, ident, NULL); 
    205203 
    206204    cd->storage_class |= storage_class; 
    207205 
    208206    cd->baseclasses.setDim(this->baseclasses.dim); 
    209207    for (int i = 0; i < cd->baseclasses.dim; i++) 
    210208    { 
    211209    BaseClass *b = (BaseClass *)this->baseclasses.data[i]; 
    212210    BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); 
     
    489487        if (toParent2()) 
    490488        { 
    491489            error("is nested within %s, but super class %s is nested within %s", 
    492490            toParent2()->toChars(), 
    493491            baseClass->toChars(), 
    494492            baseClass->toParent2()->toChars()); 
    495493        } 
    496494        else 
    497495        { 
    498496            error("is not nested, but super class %s is nested within %s", 
    499497            baseClass->toChars(), 
    500498            baseClass->toParent2()->toChars()); 
    501499        } 
    502500        isnested = 0; 
    503501        } 
    504502    } 
    505503    else if (!(storage_class & STCstatic)) 
    506504    {   Dsymbol *s = toParent2(); 
    507505        if (s) 
    508506        { 
    509         ClassDeclaration *cd = s->isClassDeclaration(); 
     507        AggregateDeclaration *ad = s->isClassDeclaration(); 
    510508        FuncDeclaration *fd = s->isFuncDeclaration(); 
    511509 
    512510 
    513         if (cd || fd) 
     511        if (ad || fd) 
    514512        {   isnested = 1; 
    515513            Type *t; 
    516             if (cd) 
    517             t = cd->type; 
     514            if (ad) 
     515            t = ad->handle; 
    518516            else if (fd) 
    519517            {   AggregateDeclaration *ad = fd->isMember2(); 
    520518            if (ad) 
    521519                t = ad->handle; 
    522520            else 
    523521            { 
    524                 t = new TypePointer(Type::tvoid); 
    525                 t = t->semantic(0, sc); 
     522                t = Type::tvoidptr; 
    526523            } 
    527524            } 
    528525            else 
    529526            assert(0); 
     527            if (t->ty == Tstruct)   // ref to struct 
     528            t = Type::tvoidptr; 
    530529            assert(!vthis); 
    531530            vthis = new ThisDeclaration(t); 
    532531            members->push(vthis); 
    533532        } 
    534533        } 
    535534    } 
    536535    } 
    537536 
    538537    if (storage_class & (STCauto | STCscope)) 
    539538    isauto = 1; 
    540539    if (storage_class & STCabstract) 
    541540    isabstract = 1; 
    542541    if (storage_class & STCinvariant) 
    543542    type = type->invariantOf(); 
    544543    else if (storage_class & STCconst) 
    545544    type = type->constOf(); 
    546545 
    547546    sc = sc->push(this); 
    548547    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
    549548         STCabstract | STCdeprecated | STCconst | STCinvariant | STCtls); 
     
    868867    return !overloadApply(fdstart, &isf, fd); 
    869868    } 
    870869} 
    871870#endif 
    872871 
    873872/**************** 
    874873 * Find virtual function matching identifier and type. 
    875874 * Used to build virtual function tables for interface implementations. 
    876875 */ 
    877876 
    878877FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) 
    879878{ 
    880879    //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars()); 
    881880 
    882881    ClassDeclaration *cd = this; 
    883882    Array *vtbl = &cd->vtbl; 
    884883    while (1) 
    885884    { 
    886885    for (size_t i = 0; i < vtbl->dim; i++) 
    887886    { 
    888         FuncDeclaration *fd = (FuncDeclaration *)vtbl->data[i]; 
     887        FuncDeclaration *fd = ((Dsymbol*)vtbl->data[i])->isFuncDeclaration(); 
     888        if (!fd) 
     889        continue;       // the first entry might be a ClassInfo 
    889890 
    890891        //printf("\t[%d] = %s\n", i, fd->toChars()); 
    891892        if (ident == fd->ident && 
    892893        //tf->equals(fd->type) 
    893894        fd->type->covariant(tf) == 1 
    894895           ) 
    895896        {   //printf("\t\tfound\n"); 
    896897        return fd; 
    897898        } 
    898899        //else printf("\t\t%d\n", fd->type->covariant(tf)); 
    899900    } 
    900901    if (!cd) 
    901902        break; 
    902903    vtbl = &cd->vtblFinal; 
    903904    cd = cd->baseClass; 
    904905    } 
    905906 
    906907    return NULL; 
    907908} 
    908909 
     
    953954 */ 
    954955 
    955956int ClassDeclaration::isAbstract() 
    956957{ 
    957958    if (isabstract) 
    958959    return TRUE; 
    959960    for (int i = 1; i < vtbl.dim; i++) 
    960961    { 
    961962    FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration(); 
    962963 
    963964    //printf("\tvtbl[%d] = %p\n", i, fd); 
    964965    if (!fd || fd->isAbstract()) 
    965966    { 
    966967        isabstract |= 1; 
    967968        return TRUE; 
    968969    } 
    969970    } 
    970971    return FALSE; 
    971972} 
    972973 
    973  
    974 /**************************************** 
    975  * Returns !=0 if there's an extra member which is the 'this' 
    976  * pointer to the enclosing context (enclosing class or function) 
    977  */ 
    978  
    979 int ClassDeclaration::isNested() 
    980 { 
    981     return isnested; 
    982 } 
    983974 
    984975/**************************************** 
    985976 * Determine if slot 0 of the vtbl[] is reserved for something else. 
    986977 * For class objects, yes, this is where the classinfo ptr goes. 
    987978 * For COM interfaces, no. 
    988979 * For non-COM interfaces, yes, this is where the Interface ptr goes. 
    989980 */ 
    990981 
    991982int ClassDeclaration::vtblOffset() 
    992983{ 
    993984    return 1; 
    994985} 
    995986 
    996987/**************************************** 
    997988 */ 
    998989 
    999990const char *ClassDeclaration::kind() 
    1000991{ 
    1001992    return "class"; 
    1002993} 
  • trunk/src/clone.c

    r179 r183  
    3030 */ 
    3131 
    3232int StructDeclaration::needOpAssign() 
    3333{ 
    3434#define X 0 
    3535    if (X) printf("StructDeclaration::needOpAssign() %s\n", toChars()); 
    3636    if (hasIdentityAssign) 
    3737    goto Ldontneed; 
    3838 
    3939    if (dtor || postblit) 
    4040    goto Lneed; 
    4141 
    4242    /* If any of the fields need an opAssign, then we 
    4343     * need it too. 
    4444     */ 
    4545    for (size_t i = 0; i < fields.dim; i++) 
    4646    { 
    4747    Dsymbol *s = (Dsymbol *)fields.data[i]; 
    4848    VarDeclaration *v = s->isVarDeclaration(); 
    4949    assert(v && v->storage_class & STCfield); 
     50    if (v->storage_class & STCref) 
     51        continue; 
    5052    Type *tv = v->type->toBasetype(); 
    5153    while (tv->ty == Tsarray) 
    5254    {   TypeSArray *ta = (TypeSArray *)tv; 
    5355        tv = tv->nextOf()->toBasetype(); 
    5456    } 
    5557    if (tv->ty == Tstruct) 
    5658    {   TypeStruct *ts = (TypeStruct *)tv; 
    5759        StructDeclaration *sd = ts->sym; 
    5860        if (sd->needOpAssign()) 
    5961        goto Lneed; 
    6062    } 
    6163    } 
    6264Ldontneed: 
    6365    if (X) printf("\tdontneed\n"); 
    6466    return 0; 
    6567 
    6668Lneed: 
    6769    if (X) printf("\tneed\n"); 
    6870    return 1; 
    6971#undef X 
     
    247249 
    248250/***************************************** 
    249251 * Create inclusive postblit for struct by aggregating 
    250252 * all the postblits in postblits[] with the postblits for 
    251253 * all the members. 
    252254 * Note the close similarity with AggregateDeclaration::buildDtor(), 
    253255 * and the ordering changes (runs forward instead of backwards). 
    254256 */ 
    255257 
    256258#if V2 
    257259FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc) 
    258260{ 
    259261    //printf("StructDeclaration::buildPostBlit() %s\n", toChars()); 
    260262    Expression *e = NULL; 
    261263 
    262264    for (size_t i = 0; i < fields.dim; i++) 
    263265    { 
    264266    Dsymbol *s = (Dsymbol *)fields.data[i]; 
    265267    VarDeclaration *v = s->isVarDeclaration(); 
    266268    assert(v && v->storage_class & STCfield); 
     269    if (v->storage_class & STCref) 
     270        continue; 
    267271    Type *tv = v->type->toBasetype(); 
    268272    size_t dim = 1; 
    269273    while (tv->ty == Tsarray) 
    270274    {   TypeSArray *ta = (TypeSArray *)tv; 
    271275        dim *= ((TypeSArray *)tv)->dim->toInteger(); 
    272276        tv = tv->nextOf()->toBasetype(); 
    273277    } 
    274278    if (tv->ty == Tstruct) 
    275279    {   TypeStruct *ts = (TypeStruct *)tv; 
    276280        StructDeclaration *sd = ts->sym; 
    277281        if (sd->postblit) 
    278282        {   Expression *ex; 
    279283 
    280284        // this.v 
    281285        ex = new ThisExp(0); 
    282286        ex = new DotVarExp(0, ex, v, 0); 
    283287 
    284288        if (dim == 1) 
    285289        {   // this.v.dtor() 
    286290            ex = new DotVarExp(0, ex, sd->postblit, 0); 
     
    342346 
    343347/***************************************** 
    344348 * Create inclusive destructor for struct/class by aggregating 
    345349 * all the destructors in dtors[] with the destructors for 
    346350 * all the members. 
    347351 * Note the close similarity with StructDeclaration::buildPostBlit(), 
    348352 * and the ordering changes (runs backward instead of forwards). 
    349353 */ 
    350354 
    351355FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc) 
    352356{ 
    353357    //printf("AggregateDeclaration::buildDtor() %s\n", toChars()); 
    354358    Expression *e = NULL; 
    355359 
    356360#if V2 
    357361    for (size_t i = 0; i < fields.dim; i++) 
    358362    { 
    359363    Dsymbol *s = (Dsymbol *)fields.data[i]; 
    360364    VarDeclaration *v = s->isVarDeclaration(); 
    361365    assert(v && v->storage_class & STCfield); 
     366    if (v->storage_class & STCref) 
     367        continue; 
    362368    Type *tv = v->type->toBasetype(); 
    363369    size_t dim = 1; 
    364370    while (tv->ty == Tsarray) 
    365371    {   TypeSArray *ta = (TypeSArray *)tv; 
    366372        dim *= ((TypeSArray *)tv)->dim->toInteger(); 
    367373        tv = tv->nextOf()->toBasetype(); 
    368374    } 
    369375    if (tv->ty == Tstruct) 
    370376    {   TypeStruct *ts = (TypeStruct *)tv; 
    371377        StructDeclaration *sd = ts->sym; 
    372378        if (sd->dtor) 
    373379        {   Expression *ex; 
    374380 
    375381        // this.v 
    376382        ex = new ThisExp(0); 
    377383        ex = new DotVarExp(0, ex, v, 0); 
    378384 
    379385        if (dim == 1) 
    380386        {   // this.v.dtor() 
    381387            ex = new DotVarExp(0, ex, sd->dtor, 0); 
  • trunk/src/constfold.c

    r178 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2007 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414#include <math.h> 
    1515 
    1616#if __DMC__ 
    1717#include <complex.h> 
    1818#endif 
    1919 
    20 #include "mem.h" 
     20#include "rmem.h" 
    2121#include "root.h" 
    2222 
    2323#include "mtype.h" 
    2424#include "expression.h" 
    2525#include "aggregate.h" 
    2626#include "declaration.h" 
    2727 
    2828#ifdef IN_GCC 
    2929#include "d-gcc-real.h" 
    3030 
    3131/* %% fix? */ 
    3232extern "C" bool real_isnan (const real_t *); 
    3333#endif 
    3434 
    3535static real_t zero; // work around DMC bug for now 
    3636 
    3737#define LOG 0 
    3838 
    3939Expression *expType(Type *type, Expression *e) 
    4040{ 
  • trunk/src/declaration.c

    r181 r183  
    439439    // it is not knowable from the syntax whether this is an alias 
    440440    // for a type or an alias for a symbol. It is up to the semantic() 
    441441    // pass to distinguish. 
    442442    // If it is a type, then type is set and getType() will return that 
    443443    // type. If it is a symbol, then aliassym is set and type is NULL - 
    444444    // toAlias() will return aliasssym. 
    445445 
    446446    Dsymbol *s; 
    447447    Type *t; 
    448448    Expression *e; 
    449449 
    450450    /* This section is needed because resolve() will: 
    451451     *   const x = 3; 
    452452     *   alias x y; 
    453453     * try to alias y to 3. 
    454454     */ 
    455455    s = type->toDsymbol(sc); 
    456456    if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())) 
    457457    goto L2;            // it's a symbolic alias 
    458458 
    459     //printf("alias type is %s\n", type->toChars()); 
    460     type->resolve(loc, sc, &e, &t, &s); 
     459    if (storage_class & STCref) 
     460    {   // For 'ref' to be attached to function types, and picked 
     461    // up by Type::resolve(), it has to go into sc. 
     462    sc = sc->push(); 
     463    sc->stc |= STCref; 
     464    type->resolve(loc, sc, &e, &t, &s); 
     465    sc = sc->pop(); 
     466    } 
     467    else 
     468    type->resolve(loc, sc, &e, &t, &s); 
    461469    if (s) 
    462470    { 
    463471    goto L2; 
    464472    } 
    465473    else if (e) 
    466474    { 
    467475    // Try to convert Expression to Dsymbol 
    468476    s = getDsymbol(e); 
    469477    if (s) 
    470478        goto L2; 
    471479 
    472480    error("cannot alias an expression %s", e->toChars()); 
    473481    t = e->type; 
    474482    } 
    475483    else if (t) 
    476484    type = t; 
    477485    if (overnext) 
    478486    ScopeDsymbol::multiplyDefined(0, this, overnext); 
    479487    this->inSemantic = 0; 
    480488    return; 
     
    840848    if (ti) 
    841849    { 
    842850        // Take care of nested templates 
    843851        while (1) 
    844852        { 
    845853        TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 
    846854        if (!ti2) 
    847855            break; 
    848856        ti = ti2; 
    849857        } 
    850858 
    851859        // If it's a member template 
    852860        AggregateDeclaration *ad = ti->tempdecl->isMember(); 
    853861        if (ad && storage_class != STCundefined) 
    854862        { 
    855863        error("cannot use template to add field to aggregate '%s'", ad->toChars()); 
    856864        } 
    857865    } 
    858866    } 
    859867 
    860     if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref) 
     868    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 
     869    ident != Id::This) 
     870    { 
    861871    error("only parameters or foreach declarations can be ref"); 
     872    } 
    862873 
    863874    if (type->isauto() && !noauto) 
    864875    { 
    865876    if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd) 
    866877    { 
    867878        error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 
    868879    } 
    869880 
    870881    if (!(storage_class & (STCauto | STCscope))) 
    871882    { 
    872883        if (!(storage_class & STCparameter) && ident != Id::withSym) 
    873884        error("reference to scope class must be scope"); 
    874885    } 
    875886    } 
    876887 
    877888    if ((isConst() || isInvariant()) && !init && !fd) 
    878889    {   // Initialize by constructor only 
    879890    storage_class |= STCctorinit; 
    880891    } 
    881892 
     
    886897 
    887898    enum TOK op = TOKconstruct; 
    888899    if (!init && !sc->inunion && !isStatic() && fd && 
    889900    (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && 
    890901    type->size() != 0) 
    891902    { 
    892903    // Provide a default initializer 
    893904    //printf("Providing default initializer for '%s'\n", toChars()); 
    894905    if (type->ty == Tstruct && 
    895906        ((TypeStruct *)type)->sym->zeroInit == 1) 
    896907    {   /* If a struct is all zeros, as a special case 
    897908         * set it's initializer to the integer 0. 
    898909         * In AssignExp::toElem(), we check for this and issue 
    899910         * a memset() to initialize the struct. 
    900911         * Must do same check in interpreter. 
    901912         */ 
    902913        Expression *e = new IntegerExp(loc, 0, Type::tint32); 
    903914        Expression *e1; 
    904915        e1 = new VarExp(loc, this); 
    905916        e = new AssignExp(loc, e1, e); 
     917        e->op = TOKconstruct; 
    906918        e->type = e1->type;     // don't type check this, it would fail 
    907919        init = new ExpInitializer(loc, e); 
    908920        return; 
    909921    } 
    910922    else if (type->ty == Ttypedef) 
    911923    {   TypeTypedef *td = (TypeTypedef *)type; 
    912924        if (td->sym->init) 
    913925        {   init = td->sym->init; 
    914926        ExpInitializer *ie = init->isExpInitializer(); 
    915927        if (ie) 
    916928            // Make copy so we can modify it 
    917929            init = new ExpInitializer(ie->loc, ie->exp); 
    918930        } 
    919931        else 
    920932        init = getExpInitializer(); 
    921933    } 
    922934    else 
    923935    { 
    924936        init = getExpInitializer(); 
    925937    } 
  • trunk/src/declaration.h

    r180 r183  
    420420{ 
    421421    TypeInfoInvariantDeclaration(Type *tinfo); 
    422422 
    423423    void toDt(dt_t **pdt); 
    424424}; 
    425425 
    426426struct TypeInfoSharedDeclaration : TypeInfoDeclaration 
    427427{ 
    428428    TypeInfoSharedDeclaration(Type *tinfo); 
    429429 
    430430    void toDt(dt_t **pdt); 
    431431}; 
    432432#endif 
    433433 
    434434/**************************************************************/ 
    435435 
    436436struct ThisDeclaration : VarDeclaration 
    437437{ 
    438438    ThisDeclaration(Type *t); 
    439439    Dsymbol *syntaxCopy(Dsymbol *); 
     440    ThisDeclaration *isThisDeclaration() { return this; } 
    440441}; 
    441442 
    442443enum ILS 
    443444{ 
    444445    ILSuninitialized,   // not computed yet 
    445446    ILSno,      // cannot inline 
    446447    ILSyes,     // can inline 
    447448}; 
    448449 
    449450/**************************************************************/ 
    450451#if V2 
    451452 
    452453enum BUILTIN 
    453454{ 
    454455    BUILTINunknown = -1,    // not known if this is a builtin 
    455456    BUILTINnot,         // this is not a builtin 
    456457    BUILTINsin,         // std.math.sin 
    457458    BUILTINcos,         // std.math.cos 
    458459    BUILTINtan,         // std.math.tan 
    459460    BUILTINsqrt,        // std.math.sqrt 
  • trunk/src/doc.c

    r182 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111// This implements the Ddoc capability. 
    1212 
    1313#include <stdio.h> 
    1414#include <string.h> 
    1515#include <time.h> 
    1616#include <ctype.h> 
    1717#include <assert.h> 
    1818 
    19 #ifdef IN_GCC 
    20 #include "mem.h" 
    21 #else 
    22 #if _WIN32 
    23 #include "..\root\mem.h" 
    24 #elif linux || __APPLE__ 
    25 #include "../root/mem.h" 
    26 #else 
    27 #error "fix this" 
    28 #endif 
    29 #endif 
    30  
     19#include "rmem.h" 
    3120#include "root.h" 
    3221 
    3322#include "mars.h" 
    3423#include "dsymbol.h" 
    3524#include "macro.h" 
    3625#include "template.h" 
    3726#include "lexer.h" 
    3827#include "aggregate.h" 
    3928#include "declaration.h" 
    4029#include "enum.h" 
    4130#include "id.h" 
    4231#include "module.h" 
    4332#include "scope.h" 
    4433#include "hdrgen.h" 
    4534#include "doc.h" 
    4635#include "mtype.h" 
    4736 
    4837struct Escape 
    4938{ 
    5039    const char *strings[256]; 
  • trunk/src/dsymbol.c

    r180 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <string.h> 
    1313#include <assert.h> 
    1414 
    15 #include "mem.h" 
     15#include "rmem.h" 
    1616 
    1717#include "mars.h" 
    1818#include "dsymbol.h" 
    1919#include "aggregate.h" 
    2020#include "identifier.h" 
    2121#include "module.h" 
    2222#include "mtype.h" 
    2323#include "expression.h" 
    2424#include "statement.h" 
    2525#include "declaration.h" 
    2626#include "id.h" 
    2727#include "scope.h" 
    2828#include "init.h" 
    2929#include "import.h" 
    3030#include "template.h" 
    3131#include "attrib.h" 
    3232 
    3333/****************************** Dsymbol ******************************/ 
    3434 
    3535Dsymbol::Dsymbol() 
     
    989989 
    990990ArrayScopeSymbol::ArrayScopeSymbol(Scope *sc, TupleDeclaration *s) 
    991991    : ScopeDsymbol() 
    992992{ 
    993993    exp = NULL; 
    994994    type = NULL; 
    995995    td = s; 
    996996    this->sc = sc; 
    997997} 
    998998 
    999999Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags) 
    10001000{ 
    10011001    //printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident->toChars(), flags); 
    10021002    if (ident == Id::length || ident == Id::dollar) 
    10031003    {   VarDeclaration **pvar; 
    10041004    Expression *ce; 
    10051005 
    10061006    L1: 
    10071007 
    10081008    if (td) 
    1009     { 
     1009    {   /* $ gives the number of elements in the tuple 
     1010         */ 
    10101011        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    10111012        Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); 
    10121013        v->init = new ExpInitializer(0, e); 
    10131014        v->storage_class |= STCstatic | STCconst; 
    10141015        v->semantic(sc); 
    10151016        return v; 
    10161017    } 
    10171018 
    10181019    if (type) 
    1019     { 
     1020    {   /* $ gives the number of type entries in the type tuple 
     1021         */ 
    10201022        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    10211023        Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); 
    10221024        v->init = new ExpInitializer(0, e); 
    10231025        v->storage_class |= STCstatic | STCconst; 
    10241026        v->semantic(sc); 
    10251027        return v; 
    10261028    } 
    10271029 
    10281030    if (exp->op == TOKindex) 
    1029     { 
     1031    {   /* array[index] where index is some function of $ 
     1032         */ 
    10301033        IndexExp *ie = (IndexExp *)exp; 
    10311034 
    10321035        pvar = &ie->lengthVar; 
    10331036        ce = ie->e1; 
    10341037    } 
    10351038    else if (exp->op == TOKslice) 
    1036     { 
     1039    {   /* array[lwr .. upr] where lwr or upr is some function of $ 
     1040         */ 
    10371041        SliceExp *se = (SliceExp *)exp; 
    10381042 
    10391043        pvar = &se->lengthVar; 
    10401044        ce = se->e1; 
    10411045    } 
    10421046    else 
     1047        /* Didn't find $, look in enclosing scope(s). 
     1048         */ 
    10431049        return NULL; 
    10441050 
     1051    /* If we are indexing into an array that is really a type 
     1052     * tuple, rewrite this as an index into a type tuple and 
     1053     * try again. 
     1054     */ 
    10451055    if (ce->op == TOKtype) 
    10461056    { 
    10471057        Type *t = ((TypeExp *)ce)->type; 
    10481058        if (t->ty == Ttuple) 
    10491059        {   type = (TypeTuple *)t; 
    10501060        goto L1; 
    10511061        } 
    10521062    } 
    10531063 
    1054     if (!*pvar) 
    1055     { 
     1064    /* *pvar is lazily initialized, so if we refer to $ 
     1065     * multiple times, it gets set only once. 
     1066     */ 
     1067    if (!*pvar)     // if not already initialized 
     1068    {   /* Create variable v and set it to the value of $, 
     1069         * which will be a constant. 
     1070         */ 
    10561071        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    10571072 
    10581073        if (ce->op == TOKvar) 
    10591074        {   // if ce is const, get its initializer 
    10601075        ce = fromConstInitializer(WANTvalue | WANTinterpret, ce); 
    10611076        } 
    10621077 
    10631078        if (ce->op == TOKstring) 
    10641079        {   /* It is for a string literal, so the 
    10651080         * length will be a const. 
    10661081         */ 
    10671082        Expression *e = new IntegerExp(0, ((StringExp *)ce)->len, Type::tsize_t); 
    10681083        v->init = new ExpInitializer(0, e); 
    10691084        v->storage_class |= STCstatic | STCconst; 
    10701085        } 
    10711086        else if (ce->op == TOKarrayliteral) 
    10721087        {   /* It is for an array literal, so the 
    10731088         * length will be a const. 
    10741089         */ 
    10751090        Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t); 
  • trunk/src/dsymbol.h

    r179 r183  
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#ifndef DMD_DSYMBOL_H 
    1212#define DMD_DSYMBOL_H 
    1313 
    1414#ifdef __DMC__ 
    1515#pragma once 
    1616#endif /* __DMC__ */ 
    1717 
    1818#include "root.h" 
    1919#include "stringtable.h" 
    2020 
    2121#include "mars.h" 
    2222#include "arraytypes.h" 
    2323 
    2424struct Identifier; 
    2525struct Scope; 
    2626struct DsymbolTable; 
    2727struct Declaration; 
     28struct ThisDeclaration; 
    2829struct TupleDeclaration; 
    2930struct TypedefDeclaration; 
    3031struct AliasDeclaration; 
    3132struct AggregateDeclaration; 
    3233struct EnumDeclaration; 
    3334struct ClassDeclaration; 
    3435struct InterfaceDeclaration; 
    3536struct StructDeclaration; 
    3637struct UnionDeclaration; 
    3738struct FuncDeclaration; 
    3839struct FuncAliasDeclaration; 
    3940struct FuncLiteralDeclaration; 
    4041struct CtorDeclaration; 
    4142struct PostBlitDeclaration; 
    4243struct DtorDeclaration; 
    4344struct StaticCtorDeclaration; 
    4445struct StaticDtorDeclaration; 
    4546struct InvariantDeclaration; 
    4647struct UnitTestDeclaration; 
    4748struct NewDeclaration; 
     
    164165 
    165166    // Backend 
    166167 
    167168    virtual Symbol *toSymbol();         // to backend symbol 
    168169    virtual void toObjFile(int multiobj);           // compile to .obj file 
    169170    virtual int cvMember(unsigned char *p); // emit cv debug info for member 
    170171 
    171172    Symbol *toImport();             // to backend import symbol 
    172173    static Symbol *toImport(Symbol *s);     // to backend import symbol 
    173174 
    174175    Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper 
    175176 
    176177    // Eliminate need for dynamic_cast 
    177178    virtual Package *isPackage() { return NULL; } 
    178179    virtual Module *isModule() { return NULL; } 
    179180    virtual EnumMember *isEnumMember() { return NULL; } 
    180181    virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; } 
    181182    virtual TemplateInstance *isTemplateInstance() { return NULL; } 
    182183    virtual TemplateMixin *isTemplateMixin() { return NULL; } 
    183184    virtual Declaration *isDeclaration() { return NULL; } 
     185    virtual ThisDeclaration *isThisDeclaration() { return NULL; } 
    184186    virtual TupleDeclaration *isTupleDeclaration() { return NULL; } 
    185187    virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } 
    186188    virtual AliasDeclaration *isAliasDeclaration() { return NULL; } 
    187189    virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; } 
    188190    virtual FuncDeclaration *isFuncDeclaration() { return NULL; } 
    189191    virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; } 
    190192    virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } 
    191193    virtual CtorDeclaration *isCtorDeclaration() { return NULL; } 
    192194    virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } 
    193195    virtual DtorDeclaration *isDtorDeclaration() { return NULL; } 
    194196    virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } 
    195197    virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; } 
    196198    virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; } 
    197199    virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; } 
    198200    virtual NewDeclaration *isNewDeclaration() { return NULL; } 
    199201    virtual VarDeclaration *isVarDeclaration() { return NULL; } 
    200202    virtual ClassDeclaration *isClassDeclaration() { return NULL; } 
    201203    virtual StructDeclaration *isStructDeclaration() { return NULL; } 
    202204    virtual UnionDeclaration *isUnionDeclaration() { return NULL; } 
    203205    virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; } 
  • trunk/src/e2ir.c

    r182 r183  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include    <stdio.h> 
    1212#include    <string.h> 
    1313#include    <time.h> 
    1414#include    <complex.h> 
    1515 
    1616#include    "lexer.h" 
    1717#include    "expression.h" 
    1818#include    "mtype.h" 
    1919#include    "dsymbol.h" 
    2020#include    "declaration.h" 
    2121#include    "enum.h" 
    2222#include    "aggregate.h" 
    2323#include    "attrib.h" 
    2424#include    "module.h" 
    2525#include    "init.h" 
    2626#include    "template.h" 
    2727 
    28 #if _WIN32 
    29 #include    "..\tk\mem.h"   // for mem_malloc 
    30 #elif linux || __APPLE__ 
    31 #include    "../tk/mem.h"   // for mem_malloc 
    32 #endif 
     28#include    "mem.h" // for tk/mem_malloc 
    3329 
    3430#include    "cc.h" 
    3531#include    "el.h" 
    3632#include    "oper.h" 
    3733#include    "global.h" 
    3834#include    "code.h" 
    3935#include    "type.h" 
    4036#include    "dt.h" 
    4137#include    "irstate.h" 
    4238#include    "id.h" 
    4339#include    "type.h" 
    4440#include    "toir.h" 
    4541 
    4642static char __file__[] = __FILE__;  /* for tassert.h        */ 
    4743#include    "tassert.h" 
    4844 
    4945 
    5046elem *addressElem(elem *e, Type *t); 
    5147elem *array_toPtr(Type *t, elem *e); 
    5248elem *bit_assign(enum OPER op, elem *eb, elem *ei, elem *ev, int result); 
     
    15151512        if (cdp != cdthis) 
    15161513        {   int i = cdp->isClassDeclaration()->isBaseOf(cdthis, &offset); 
    15171514        assert(i); 
    15181515        } 
    15191516        ethis = thisexp->toElem(irs); 
    15201517        if (offset) 
    15211518        ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, offset)); 
    15221519 
    15231520        ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, cd->vthis->offset)); 
    15241521        ey = el_una(OPind, TYnptr, ey); 
    15251522        ey = el_bin(OPeq, TYnptr, ey, ethis); 
    15261523 
    15271524//printf("ex: "); elem_print(ex); 
    15281525//printf("ey: "); elem_print(ey); 
    15291526//printf("ez: "); elem_print(ez); 
    15301527    } 
    15311528    else if (cd->isNested()) 
    15321529    {   /* Initialize cd->vthis: 
    15331530         *  *(ey + cd.vthis.offset) = this; 
    15341531         */ 
    1535         elem *ethis; 
    1536         FuncDeclaration *thisfd = irs->getFunc(); 
    1537         int offset = 0; 
    1538         Dsymbol *cdp = cd->toParent2(); // class/func we're nested in 
    1539  
    1540         if (cdp == thisfd) 
    1541         {   /* Class we're new'ing is a local class in this function: 
    1542          *  void thisfd() { class cd { } } 
    1543          */ 
    1544         if (irs->sclosure) 
    1545             ethis = el_var(irs->sclosure); 
    1546         else if (irs->sthis) 
    1547         { 
    1548 #if V2 
    1549             if (thisfd->closureVars.dim) 
    1550 #else 
    1551             if (thisfd->nestedFrameRef) 
    1552 #endif 
    1553             { 
    1554             ethis = el_ptr(irs->sthis); 
    1555             } 
    1556             else 
    1557             ethis = el_var(irs->sthis); 
    1558         } 
    1559         else 
    1560         { 
    1561             ethis = el_long(TYnptr, 0); 
    1562 #if V2 
    1563             if (thisfd->closureVars.dim) 
    1564 #else 
    1565             if (thisfd->nestedFrameRef) 
    1566 #endif 
    1567             { 
    1568             ethis->Eoper = OPframeptr; 
    1569             } 
    1570         } 
    1571         } 
    1572         else if (thisfd->vthis && 
    1573           (cdp == thisfd->toParent2() || 
    1574            (cdp->isClassDeclaration() && 
    1575             cdp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset) 
    1576            ) 
    1577           ) 
    1578         ) 
    1579         {   /* Class we're new'ing is at the same level as thisfd 
    1580          */ 
    1581         assert(offset == 0);    // BUG: should handle this case 
    1582         ethis = el_var(irs->sthis); 
    1583         } 
    1584         else 
    1585         { 
    1586         ethis = getEthis(loc, irs, cd->toParent2()); 
    1587         ethis = el_una(OPaddr, TYnptr, ethis); 
    1588         } 
    1589  
    1590         ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, cd->vthis->offset)); 
    1591         ey = el_una(OPind, TYnptr, ey); 
    1592         ey = el_bin(OPeq, TYnptr, ey, ethis); 
    1593  
     1532        ey = setEthis(loc, irs, ey, cd); 
    15941533    } 
    15951534 
    15961535    if (member) 
    15971536        // Call constructor 
    15981537        ez = callfunc(loc, irs, 1, type, ez, ectype, member, member->type, NULL, arguments); 
    15991538 
    16001539    e = el_combine(ex, ey); 
    16011540    e = el_combine(e, ez); 
    16021541    } 
    16031542    else if (t->ty == Tpointer && t->nextOf()->toBasetype()->ty == Tstruct) 
    16041543    { 
    16051544    Symbol *csym; 
    16061545 
    16071546    t = newtype->toBasetype(); 
    16081547    assert(t->ty == Tstruct); 
    16091548    TypeStruct *tclass = (TypeStruct *)(t); 
    16101549    StructDeclaration *cd = tclass->sym; 
    16111550 
    16121551    /* Things to do: 
    16131552     * 1) ex: call allocator 
    16141553     * 2) ey: set vthis for nested classes 
    16151554     * 3) ez: call constructor 
    16161555     */ 
    16171556 
    16181557    elem *ex = NULL; 
    16191558    elem *ey = NULL; 
    16201559    elem *ez = NULL; 
    16211560 
    16221561    if (allocator) 
    16231562    {   elem *ei; 
    16241563        Symbol *si; 
    16251564 
    16261565        ex = el_var(allocator->toSymbol()); 
    16271566        ex = callfunc(loc, irs, 1, type, ex, allocator->type, 
    16281567            allocator, allocator->type, NULL, newargs); 
    16291568 
    16301569        si = tclass->sym->toInitializer(); 
    16311570        ei = el_var(si); 
    16321571 
    1633         if (member) 
     1572        if (cd->isNested()) 
     1573        { 
     1574        ey = el_same(&ex); 
     1575        ez = el_copytree(ey); 
     1576        } 
     1577        else if (member) 
    16341578        ez = el_same(&ex); 
    1635         else 
     1579 
     1580        if (!member) 
    16361581        {   /* Statically intialize with default initializer 
    16371582         */ 
    16381583        ex = el_una(OPind, TYstruct, ex); 
    16391584        ex = el_bin(OPstreq, TYnptr, ex, ei); 
    16401585        ex->Enumbytes = cd->size(loc); 
    16411586        ex = el_una(OPaddr, TYnptr, ex); 
    16421587        } 
    16431588        ectype = tclass; 
    16441589    } 
    16451590    else 
    16461591    { 
    16471592        d_uns64 elemsize = cd->size(loc); 
    16481593 
    16491594        // call _d_newarrayT(ti, 1) 
    16501595        e = el_long(TYsize_t, 1); 
    16511596        e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 
    16521597 
    16531598        int rtl = t->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT; 
    16541599        e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); 
    16551600 
    16561601        // The new functions return an array, so convert to a pointer 
    16571602        // ex -> (unsigned)(e >> 32) 
    16581603        e = el_bin(OPshr, TYdarray, e, el_long(TYint, 32)); 
    16591604        ex = el_una(OP64_32, TYnptr, e); 
    16601605 
    16611606        ectype = NULL; 
    16621607 
    1663         if (member) 
     1608        if (cd->isNested()) 
     1609        { 
     1610        ey = el_same(&ex); 
     1611        ez = el_copytree(ey); 
     1612        } 
     1613        else if (member) 
    16641614        ez = el_same(&ex); 
    16651615//elem_print(ex); 
    16661616//elem_print(ey); 
    16671617//elem_print(ez); 
     1618    } 
     1619 
     1620    if (cd->isNested()) 
     1621    {   /* Initialize cd->vthis: 
     1622         *  *(ey + cd.vthis.offset) = this; 
     1623         */ 
     1624        ey = setEthis(loc, irs, ey, cd); 
    16681625    } 
    16691626 
    16701627    if (member) 
    16711628    {   // Call constructor 
    16721629        ez = callfunc(loc, irs, 1, type, ez, ectype, member, member->type, NULL, arguments); 
    16731630#if STRUCTTHISREF 
    16741631        /* Structs return a ref, which gets automatically dereferenced. 
    16751632         * But we want a pointer to the instance. 
    16761633         */ 
    16771634        ez = el_una(OPaddr, TYnptr, ez); 
    16781635#endif 
    16791636    } 
    16801637 
    16811638    e = el_combine(ex, ey); 
    16821639    e = el_combine(e, ez); 
    16831640    } 
    16841641    else if (t->ty == Tarray) 
    16851642    { 
    16861643    TypeDArray *tda = (TypeDArray *)(t); 
    16871644 
     
    27362693    elem *eb; 
    27372694    elem *ei; 
    27382695    elem *ev; 
    27392696    TY ty; 
    27402697    Type *ta; 
    27412698 
    27422699    ae = (IndexExp *)(e1); 
    27432700    ta = ae->e1->type->toBasetype(); 
    27442701    ty = ta->ty; 
    27452702    } 
    27462703 
    27472704#if V2 
    27482705    /* Look for reference initializations 
    27492706     */ 
    27502707    if (op == TOKconstruct && e1->op == TOKvar) 
    27512708    { 
    27522709    VarExp *ve = (VarExp *)e1; 
    27532710    Declaration *s = ve->var; 
    27542711    if (s->storage_class & STCref) 
    27552712    { 
     2713#if 0 
    27562714        Expression *ae = e2->addressOf(NULL); 
    27572715        e = ae->toElem(irs); 
     2716#else 
     2717        e = e2->toElem(irs); 
     2718        e = addressElem(e, e2->type); 
     2719#endif 
    27582720        elem *es = el_var(s->toSymbol()); 
    27592721        es->Ety = TYnptr; 
    27602722        e = el_bin(OPeq, TYnptr, es, e); 
     2723// BUG: type is struct, and e2 is TOKint64 
    27612724        goto Lret; 
    27622725    } 
    27632726    } 
    27642727#endif 
    27652728 
    27662729#if 1 
    27672730    /* This will work if we can distinguish an assignment from 
    27682731     * an initialization of the lvalue. It'll work if the latter. 
    27692732     * If the former, because of aliasing of the return value with 
    27702733     * function arguments, it'll fail. 
    27712734     */ 
    27722735    if (op == TOKconstruct && e2->op == TOKcall) 
    27732736    {   CallExp *ce = (CallExp *)e2; 
    27742737 
    27752738    TypeFunction *tf = (TypeFunction *)ce->e1->type->toBasetype(); 
    27762739    if (tf->ty == Tfunction && tf->retStyle() == RETstack) 
    27772740    { 
    27782741        elem *ehidden = e1->toElem(irs); 
    27792742        ehidden = el_una(OPaddr, TYnptr, ehidden); 
    27802743        assert(!irs->ehidden); 
    27812744        irs->ehidden = ehidden; 
    27822745        e = e2->toElem(irs); 
    27832746        goto Lret; 
    27842747    } 
    27852748    } 
    27862749#endif 
     2750//printf("test1 %d\n", op); 
     2751//if (op == TOKconstruct) printf("construct\n"); 
    27872752    if (t1b->ty == Tstruct) 
    2788     { 
     2753    {   elem *eleft = e1->toElem(irs); 
     2754 
    27892755    if (e2->op == TOKint64) 
    27902756    {   /* Implement: 
    27912757         *  (struct = 0) 
    27922758         * with: 
    27932759         *  memset(&struct, 0, struct.sizeof) 
    27942760         */ 
    2795         elem *el = e1->toElem(irs); 
    2796         elem *enbytes = el_long(TYint, e1->type->size()); 
     2761        elem *ey = NULL; 
     2762        int sz = e1->type->size(); 
     2763        StructDeclaration *sd = ((TypeStruct *)t1b)->sym; 
     2764        if (sd->isnested && op == TOKconstruct) 
     2765        { 
     2766        ey = el_una(OPaddr, TYnptr, eleft); 
     2767        eleft = el_same(&ey); 
     2768        ey = setEthis(loc, irs, ey, sd); 
     2769        sz = sd->vthis->offset; 
     2770        } 
     2771 
     2772        elem *el = eleft; 
     2773        elem *enbytes = el_long(TYint, sz); 
    27972774        elem *evalue = el_long(TYint, 0); 
    27982775 
    2799         el = el_una(OPaddr, TYnptr, el); 
     2776        if (!(sd->isnested && op == TOKconstruct)) 
     2777        el = el_una(OPaddr, TYnptr, el); 
    28002778        e = el_param(enbytes, evalue); 
    28012779        e = el_bin(OPmemset,TYnptr,el,e); 
     2780        e = el_combine(ey, e); 
    28022781        el_setLoc(e, loc); 
    28032782        //e = el_una(OPind, TYstruct, e); 
    28042783    } 
    28052784    else 
    28062785    { 
    2807         elem *e1; 
    2808         elem *e2; 
    2809         tym_t tym; 
    2810  
    28112786        //printf("toElemBin() '%s'\n", toChars()); 
    28122787 
    2813         tym = type->totym(); 
    2814  
    2815         e1 = this->e1->toElem(irs)
     2788        tym_t tym = type->totym(); 
     2789 
     2790        elem *e1 = eleft
    28162791        elem *ex = e1; 
    28172792        if (e1->Eoper == OPind) 
    28182793        ex = e1->E1; 
    28192794        if (this->e2->op == TOKstructliteral && 
    28202795        ex->Eoper == OPvar && ex->EV.sp.Voffset == 0) 
    28212796        {   StructLiteralExp *se = (StructLiteralExp *)this->e2; 
    28222797 
    28232798        Symbol *symSave = se->sym; 
    28242799        size_t soffsetSave = se->soffset; 
    28252800        int fillHolesSave = se->fillHoles; 
    28262801 
    28272802        se->sym = ex->EV.sp.Vsym; 
    28282803        se->soffset = 0; 
    28292804        se->fillHoles = (op == TOKconstruct || op == TOKblit) ? 1 : 0; 
    28302805 
    28312806        el_free(e1); 
    28322807        e = this->e2->toElem(irs); 
    28332808 
    28342809        se->sym = symSave; 
    28352810        se->soffset = soffsetSave; 
    28362811        se->fillHoles = fillHolesSave; 
    28372812        } 
    28382813        else 
    28392814        { 
    2840         e2 = this->e2->toElem(irs); 
     2815        elem *e2 = this->e2->toElem(irs); 
    28412816        e = el_bin(OPstreq,tym,e1,e2); 
    28422817        e->Enumbytes = this->e1->type->size(); 
    28432818        } 
    28442819        goto Lret; 
    28452820    } 
    28462821    } 
    28472822    else 
    28482823    e = toElemBin(irs,OPeq); 
    28492824    return e; 
    28502825 
    28512826  Lret: 
    28522827    el_setLoc(e,loc); 
    28532828    return e; 
    28542829} 
    28552830 
    28562831/*************************************** 
    28572832 */ 
    28582833 
    28592834elem *AddAssignExp::toElem(IRState *irs) 
    28602835{ 
     
    39673942    case X(Tfloat64,Tfloat80): eop = OPd_ld;  goto Leop; 
    39683943    case X(Tfloat64,Timaginary32):  goto Lzero; 
    39693944    case X(Tfloat64,Timaginary64):  goto Lzero; 
    39703945    case X(Tfloat64,Timaginary80):  goto Lzero; 
    39713946    case X(Tfloat64,Tcomplex32): 
    39723947    case X(Tfloat64,Tcomplex64): 
    39733948    case X(Tfloat64,Tcomplex80): 
    39743949        e = el_bin(OPadd,TYcfloat,el_long(TYidouble,0),e); 
    39753950        fty = Tcomplex64; 
    39763951        goto Lagain; 
    39773952 
    39783953    /* ============================= */ 
    39793954 
    39803955    case X(Tfloat80,Tint8): 
    39813956    case X(Tfloat80,Tuns8): 
    39823957    case X(Tfloat80,Tint16): 
    39833958    case X(Tfloat80,Tuns16): 
    39843959    case X(Tfloat80,Tint32): 
    39853960    case X(Tfloat80,Tuns32): 
    39863961    case X(Tfloat80,Tint64): 
    3987     case X(Tfloat80,Tuns64): 
    39883962    case X(Tfloat80,Tfloat32): e = el_una(OPld_d, TYdouble, e); 
    39893963                   fty = Tfloat64; 
    39903964                   goto Lagain; 
     3965    case X(Tfloat80,Tuns64): 
     3966                   eop = OPld_u64; goto Leop; 
    39913967    case X(Tfloat80,Tfloat64): eop = OPld_d; goto Leop; 
    39923968    case X(Tfloat80,Timaginary32): goto Lzero; 
    39933969    case X(Tfloat80,Timaginary64): goto Lzero; 
    39943970    case X(Tfloat80,Timaginary80): goto Lzero; 
    39953971    case X(Tfloat80,Tcomplex32): 
    39963972    case X(Tfloat80,Tcomplex64): 
    39973973    case X(Tfloat80,Tcomplex80): 
    39983974        e = el_bin(OPadd,TYcldouble,e,el_long(TYildouble,0)); 
    39993975        fty = Tcomplex80; 
    40003976        goto Lagain; 
    40013977 
    40023978    /* ============================= */ 
    40033979 
    40043980    case X(Timaginary32,Tint8): 
    40053981    case X(Timaginary32,Tuns8): 
    40063982    case X(Timaginary32,Tint16): 
    40073983    case X(Timaginary32,Tuns16): 
    40083984    case X(Timaginary32,Tint32): 
    40093985    case X(Timaginary32,Tuns32): 
    40103986    case X(Timaginary32,Tint64): 
     
    46204596        e = el_combine(e, fillHole(stmp, &offset, v->offset, sd->structsize)); 
    46214597        size_t vend = v->offset + v->type->size(); 
    46224598        if (offset < vend) 
    46234599        offset = vend; 
    46244600    } 
    46254601    e = el_combine(e, fillHole(stmp, &offset, sd->structsize, sd->structsize)); 
    46264602    } 
    46274603 
    46284604    if (elements) 
    46294605    { 
    46304606    dim = elements->dim; 
    46314607    assert(dim <= sd->fields.dim); 
    46324608    for (size_t i = 0; i < dim; i++) 
    46334609    {   Expression *el = (Expression *)elements->data[i]; 
    46344610        if (!el) 
    46354611        continue; 
    46364612 
    46374613        Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
    46384614        VarDeclaration *v = s->isVarDeclaration(); 
    46394615        assert(v); 
     4616        assert(!v->isThisDeclaration()); 
    46404617 
    46414618        elem *e1; 
    46424619        if (tybasic(stmp->Stype->Tty) == TYnptr) 
    46434620        {   e1 = el_var(stmp); 
    46444621        e1->EV.sp.Voffset = soffset; 
    46454622        } 
    46464623        else 
    46474624        {   e1 = el_ptr(stmp); 
    46484625        if (soffset) 
    46494626            e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); 
    46504627        } 
    46514628        e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v->offset)); 
    46524629        elem *ec = e1;          // pointer to destination 
    46534630 
    46544631        elem *ep = el->toElem(irs); 
    46554632 
    46564633        Type *t1b = v->type->toBasetype(); 
    46574634        Type *t2b = el->type->toBasetype(); 
    46584635        if (t1b->ty == Tsarray) 
    46594636        { 
     
    47134690        } 
    47144691#if V2 
    47154692        /* Call postBlit() on e1 
    47164693         */ 
    47174694        Type *tb = v->type->toBasetype(); 
    47184695        if (tb->ty == Tstruct) 
    47194696        {   StructDeclaration *sd = ((TypeStruct *)tb)->sym; 
    47204697            if (sd->postblit) 
    47214698            {   FuncDeclaration *fd = sd->postblit; 
    47224699            ec = el_copytree(ec); 
    47234700            ec = callfunc(loc, irs, 1, Type::tvoid, ec, tb->pointerTo(), fd, fd->type, NULL, NULL); 
    47244701            e1 = el_bin(OPcomma, ec->Ety, e1, ec); 
    47254702            } 
    47264703        } 
    47274704#endif 
    47284705        } 
    47294706        e = el_combine(e, e1); 
    47304707    } 
    47314708    } 
    47324709 
     4710    if (sd->isnested) 
     4711    {   // Initialize the hidden 'this' pointer 
     4712    assert(sd->fields.dim); 
     4713    Dsymbol *s = (Dsymbol *)sd->fields.data[sd->fields.dim - 1]; 
     4714    ThisDeclaration *v = s->isThisDeclaration(); 
     4715    assert(v); 
     4716 
     4717    elem *e1; 
     4718    if (tybasic(stmp->Stype->Tty) == TYnptr) 
     4719    {   e1 = el_var(stmp); 
     4720        e1->EV.sp.Voffset = soffset; 
     4721    } 
     4722    else 
     4723    {   e1 = el_ptr(stmp); 
     4724        if (soffset) 
     4725        e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); 
     4726    } 
     4727    e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v->offset)); 
     4728    e1 = setEthis(loc, irs, e1, sd); 
     4729 
     4730    e = el_combine(e, e1); 
     4731    } 
     4732 
    47334733    elem *ev = el_var(stmp); 
    47344734    ev->Enumbytes = sd->structsize; 
    47354735    e = el_combine(e, ev); 
    47364736    el_setLoc(e,loc); 
    47374737    return e; 
    47384738} 
  • trunk/src/expression.c

    r182 r183  
    1515#include <assert.h> 
    1616#if _MSC_VER 
    1717#include <complex> 
    1818#else 
    1919#include <complex.h> 
    2020#endif 
    2121 
    2222#if _WIN32 && __DMC__ 
    2323extern "C" char * __cdecl __locale_decpoint; 
    2424#endif 
    2525 
    2626#if IN_GCC 
    2727// Issues with using -include total.h (defines integer_t) and then complex.h fails... 
    2828#undef integer_t 
    2929#endif 
    3030 
    3131#ifdef __APPLE__ 
    3232#define integer_t dmd_integer_t 
    3333#endif 
    3434 
    35 #if IN_GCC 
    36 #include "mem.h" 
    37 #elif _WIN32 
    38 #include "..\root\mem.h" 
    39 #elif linux || __APPLE__ 
    40 #include "../root/mem.h" 
    41 #endif 
     35#include "rmem.h" 
    4236 
    4337//#include "port.h" 
    4438#include "mtype.h" 
    4539#include "init.h" 
    4640#include "expression.h" 
    4741#include "template.h" 
    4842#include "utf.h" 
    4943#include "enum.h" 
    5044#include "scope.h" 
    5145#include "statement.h" 
    5246#include "declaration.h" 
    5347#include "aggregate.h" 
    5448#include "import.h" 
    5549#include "id.h" 
    5650#include "dsymbol.h" 
    5751#include "module.h" 
    5852#include "attrib.h" 
    5953#include "hdrgen.h" 
    6054#include "parse.h" 
    6155 
     
    933927} 
    934928 
    935929char *Expression::toChars() 
    936930{   OutBuffer *buf; 
    937931    HdrGenState hgs; 
    938932 
    939933    memset(&hgs, 0, sizeof(hgs)); 
    940934    buf = new OutBuffer(); 
    941935    toCBuffer(buf, &hgs); 
    942936    return buf->toChars(); 
    943937} 
    944938 
    945939void Expression::error(const char *format, ...) 
    946940{ 
    947941    va_list ap; 
    948942    va_start(ap, format); 
    949943    ::verror(loc, format, ap); 
    950944    va_end( ap ); 
    951945} 
    952946 
     947void Expression::warning(const char *format, ...) 
     948{ 
     949    if (global.params.warnings && !global.gag) 
     950    { 
     951    fprintf(stdmsg, "warning - "); 
     952    va_list ap; 
     953    va_start(ap, format); 
     954    ::verror(loc, format, ap); 
     955    va_end( ap ); 
     956    } 
     957} 
     958 
    953959void Expression::rvalue() 
    954960{ 
    955961    if (type && type->toBasetype()->ty == Tvoid) 
    956962    {   error("expression %s is void and has no value", toChars()); 
    957963#if 0 
    958964    dump(0); 
    959965    halt(); 
    960966#endif 
    961967    type = Type::tint32; 
    962968    } 
    963969} 
    964970 
    965971Expression *Expression::combine(Expression *e1, Expression *e2) 
    966972{ 
    967973    if (e1) 
    968974    { 
    969975    if (e2) 
    970976    { 
    971977        e1 = new CommaExp(e1->loc, e1, e2); 
    972978        e1->type = e2->type; 
     
    30553061 
    30563062// sd( e1, e2, e3, ... ) 
    30573063 
    30583064StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements) 
    30593065    : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp)) 
    30603066{ 
    30613067    this->sd = sd; 
    30623068    this->elements = elements; 
    30633069    this->sym = NULL; 
    30643070    this->soffset = 0; 
    30653071    this->fillHoles = 1; 
    30663072} 
    30673073 
    30683074Expression *StructLiteralExp::syntaxCopy() 
    30693075{ 
    30703076    return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); 
    30713077} 
    30723078 
    30733079Expression *StructLiteralExp::semantic(Scope *sc) 
    30743080{   Expression *e; 
     3081    int nfields = sd->fields.dim - sd->isnested; 
    30753082 
    30763083#if LOGSEMANTIC 
    30773084    printf("StructLiteralExp::semantic('%s')\n", toChars()); 
    30783085#endif 
    30793086    if (type) 
    30803087    return this; 
    30813088 
    30823089    // Run semantic() on each element 
    30833090    for (size_t i = 0; i < elements->dim; i++) 
    30843091    {   e = (Expression *)elements->data[i]; 
    30853092    if (!e) 
    30863093        continue; 
    30873094    e = e->semantic(sc); 
    30883095    elements->data[i] = (void *)e; 
    30893096    } 
    30903097    expandTuples(elements); 
    30913098    size_t offset = 0; 
    30923099    for (size_t i = 0; i < elements->dim; i++) 
    30933100    {   e = (Expression *)elements->data[i]; 
    30943101    if (!e) 
    30953102        continue; 
    30963103 
    30973104    if (!e->type) 
    30983105        error("%s has no value", e->toChars()); 
    30993106    e = resolveProperties(sc, e); 
    3100     if (i >= sd->fields.dim
     3107    if (i >= nfields
    31013108    {   error("more initializers than fields of %s", sd->toChars()); 
    31023109        break; 
    31033110    } 
    31043111    Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
    31053112    VarDeclaration *v = s->isVarDeclaration(); 
    31063113    assert(v); 
    31073114    if (v->offset < offset) 
    31083115        error("overlapping initialization for %s", v->toChars()); 
    31093116    offset = v->offset + v->type->size(); 
    31103117 
    31113118    Type *telem = v->type; 
    31123119    while (!e->implicitConvTo(telem) && telem->toBasetype()->ty == Tsarray) 
    31133120    {   /* Static array initialization, as in: 
    31143121         *  T[3][5] = e; 
    31153122         */ 
    31163123        telem = telem->toBasetype()->nextOf(); 
    31173124    } 
    31183125 
    31193126    e = e->implicitCastTo(sc, telem); 
    31203127 
    31213128    elements->data[i] = (void *)e; 
    31223129    } 
    31233130 
    31243131    /* Fill out remainder of elements[] with default initializers for fields[] 
    31253132     */ 
    3126     for (size_t i = elements->dim; i < sd->fields.dim; i++) 
     3133    for (size_t i = elements->dim; i < nfields; i++) 
    31273134    {   Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
    31283135    VarDeclaration *v = s->isVarDeclaration(); 
    31293136    assert(v); 
     3137    assert(!v->isThisDeclaration()); 
    31303138 
    31313139    if (v->offset < offset) 
    31323140    {   e = NULL; 
    31333141        sd->hasUnions = 1; 
    31343142    } 
    31353143    else 
    31363144    { 
    31373145        if (v->init) 
    31383146        {   e = v->init->toExpression(); 
    31393147        if (!e) 
    31403148            error("cannot make expression out of initializer for %s", v->toChars()); 
    31413149        } 
    31423150        else 
    31433151        {   e = v->type->defaultInit(); 
    31443152        e->loc = loc; 
    31453153        } 
    31463154        offset = v->offset + v->type->size(); 
    31473155    } 
    31483156    elements->push(e); 
    31493157    } 
     
    46814689        assert(0); 
    46824690    } 
    46834691    goto Lyes; 
    46844692    } 
    46854693    else if (id && tspec) 
    46864694    { 
    46874695    /* Evaluate to TRUE if targ matches tspec. 
    46884696     * If TRUE, declare id as an alias for the specialized type. 
    46894697     */ 
    46904698 
    46914699    MATCH m; 
    46924700    assert(parameters && parameters->dim); 
    46934701 
    46944702    Objects dedtypes; 
    46954703    dedtypes.setDim(parameters->dim); 
    46964704    dedtypes.zero(); 
    46974705 
    46984706    m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 
    46994707    if (m == MATCHnomatch || 
    47004708        (m != MATCHexact && tok == TOKequal)) 
     4709    { 
    47014710        goto Lno; 
     4711    } 
    47024712    else 
    47034713    { 
    47044714        tded = (Type *)dedtypes.data[0]; 
    47054715        if (!tded) 
    47064716        tded = targ; 
    47074717 
    47084718        Objects tiargs; 
    47094719        tiargs.setDim(1); 
    47104720        tiargs.data[0] = (void *)targ; 
    47114721 
    47124722        for (int i = 1; i < parameters->dim; i++) 
    47134723        {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    47144724        Declaration *s; 
    47154725 
    47164726        m = tp->matchArg(sc, &tiargs, i, parameters, &dedtypes, &s); 
    47174727        if (m == MATCHnomatch) 
    47184728            goto Lno; 
    47194729        s->semantic(sc); 
    47204730        if (!sc->insert(s)) 
    47214731            error("declaration %s is already defined", s->toChars()); 
     
    47234733        Object *o = (Object *)dedtypes.data[i]; 
    47244734        Dsymbol *s = TemplateDeclaration::declareParameter(loc, sc, tp, o); 
    47254735#endif 
    47264736        if (sc->sd) 
    47274737            s->addMember(sc, sc->sd, 1); 
    47284738        } 
    47294739 
    47304740        goto Lyes; 
    47314741    } 
    47324742    } 
    47334743    else if (id) 
    47344744    { 
    47354745    /* Declare id as an alias for type targ. Evaluate to TRUE 
    47364746     */ 
    47374747    tded = targ; 
    47384748    goto Lyes; 
    47394749    } 
    47404750    else if (tspec) 
    47414751    { 
    47424752    /* Evaluate to TRUE if targ matches tspec 
     4753     * is(targ == tspec) 
     4754     * is(targ : tspec) 
    47434755     */ 
    47444756    tspec = tspec->semantic(loc, sc); 
    47454757    //printf("targ  = %s\n", targ->toChars()); 
    47464758    //printf("tspec = %s\n", tspec->toChars()); 
    47474759    if (tok == TOKcolon) 
    47484760    {   if (targ->implicitConvTo(tspec)) 
    47494761        goto Lyes; 
    47504762        else 
    47514763        goto Lno; 
    47524764    } 
    47534765    else /* == */ 
    47544766    {   if (targ->equals(tspec)) 
    47554767        goto Lyes; 
    47564768        else 
    47574769        goto Lno; 
    47584770    } 
    47594771    } 
    47604772 
    47614773Lyes: 
    47624774    if (id) 
     
    59525964    arguments->data[0] = (void *)earg1; 
    59535965    arguments->data[1] = (void *)earg2; 
    59545966 
    59555967    this->arguments = arguments; 
    59565968} 
    59575969 
    59585970Expression *CallExp::syntaxCopy() 
    59595971{ 
    59605972    return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments)); 
    59615973} 
    59625974 
    59635975 
    59645976Expression *CallExp::semantic(Scope *sc) 
    59655977{ 
    59665978    TypeFunction *tf; 
    59675979    FuncDeclaration *f; 
    59685980    int i; 
    59695981    Type *t1; 
    59705982    int istemp; 
    59715983    Objects *targsi = NULL; // initial list of template arguments 
     5984    TemplateInstance *tierror = NULL; 
    59725985 
    59735986#if LOGSEMANTIC 
    59745987    printf("CallExp::semantic() %s\n", toChars()); 
    59755988#endif 
    59765989    if (type) 
    59775990    return this;        // semantic() already run 
    59785991#if 0 
    59795992    if (arguments && arguments->dim) 
    59805993    { 
    59815994    Expression *earg = (Expression *)arguments->data[0]; 
    59825995    earg->print(); 
    59835996    if (earg->type) earg->type->print(); 
    59845997    } 
    59855998#endif 
    59865999 
    59876000    if (e1->op == TOKdelegate) 
    59886001    {   DelegateExp *de = (DelegateExp *)e1; 
    59896002 
    59906003    e1 = new DotVarExp(de->loc, de->e1, de->func); 
    59916004    return semantic(sc); 
     
    60416054     */ 
    60426055    if (e1->op == TOKimport && !e1->type) 
    60436056    {   ScopeExp *se = (ScopeExp *)e1; 
    60446057    TemplateInstance *ti = se->sds->isTemplateInstance(); 
    60456058    if (ti && !ti->semanticdone) 
    60466059    { 
    60476060        /* Attempt to instantiate ti. If that works, go with it. 
    60486061         * If not, go with partial explicit specialization. 
    60496062         */ 
    60506063        ti->semanticTiargs(sc); 
    60516064        unsigned errors = global.errors; 
    60526065        global.gag++; 
    60536066        ti->semantic(sc); 
    60546067        global.gag--; 
    60556068        if (errors != global.errors) 
    60566069        { 
    60576070        /* Didn't work, go with partial explicit specialization 
    60586071         */ 
    60596072        global.errors = errors; 
    60606073        targsi = ti->tiargs; 
     6074        tierror = ti;           // for error reporting 
    60616075        e1 = new IdentifierExp(loc, ti->name); 
    60626076        } 
    60636077    } 
    60646078    } 
    60656079 
    60666080    /* This recognizes: 
    60676081     *  expr.foo!(tiargs)(funcargs) 
    60686082     */ 
    60696083    if (e1->op == TOKdotti && !e1->type) 
    60706084    {   DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; 
    60716085    TemplateInstance *ti = se->ti; 
    60726086    if (!ti->semanticdone) 
    60736087    { 
    60746088        /* Attempt to instantiate ti. If that works, go with it. 
    60756089         * If not, go with partial explicit specialization. 
    60766090         */ 
    60776091        ti->semanticTiargs(sc); 
    60786092        Expression *etmp; 
    60796093        unsigned errors = global.errors; 
    60806094        global.gag++; 
    60816095        etmp = e1->semantic(sc); 
    60826096        global.gag--; 
    60836097        if (errors != global.errors) 
    60846098        { 
    60856099        global.errors = errors; 
    60866100        targsi = ti->tiargs; 
     6101        tierror = ti;       // for error reporting 
    60876102        e1 = new DotIdExp(loc, se->e1, ti->name); 
    60886103        } 
    60896104        else 
    60906105        e1 = etmp; 
    60916106    } 
    60926107    } 
    60936108#endif 
    60946109 
    60956110    istemp = 0; 
    60966111Lagain: 
    60976112    //printf("Lagain: %s\n", toChars()); 
    60986113    f = NULL; 
    60996114    if (e1->op == TOKthis || e1->op == TOKsuper) 
    61006115    { 
    61016116    // semantic() run later for these 
    61026117    } 
    61036118    else 
    61046119    { 
    61056120    UnaExp::semantic(sc); 
    61066121 
     
    64666481    { 
    64676482    if (t1->ty == Tdelegate) 
    64686483    {   TypeDelegate *td = (TypeDelegate *)t1; 
    64696484        assert(td->next->ty == Tfunction); 
    64706485        tf = (TypeFunction *)(td->next); 
    64716486        goto Lcheckargs; 
    64726487    } 
    64736488    else if (t1->ty == Tpointer && ((TypePointer *)t1)->next->ty == Tfunction) 
    64746489    {   Expression *e; 
    64756490 
    64766491        e = new PtrExp(loc, e1); 
    64776492        t1 = ((TypePointer *)t1)->next; 
    64786493        e->type = t1; 
    64796494        e1 = e; 
    64806495    } 
    64816496    else if (e1->op == TOKtemplate) 
    64826497    { 
    64836498        TemplateExp *te = (TemplateExp *)e1; 
    64846499        f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); 
    64856500        if (!f) 
    6486         {   type = Type::terror; 
     6501        {   if (tierror) 
     6502            tierror->error("errors instantiating template");    // give better error message 
     6503        type = Type::terror; 
    64876504        return this; 
    64886505        } 
    64896506        if (f->needThis() && hasThis(sc)) 
    64906507        { 
    64916508        // Supply an implicit 'this', as in 
    64926509        //    this.ident 
    64936510 
    64946511        e1 = new DotTemplateExp(loc, (new ThisExp(loc))->semantic(sc), te->td); 
    64956512        goto Lagain; 
    64966513        } 
    64976514 
    64986515        e1 = new VarExp(loc, f); 
    64996516        goto Lagain; 
    65006517    } 
    65016518    else 
    65026519    {   error("function expected before (), not %s of type %s", e1->toChars(), e1->type->toChars()); 
    65036520        type = Type::terror; 
    65046521        return this; 
    65056522    } 
    65066523    } 
     
    66096626        return 1; 
    66106627    } 
    66116628 
    66126629    /* If calling a function or delegate that is typed as nothrow, 
    66136630     * then this expression cannot throw. 
    66146631     * Note that pure functions can throw. 
    66156632     */ 
    66166633    Type *t = e1->type->toBasetype(); 
    66176634    if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow) 
    66186635    return 0; 
    66196636    if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow) 
    66206637    return 0; 
    66216638 
    66226639    return 1; 
    66236640} 
    66246641#endif 
    66256642 
    66266643#if V2 
    66276644int CallExp::isLvalue() 
    66286645{ 
    6629     if (type->toBasetype()->ty == Tstruct) 
    6630   return 1; 
     6646//    if (type->toBasetype()->ty == Tstruct) 
     6647//    return 1; 
    66316648    Type *tb = e1->type->toBasetype(); 
    66326649    if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) 
    66336650    return 1;       // function returns a reference 
    66346651    return 0; 
    66356652} 
    66366653#endif 
    66376654 
    66386655Expression *CallExp::toLvalue(Scope *sc, Expression *e) 
    66396656{ 
    66406657    if (isLvalue()) 
    66416658    return this; 
    66426659    return Expression::toLvalue(sc, e); 
    66436660} 
    66446661 
    66456662void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    66466663{   int i; 
    66476664 
    66486665    expToCBuffer(buf, hgs, e1, precedence[op]); 
    66496666    buf->writeByte('('); 
    66506667    argsToCBuffer(buf, arguments, hgs); 
     
    74197436        } 
    74207437        else 
    74217438        {   Arguments *args = new Arguments; 
    74227439        args->reserve(j2 - j1); 
    74237440        for (size_t i = j1; i < j2; i++) 
    74247441        {   Argument *arg = Argument::getNth(tup->arguments, i); 
    74257442            args->push(arg); 
    74267443        } 
    74277444        e = new TypeExp(e1->loc, new TypeTuple(args)); 
    74287445        } 
    74297446        e = e->semantic(sc); 
    74307447    } 
    74317448    else 
    74327449    { 
    74337450        error("string slice [%ju .. %ju] is out of bounds", i1, i2); 
    74347451        e = e1; 
    74357452    } 
    74367453    return e; 
    74377454    } 
    74387455 
    7439     type = t->nextOf()->arrayOf(); 
     7456    if (t->ty == Tarray) 
     7457    { 
     7458    type = e1->type; 
     7459    } 
     7460    else 
     7461    type = t->nextOf()->arrayOf(); 
    74407462    return e; 
    74417463 
    74427464Lerror: 
    74437465    char *s; 
    74447466    if (t->ty == Tvoid) 
    74457467    s = e1->toChars(); 
    74467468    else 
    74477469    s = t->toChars(); 
    74487470    error("%s cannot be sliced with []", s); 
    74497471    e = new IntegerExp(0); 
    74507472    return e; 
    74517473} 
    74527474 
    74537475void SliceExp::checkEscape() 
    74547476{ 
    74557477    e1->checkEscape(); 
    74567478} 
    74577479 
    74587480#if V2 
    74597481int SliceExp::isLvalue() 
     
    77567778        TypeSArray *tsa = (TypeSArray *)t1; 
    77577779 
    77587780#if 0   // Don't do now, because it might be short-circuit evaluated 
    77597781        // Do compile time array bounds checking if possible 
    77607782        e2 = e2->optimize(WANTvalue); 
    77617783        if (e2->op == TOKint64) 
    77627784        { 
    77637785        integer_t index = e2->toInteger(); 
    77647786        integer_t length = tsa->dim->toInteger(); 
    77657787        if (index < 0 || index >= length) 
    77667788            error("array index [%lld] is outside array bounds [0 .. %lld]", 
    77677789                index, length); 
    77687790        } 
    77697791#endif 
    77707792        e->type = t1->nextOf(); 
    77717793        break; 
    77727794    } 
    77737795 
    77747796    case Taarray: 
    77757797    {   TypeAArray *taa = (TypeAArray *)t1; 
    7776  
    7777         e2 = e2->implicitCastTo(sc, taa->index);    // type checking 
     7798        if (!arrayTypeCompatible(e2->loc, e2->type, taa->index)) 
     7799        { 
     7800        e2 = e2->implicitCastTo(sc, taa->index);    // type checking 
     7801        } 
    77787802        type = taa->next; 
    77797803        break; 
    77807804    } 
    77817805 
    77827806    case Ttuple: 
    77837807    { 
    77847808        e2 = e2->implicitCastTo(sc, Type::tsize_t); 
    77857809        e2 = e2->optimize(WANTvalue | WANTinterpret); 
    77867810        uinteger_t index = e2->toUInteger(); 
    77877811        size_t length; 
    77887812        TupleExp *te; 
    77897813        TypeTuple *tup; 
    77907814 
    77917815        if (e1->op == TOKtuple) 
    77927816        {   te = (TupleExp *)e1; 
    77937817        length = te->exps->dim; 
    77947818        } 
    77957819        else if (e1->op == TOKtype) 
    77967820        { 
    77977821        tup = (TypeTuple *)t1; 
     
    94489472 
    94499473    if (type) 
    94509474    return this; 
    94519475 
    94529476    BinExp::semanticp(sc); 
    94539477    e = op_overload(sc); 
    94549478    if (e) 
    94559479    return e; 
    94569480 
    94579481    //type = Type::tboolean; 
    94589482    Type *t2b = e2->type->toBasetype(); 
    94599483    if (t2b->ty != Taarray) 
    94609484    { 
    94619485    error("rvalue of in expression must be an associative array, not %s", e2->type->toChars()); 
    94629486    type = Type::terror; 
    94639487    } 
    94649488    else 
    94659489    { 
    94669490    TypeAArray *ta = (TypeAArray *)t2b; 
    94679491 
    9468     // Convert key to type of key 
    9469     e1 = e1->implicitCastTo(sc, ta->index); 
     9492    // Special handling for array keys 
     9493    if (!arrayTypeCompatible(e1->loc, e1->type, ta->index)) 
     9494    { 
     9495        // Convert key to type of key 
     9496        e1 = e1->implicitCastTo(sc, ta->index); 
     9497    } 
    94709498 
    94719499    // Return type is pointer to value 
    94729500    type = ta->nextOf()->pointerTo(); 
    94739501    } 
    94749502    return this; 
    94759503} 
    94769504 
    94779505int InExp::isBit() 
    94789506{ 
    94799507    return FALSE; 
    94809508} 
    94819509 
    94829510 
    94839511/************************************************************/ 
    94849512 
    94859513/* This deletes the key e1 from the associative array e2 
    94869514 */ 
    94879515 
    94889516RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2) 
    94899517    : BinExp(loc, TOKremove, sizeof(RemoveExp), e1, e2) 
     
    96179645    } 
    96189646 
    96199647    //if (e2->op != TOKnull) 
    96209648    { 
    96219649    e = op_overload(sc); 
    96229650    if (e) 
    96239651    { 
    96249652        if (op == TOKnotequal) 
    96259653        { 
    96269654        e = new NotExp(e->loc, e); 
    96279655        e = e->semantic(sc); 
    96289656        } 
    96299657        return e; 
    96309658    } 
    96319659    } 
    96329660 
    96339661    e = typeCombine(sc); 
    96349662    type = Type::tboolean; 
    96359663 
    96369664    // Special handling for array comparisons 
    9637     t1 = e1->type->toBasetype(); 
    9638     t2 = e2->type->toBasetype(); 
    9639  
    9640     if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 
    9641     (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 
    9642     { 
    9643     if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 
    9644         t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 
    9645         (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 
    9646         error("array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 
    9647     } 
    9648     else 
     9665    if (!arrayTypeCompatible(loc, e1->type, e2->type)) 
    96499666    { 
    96509667    if (e1->type != e2->type && e1->type->isfloating() && e2->type->isfloating()) 
    96519668    { 
    96529669        // Cast both to complex 
    96539670        e1 = e1->castTo(sc, Type::tcomplex80); 
    96549671        e2 = e2->castTo(sc, Type::tcomplex80); 
    96559672    } 
    96569673    } 
    96579674    return e; 
    96589675} 
    96599676 
    96609677int EqualExp::isBit() 
    96619678{ 
    96629679    return TRUE; 
    96639680} 
    96649681 
    96659682 
    96669683 
    96679684/************************************************************/ 
    96689685 
  • trunk/src/expression.h

    r181 r183  
    7272int arrayExpressionCanThrow(Expressions *exps); 
    7373 
    7474struct Expression : Object 
    7575{ 
    7676    Loc loc;            // file location 
    7777    enum TOK op;        // handy to minimize use of dynamic_cast 
    7878    Type *type;         // !=NULL means that semantic() has been run 
    7979    int size;           // # of bytes in Expression so we can copy() it 
    8080 
    8181    Expression(Loc loc, enum TOK op, int size); 
    8282    Expression *copy(); 
    8383    virtual Expression *syntaxCopy(); 
    8484    virtual Expression *semantic(Scope *sc); 
    8585 
    8686    int dyncast() { return DYNCAST_EXPRESSION; }    // kludge for template.isExpression() 
    8787 
    8888    void print(); 
    8989    char *toChars(); 
    9090    virtual void dump(int indent); 
    9191    void error(const char *format, ...); 
     92    void warning(const char *format, ...); 
    9293    virtual void rvalue(); 
    9394 
    9495    static Expression *combine(Expression *e1, Expression *e2); 
    9596    static Expressions *arraySyntaxCopy(Expressions *exps); 
    9697 
    9798    virtual integer_t toInteger(); 
    9899    virtual uinteger_t toUInteger(); 
    99100    virtual real_t toReal(); 
    100101    virtual real_t toImaginary(); 
    101102    virtual complex_t toComplex(); 
    102103    virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    103104    virtual void toMangleBuffer(OutBuffer *buf); 
    104105    virtual int isLvalue(); 
    105106    virtual Expression *toLvalue(Scope *sc, Expression *e); 
    106107    virtual Expression *modifiableLvalue(Scope *sc, Expression *e); 
    107108    virtual Expression *implicitCastTo(Scope *sc, Type *t); 
    108109    virtual MATCH implicitConvTo(Type *t); 
    109110    virtual Expression *castTo(Scope *sc, Type *t); 
    110111    virtual void checkEscape(); 
    111112    void checkScalar(); 
  • trunk/src/func.c

    r182 r183  
    356356            // Append to end of vtbl[] 
    357357            //printf("\tintroducing function\n"); 
    358358            introducing = 1; 
    359359            vi = cd->vtbl.dim; 
    360360            cd->vtbl.push(this); 
    361361            vtblIndex = vi; 
    362362        } 
    363363        break; 
    364364 
    365365        case -2:    // can't determine because of fwd refs 
    366366        cd->sizeok = 2; // can't finish due to forward reference 
    367367        return; 
    368368 
    369369        default: 
    370370        {   FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi]; 
    371371        // This function is covariant with fdv 
    372372        if (fdv->isFinal()) 
    373373            error("cannot override final function %s", fdv->toPrettyChars()); 
    374374 
    375375#if V2 
    376         if (!isOverride() && global.params.warnings
    377             error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); 
     376        if (!isOverride()
     377            warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); 
    378378#endif 
    379379 
    380380        if (fdv->toParent() == parent) 
    381381        { 
    382382            // If both are mixins, then error. 
    383383            // If either is not, the one that is not overrides 
    384384            // the other. 
    385385            if (fdv->parent->isClassDeclaration()) 
    386386            break; 
    387387            if (!this->parent->isClassDeclaration() 
    388388#if !BREAKABI 
    389389            && !isDtorDeclaration() 
    390390#endif 
    391391#if V2 
    392392            && !isPostBlitDeclaration() 
    393393#endif 
    394394            ) 
    395395            error("multiple overrides of same function"); 
    396396        } 
    397397        cd->vtbl.data[vi] = (void *)this; 
     
    10911091        { 
    10921092        int blockexit = fbody ? fbody->blockExit() : 0; 
    10931093        if (f->isnothrow && blockexit & BEthrow) 
    10941094            error("'%s' is nothrow yet may throw", toChars()); 
    10951095 
    10961096        int offend = blockexit & BEfallthru; 
    10971097 
    10981098        if (type->nextOf()->ty == Tvoid) 
    10991099        { 
    11001100            if (offend && isMain()) 
    11011101            {   // Add a return 0; statement 
    11021102            Statement *s = new ReturnStatement(0, new IntegerExp(0)); 
    11031103            fbody = new CompoundStatement(0, fbody, s); 
    11041104            } 
    11051105        } 
    11061106        else 
    11071107        { 
    11081108            if (offend) 
    11091109            {   Expression *e; 
    11101110 
    1111             if (global.params.warnings) 
    1112             {   fprintf(stdmsg, "warning - "); 
    1113                 error("no return at end of function"); 
    1114             } 
     1111            warning(loc, "no return at end of function"); 
    11151112 
    11161113            if (global.params.useAssert && 
    11171114                !global.params.useInline) 
    11181115            {   /* Add an assert(0, msg); where the missing return 
    11191116                 * should be. 
    11201117                 */ 
    11211118                e = new AssertExp( 
    11221119                  endloc, 
    11231120                  new IntegerExp(0), 
    11241121                  new StringExp(loc, (char *)"missing return expression") 
    11251122                ); 
    11261123            } 
    11271124            else 
    11281125                e = new HaltExp(endloc); 
    11291126            e = new CommaExp(0, e, type->nextOf()->defaultInit()); 
    11301127            e = e->semantic(sc2); 
    11311128            Statement *s = new ExpStatement(0, e); 
    11321129            fbody = new CompoundStatement(0, fbody, s); 
    11331130            } 
    11341131        } 
     
    19241921{   int level; 
    19251922    Dsymbol *s; 
    19261923    Dsymbol *fdparent; 
    19271924 
    19281925    //printf("FuncDeclaration::getLevel(fd = '%s')\n", fd->toChars()); 
    19291926    fdparent = fd->toParent2(); 
    19301927    if (fdparent == this) 
    19311928    return -1; 
    19321929    s = this; 
    19331930    level = 0; 
    19341931    while (fd != s && fdparent != s->toParent2()) 
    19351932    { 
    19361933    //printf("\ts = '%s'\n", s->toChars()); 
    19371934    FuncDeclaration *thisfd = s->isFuncDeclaration(); 
    19381935    if (thisfd) 
    19391936    {   if (!thisfd->isNested() && !thisfd->vthis) 
    19401937        goto Lerr; 
    19411938    } 
    19421939    else 
    19431940    { 
    1944         ClassDeclaration *thiscd = s->isClassDeclaration(); 
     1941        AggregateDeclaration *thiscd = s->isAggregateDeclaration(); 
    19451942        if (thiscd) 
    19461943        {   if (!thiscd->isNested()) 
    19471944            goto Lerr; 
    19481945        } 
    19491946        else 
    19501947        goto Lerr; 
    19511948    } 
    19521949 
    19531950    s = s->toParent2(); 
    19541951    assert(s); 
    19551952    level++; 
    19561953    } 
    19571954    return level; 
    19581955 
    19591956Lerr: 
    19601957    error(loc, "cannot access frame of function %s", fd->toChars()); 
    19611958    return 1; 
    19621959} 
    19631960 
    19641961void FuncDeclaration::appendExp(Expression *e) 
  • trunk/src/hdrgen.c

    r182 r183  
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111// Routines to emit header files 
    1212 
    1313#ifdef _DH 
    1414 
    1515#define PRETTY_PRINT 
    1616#define TEST_EMIT_ALL  0    // For Testing 
    1717 
    1818#define LOG 0 
    1919 
    2020#include <stdio.h> 
    2121#include <stdlib.h> 
    2222#include <assert.h> 
    2323#if __DMC__ 
    2424#include <complex.h> 
    2525#endif 
    2626 
    27 #ifdef IN_GCC 
    28 #include "mem.h" 
    29 #else 
    30 #if _WIN32 
    31 #include "..\root\mem.h" 
    32 #elif linux || __APPLE__ 
    33 #include "../root/mem.h" 
    34 #else 
    35 #error "fix this" 
    36 #endif 
    37 #endif 
     27#include "rmem.h" 
    3828 
    3929#include "id.h" 
    4030#include "init.h" 
    4131 
    4232#include "attrib.h" 
    4333#include "cond.h" 
    4434#include "enum.h" 
    4535#include "import.h" 
    4636#include "module.h" 
    4737#include "mtype.h" 
    4838#include "scope.h" 
    4939#include "staticassert.h" 
    5040#include "template.h" 
    5141#include "utf.h" 
    5242#include "version.h" 
    5343 
    5444#include "declaration.h" 
    5545#include "aggregate.h" 
    5646#include "expression.h" 
    5747#include "statement.h" 
  • trunk/src/inifile.c

    r182 r183  
    1  
    2 // Copyright (c) 1999-2009 by Digital Mars 
    3 // All Rights Reserved 
    4 // written by Walter Bright 
    5 // http://www.digitalmars.com 
    6  
     1/* 
     2 * Some portions copyright (c) 1994-1995 by Symantec 
     3 * Copyright (c) 1999-2009 by Digital Mars 
     4 * All Rights Reserved 
     5 * http://www.digitalmars.com 
     6 * Written by Walter Bright 
     7 * 
     8 * This source file is made available for personal use 
     9 * only. The license is in /dmd/src/dmd/backendlicense.txt 
     10 * For any other uses, please contact Digital Mars. 
     11 */ 
    712 
    813#include    <stdio.h> 
    914#include    <string.h> 
    1015#include    <stdlib.h> 
    1116#include    <ctype.h> 
    1217 
    1318#if __APPLE__ 
    1419#include    <sys/syslimits.h> 
    1520#endif 
    1621 
    1722#include    "root.h" 
    18 #include    "mem.h" 
     23#include    "rmem.h" 
    1924 
    2025#define LOG 0 
    2126 
    2227char *skipspace(const char *p); 
    2328 
    2429#if __GNUC__ 
    2530char *strupr(char *s) 
    2631{ 
    2732    char *t = s; 
    2833     
    2934    while (*s) 
    3035    { 
    3136    *s = toupper(*s); 
    3237    s++; 
    3338    } 
    3439 
    3540    return t; 
    3641} 
    3742#endif /* unix */ 
    3843 
  • trunk/src/interpret.c

    r180 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    15 #include "mem.h" 
     15#include "rmem.h" 
    1616 
    1717#include "statement.h" 
    1818#include "expression.h" 
    1919#include "cond.h" 
    2020#include "init.h" 
    2121#include "staticassert.h" 
    2222#include "mtype.h" 
    2323#include "scope.h" 
    2424#include "declaration.h" 
    2525#include "aggregate.h" 
    2626#include "id.h" 
    2727 
    2828#define LOG 0 
    2929 
    3030struct InterState 
    3131{ 
    3232    InterState *caller;     // calling function's InterState 
    3333    FuncDeclaration *fd;    // function being interpreted 
    3434    Dsymbols vars;      // variables used in this function 
    3535    Statement *start;       // if !=NULL, start execution at this statement 
  • trunk/src/lexer.c

    r182 r183  
    98// See the included readme.txt for details. 
    109 
    1110/* Lexical Analyzer */ 
    1211 
    1312#include <stdio.h> 
    1413#include <string.h> 
    1514#include <ctype.h> 
    1615#include <stdarg.h> 
    1716#include <errno.h> 
    1817#include <wchar.h> 
    1918#include <stdlib.h> 
    2019#include <assert.h> 
    2120#if _MSC_VER 
    2221#include <time.h> 
    2322#else 
    2423#include <sys/time.h> 
    2524#endif 
    2625#ifdef IN_GCC 
    2726 
    2827#include <time.h> 
    29 #include "mem.h" 
    30  
    3128#else 
    3229 
    3330#if __GNUC__ 
    3431#include <time.h> 
    3532#endif 
    36  
    37 #if _WIN32 
    38 #include "..\root\mem.h" 
    39 #else 
    40 #include "../root/mem.h" 
    41 #endif 
    42 #endif 
     32#endif 
     33 
     34#include "rmem.h" 
    4335 
    4436#include "stringtable.h" 
    4537 
    4638#include "lexer.h" 
    4739#include "utf.h" 
    4840#include "identifier.h" 
    4941#include "id.h" 
    5042#include "module.h" 
    5143 
    5244#if _WIN32 && __DMC__ 
    5345// from \dm\src\include\setlocal.h 
    5446extern "C" char * __cdecl __locale_decpoint; 
    5547#endif 
    5648 
    5749#if _MSC_VER // workaround VC++ bug, labels and types should be in separate namespaces 
    5850#define Lstring Lstr 
    5951#endif 
    6052 
    6153extern int HtmlNamedEntity(unsigned char *p, int length); 
    6254 
     
    599591            p++; 
    600592            t->value = delimitedStringConstant(t); 
    601593            return; 
    602594        } 
    603595        else if (p[1] == '{') 
    604596        { 
    605597            p++; 
    606598            t->value = tokenStringConstant(t); 
    607599            return; 
    608600        } 
    609601        else 
    610602            goto case_ident; 
    611603#endif 
    612604 
    613605        case '"': 
    614606        t->value = escapeStringConstant(t,0); 
    615607        return; 
    616608#if ! TEXTUAL_ASSEMBLY_OUT 
    617609        case '\\':          // escaped string literal 
    618610        {   unsigned c; 
     611        unsigned char *pstart = p; 
    619612 
    620613        stringbuffer.reset(); 
    621614        do 
    622615        { 
    623616            p++; 
    624617            switch (*p) 
    625618            { 
    626619            case 'u': 
    627620            case 'U': 
    628621            case '&': 
    629622                c = escapeSequence(); 
    630623                stringbuffer.writeUTF8(c); 
    631624                break; 
    632625 
    633626            default: 
    634627                c = escapeSequence(); 
    635628                stringbuffer.writeByte(c); 
    636629                break; 
    637630            } 
    638631        } while (*p == '\\'); 
    639632        t->len = stringbuffer.offset; 
    640633        stringbuffer.writeByte(0); 
    641634        t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); 
    642635        memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); 
    643636        t->postfix = 0; 
    644637        t->value = TOKstring; 
     638        if (!global.params.useDeprecated) 
     639            error("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart); 
    645640        return; 
    646641        } 
    647642#endif 
    648643        case 'l': 
    649644        case 'L': 
    650645#endif 
    651646        case 'a':   case 'b':   case 'c':   case 'd':   case 'e': 
    652647        case 'f':   case 'g':   case 'h':   case 'i':   case 'j': 
    653648        case 'k':               case 'm':   case 'n':   case 'o': 
    654649#if V2 
    655650        case 'p':   /*case 'q': case 'r':*/ case 's':   case 't': 
    656651#else 
    657652        case 'p':   case 'q': /*case 'r':*/ case 's':   case 't': 
    658653#endif 
    659654        case 'u':   case 'v':   case 'w': /*case 'x':*/ case 'y': 
    660655        case 'z': 
    661656        case 'A':   case 'B':   case 'C':   case 'D':   case 'E': 
    662657        case 'F':   case 'G':   case 'H':   case 'I':   case 'J': 
    663658        case 'K':               case 'M':   case 'N':   case 'O': 
    664659        case 'P':   case 'Q':   case 'R':   case 'S':   case 'T': 
  • trunk/src/libelf.c

    r181 r183  
    11  
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414#include <time.h> 
    1515#include <unistd.h> 
    1616#include <sys/types.h> 
    1717#include <sys/stat.h> 
    1818 
    19 #include "mem.h" 
     19#include "rmem.h" 
    2020#include "root.h" 
    2121#include "stringtable.h" 
    2222 
    2323#include "mars.h" 
    2424#include "lib.h" 
    2525#include "melf.h" 
    2626 
    2727#define LOG 0 
    2828 
    2929Library::Library() 
    3030{ 
    3131    libfile = NULL; 
    3232} 
    3333 
    3434/*********************************** 
    3535 * Set the library file name based on the output directory 
    3636 * and the filename. 
    3737 * Add default library file name extension. 
    3838 */ 
    3939 
  • trunk/src/libmach.c

    r182 r183  
    1212 * module format. While the format is 
    1313 * equivalent to the Linux arch format, it differs in many details. 
    1414 * This format is described in the Apple document 
    1515 * "Mac OS X ABI Mach-O File Format Reference" dated 2007-04-26 
    1616 * in the section "Static Archive Libraries". 
    1717 * That specification is only about half complete and has numerous 
    1818 * errors, so use the source code here as a better guide. 
    1919 */ 
    2020 
    2121#include <stdio.h> 
    2222#include <stdlib.h> 
    2323#include <assert.h> 
    2424#include <time.h> 
    2525#include <unistd.h> 
    2626#include <sys/types.h> 
    2727#include <sys/stat.h> 
    2828 
    2929#undef integer_t 
    3030#include "mach.h" 
    3131 
    32 #include "mem.h" 
     32#include "rmem.h" 
    3333#include "root.h" 
    3434#include "stringtable.h" 
    3535 
    3636#include "mars.h" 
    3737#include "lib.h" 
    3838 
    3939#define LOG 0 
    4040 
    4141Library::Library() 
    4242{ 
    4343    libfile = NULL; 
    4444} 
    4545 
    4646/*********************************** 
    4747 * Set the library file name based on the output directory 
    4848 * and the filename. 
    4949 * Add default library file name extension. 
    5050 */ 
    5151 
    5252void Library::setFilename(char *dir, char *filename) 
  • trunk/src/link.c

    r182 r183  
    1212#include    <ctype.h> 
    1313#include    <assert.h> 
    1414#include    <stdarg.h> 
    1515#include    <string.h> 
    1616#include    <stdlib.h> 
    1717 
    1818#if _WIN32 
    1919#include    <process.h> 
    2020#endif 
    2121 
    2222#if linux || __APPLE__ 
    2323#include    <sys/types.h> 
    2424#include    <sys/wait.h> 
    2525#include    <unistd.h> 
    2626#endif 
    2727 
    2828#include    "root.h" 
    2929 
    3030#include    "mars.h" 
    3131 
    32 #include    "mem.h" 
     32#include    "rmem.h" 
    3333 
    3434int executecmd(char *cmd, char *args, int useenv); 
    3535int executearg0(char *cmd, char *args); 
    3636 
    3737/**************************************** 
    3838 * Write filename to cmdbuf, quoting if necessary. 
    3939 */ 
    4040 
    4141void writeFilename(OutBuffer *buf, char *filename, size_t len) 
    4242{ 
    4343    /* Loop and see if we need to quote 
    4444     */ 
    4545    for (size_t i = 0; i < len; i++) 
    4646    {   char c = filename[i]; 
    4747 
    4848    if (isalnum(c) || c == '_') 
    4949        continue; 
    5050 
    5151    /* Need to quote 
    5252     */ 
  • trunk/src/macro.c

    r182 r183  
    11 
    22// Copyright (c) 1999-2006 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010/* Simple macro text processor. 
    1111 */ 
    1212 
    1313#include <stdio.h> 
    1414#include <string.h> 
    1515#include <time.h> 
    1616#include <ctype.h> 
    1717#include <assert.h> 
    1818 
    19 #ifdef IN_GCC 
    20 #include "mem.h" 
    21 #else 
    22 #if _WIN32 
    23 #include "..\root\mem.h" 
    24 #elif linux || __APPLE__ 
    25 #include "../root/mem.h" 
    26 #else 
    27 #error "fix this" 
    28 #endif 
    29 #endif 
    30  
     19#include "rmem.h" 
    3120#include "root.h" 
    3221#include "macro.h" 
    3322 
    3423#define isidstart(c) (isalpha(c) || (c) == '_') 
    3524#define isidchar(c)  (isalnum(c) || (c) == '_') 
    3625 
    3726unsigned char *memdup(unsigned char *p, size_t len) 
    3827{ 
    3928    return (unsigned char *)memcpy(mem.malloc(len), p, len); 
    4029} 
    4130 
    4231Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen) 
    4332{ 
    4433    next = NULL; 
    4534 
    4635#if 1 
    4736    this->name = name; 
    4837    this->namelen = namelen; 
    4938 
    5039    this->text = text; 
  • trunk/src/mars.c

    r182 r183  
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <ctype.h> 
    1414#include <assert.h> 
    1515#include <limits.h> 
    1616 
    1717#if __DMC__ 
    1818#include <dos.h> 
    1919#endif 
    2020 
    2121#if linux || __APPLE__ 
    2222#include <errno.h> 
    2323#endif 
    2424 
    25 #include "mem.h" 
     25#include "rmem.h" 
    2626#include "root.h" 
    2727 
    2828#include "mars.h" 
    2929#include "module.h" 
    3030#include "mtype.h" 
    3131#include "id.h" 
    3232#include "cond.h" 
    3333#include "expression.h" 
    3434#include "lexer.h" 
    3535#include "lib.h" 
    3636 
    3737#if WINDOWS_SEH 
    3838#include <windows.h> 
    3939long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); 
    4040#endif 
    4141 
    4242 
    4343void browse(const char *url); 
    4444void getenv_setargv(const char *envvar, int *pargc, char** *pargv); 
    4545 
     
    5757    ddoc_ext = "ddoc"; 
    5858 
    5959#if TARGET_WINDOS 
    6060    obj_ext  = "obj"; 
    6161#elif TARGET_LINUX || TARGET_OSX 
    6262    obj_ext  = "o"; 
    6363#else 
    6464#error "fix this" 
    6565#endif 
    6666 
    6767#if TARGET_WINDOS 
    6868    lib_ext  = "lib"; 
    6969#elif TARGET_LINUX || TARGET_OSX 
    7070    lib_ext  = "a"; 
    7171#else 
    7272#error "fix this" 
    7373#endif 
    7474 
    7575    copyright = "Copyright (c) 1999-2009 by Digital Mars"; 
    7676    written = "written by Walter Bright"; 
    77     version = "v2.025"; 
     77    version = "v2.026"; 
    7878    global.structalign = 8; 
    7979 
    8080    memset(&params, 0, sizeof(Param)); 
    8181} 
    8282 
    8383char *Loc::toChars() 
    8484{ 
    8585    OutBuffer buf; 
    8686    char *p; 
    8787 
    8888    if (filename) 
    8989    { 
    9090    buf.printf("%s", filename); 
    9191    } 
    9292 
    9393    if (linnum) 
    9494    buf.printf("(%d)", linnum); 
    9595    buf.writeByte(0); 
    9696    return (char *)buf.extractData(); 
    9797} 
    9898 
    9999Loc::Loc(Module *mod, unsigned linnum) 
    100100{ 
    101101    this->linnum = linnum; 
    102102    this->filename = mod ? mod->srcfile->toChars() : NULL; 
    103103} 
    104104 
    105105/************************************** 
    106106 * Print error message and exit. 
    107107 */ 
    108108 
    109109void error(Loc loc, const char *format, ...) 
    110110{ 
    111111    va_list ap; 
    112112    va_start(ap, format); 
    113113    verror(loc, format, ap); 
    114114    va_end( ap ); 
     115} 
     116 
     117void warning(Loc loc, const char *format, ...) 
     118{ 
     119    if (global.params.warnings && !global.gag) 
     120    { 
     121    fprintf(stdmsg, "warning - "); 
     122    va_list ap; 
     123    va_start(ap, format); 
     124    verror(loc, format, ap); 
     125    va_end( ap ); 
     126    } 
    115127} 
    116128 
    117129void verror(Loc loc, const char *format, va_list ap) 
    118130{ 
    119131    if (!global.gag) 
    120132    { 
    121133    char *p = loc.toChars(); 
    122134 
    123135    if (*p) 
    124136        fprintf(stdmsg, "%s: ", p); 
    125137    mem.free(p); 
    126138 
    127139    fprintf(stdmsg, "Error: "); 
    128140#if _MSC_VER 
    129141    // MS doesn't recognize %zu format 
    130142    OutBuffer tmp; 
    131143    tmp.vprintf(format, ap); 
    132144    fprintf(stdmsg, "%s", tmp.toChars()); 
    133145#else 
    134146    vfprintf(stdmsg, format, ap); 
     
    218230  -version=ident compile in version code identified by ident\n\ 
    219231  -w             enable warnings\n\ 
    220232", 
    221233#if WIN32 
    222234"  @cmdfile       read arguments from cmdfile\n" 
    223235#else 
    224236"" 
    225237#endif 
    226238); 
    227239} 
    228240 
    229241int main(int argc, char *argv[]) 
    230242{ 
    231243    int i; 
    232244    Array files; 
    233245    Array libmodules; 
    234246    char *p; 
    235247    Module *m; 
    236248    int status = EXIT_SUCCESS; 
    237249    int argcstart = argc; 
     250    int setdebuglib = 0; 
    238251 
    239252    // Check for malformed input 
    240253    if (argc < 1 || !argv) 
    241254    { 
    242255      Largs: 
    243256    error("missing or null command line arguments"); 
    244257    fatal(); 
    245258    } 
    246259    for (i = 0; i < argc; i++) 
    247260    { 
    248261    if (!argv[i]) 
    249262        goto Largs; 
    250263    } 
    251264 
    252265#if __DMC__ // DMC unique support for response files 
    253266    if (response_expand(&argc,&argv))   // expand response files 
    254267    error("can't open response file"); 
    255268#endif 
    256269 
    257270    files.reserve(argc - 1); 
     
    263276    global.params.useInvariants = 1; 
    264277    global.params.useIn = 1; 
    265278    global.params.useOut = 1; 
    266279    global.params.useArrayBounds = 1; 
    267280    global.params.useSwitchError = 1; 
    268281    global.params.useInline = 0; 
    269282    global.params.obj = 1; 
    270283    global.params.Dversion = 2; 
    271284    global.params.quiet = 1; 
    272285 
    273286    global.params.linkswitches = new Array(); 
    274287    global.params.libfiles = new Array(); 
    275288    global.params.objfiles = new Array(); 
    276289    global.params.ddocfiles = new Array(); 
    277290 
    278291#if TARGET_WINDOS 
    279292    global.params.defaultlibname = "phobos"; 
    280293#elif TARGET_LINUX || TARGET_OSX 
    281294    global.params.defaultlibname = "phobos2"; 
    282295#endif 
    283     global.params.debuglibname = global.params.defaultlibname; 
    284296 
    285297    // Predefine version identifiers 
    286298    VersionCondition::addPredefinedGlobalIdent("DigitalMars"); 
    287299#if TARGET_WINDOS 
    288300    VersionCondition::addPredefinedGlobalIdent("Windows"); 
    289301    global.params.isWindows = 1; 
    290302#endif 
    291303#if TARGET_LINUX 
    292304    VersionCondition::addPredefinedGlobalIdent("Posix"); 
    293305    VersionCondition::addPredefinedGlobalIdent("linux"); 
    294306    global.params.isLinux = 1; 
    295307#endif 
    296308#if TARGET_OSX 
    297309    VersionCondition::addPredefinedGlobalIdent("Posix"); 
    298310    VersionCondition::addPredefinedGlobalIdent("OSX"); 
    299311    global.params.isOSX = 1; 
    300312 
    301313    // For legacy compatibility 
    302314    VersionCondition::addPredefinedGlobalIdent("darwin"); 
    303315#endif 
     
    538550        else if (strcmp(p + 1, "-help") == 0) 
    539551        {   usage(); 
    540552        exit(EXIT_SUCCESS); 
    541553        } 
    542554        else if (strcmp(p + 1, "-r") == 0) 
    543555        global.params.debugr = 1; 
    544556        else if (strcmp(p + 1, "-x") == 0) 
    545557        global.params.debugx = 1; 
    546558        else if (strcmp(p + 1, "-y") == 0) 
    547559        global.params.debugy = 1; 
    548560        else if (p[1] == 'L') 
    549561        { 
    550562        global.params.linkswitches->push(p + 2); 
    551563        } 
    552564        else if (memcmp(p + 1, "defaultlib=", 11) == 0) 
    553565        { 
    554566        global.params.defaultlibname = p + 1 + 11; 
    555567        } 
    556568        else if (memcmp(p + 1, "debuglib=", 9) == 0) 
    557569        { 
     570        setdebuglib = 1; 
    558571        global.params.debuglibname = p + 1 + 9; 
    559572        } 
    560573        else if (memcmp(p + 1, "man", 3) == 0) 
    561574        { 
    562575#if _WIN32 
    563576#if V1 
    564577        browse("http://www.digitalmars.com/d/1.0/dmd-windows.html"); 
    565578#else 
    566579        browse("http://www.digitalmars.com/d/2.0/dmd-windows.html"); 
    567580#endif 
    568581#endif 
    569582#if linux 
    570583#if V1 
    571584        browse("http://www.digitalmars.com/d/1.0/dmd-linux.html"); 
    572585#else 
    573586        browse("http://www.digitalmars.com/d/2.0/dmd-linux.html"); 
    574587#endif 
    575588#endif 
    576589#if __APPLE__ 
    577590#if V1 
     
    613626#if !TARGET_LINUX && !TARGET_OSX 
    614627        char *ext = FileName::ext(p); 
    615628        if (ext && stricmp(ext, "exe") == 0) 
    616629        { 
    617630        global.params.objname = p; 
    618631        continue; 
    619632        } 
    620633#endif 
    621634        files.push(p); 
    622635    } 
    623636    } 
    624637    if (global.errors) 
    625638    { 
    626639    fatal(); 
    627640    } 
    628641    if (files.dim == 0) 
    629642    {   usage(); 
    630643    return EXIT_FAILURE; 
    631644    } 
    632645 
     646    if (!setdebuglib) 
     647    global.params.debuglibname = global.params.defaultlibname; 
     648 
    633649#if TARGET_OSX 
    634650    global.params.pic = 1; 
    635651#endif 
    636652 
    637653    if (global.params.release) 
    638654    {   global.params.useInvariants = 0; 
    639655    global.params.useIn = 0; 
    640656    global.params.useOut = 0; 
    641657    global.params.useAssert = 0; 
    642658    global.params.useArrayBounds = 0; 
    643659    global.params.useSwitchError = 0; 
    644660    } 
    645661 
    646662    if (global.params.run) 
    647663    global.params.quiet = 1; 
    648664 
    649665    if (global.params.useUnitTests) 
    650666    global.params.useAssert = 1; 
    651667 
    652668    if (!global.params.obj || global.params.lib) 
  • trunk/src/mars.h

    r182 r183  
    329329enum DYNCAST 
    330330{ 
    331331    DYNCAST_OBJECT, 
    332332    DYNCAST_EXPRESSION, 
    333333    DYNCAST_DSYMBOL, 
    334334    DYNCAST_TYPE, 
    335335    DYNCAST_IDENTIFIER, 
    336336    DYNCAST_TUPLE, 
    337337}; 
    338338 
    339339enum MATCH 
    340340{ 
    341341    MATCHnomatch,   // no match 
    342342    MATCHconvert,   // match with conversions 
    343343#if V2 
    344344    MATCHconst,     // match with conversion to const 
    345345#endif 
    346346    MATCHexact      // exact match 
    347347}; 
    348348 
     349void warning(Loc loc, const char *format, ...); 
    349350void error(Loc loc, const char *format, ...); 
    350351void verror(Loc loc, const char *format, va_list); 
    351352void fatal(); 
    352353void err_nomem(); 
    353354int runLINK(); 
    354355void deleteExeFile(); 
    355356int runProgram(); 
    356357void inifile(const char *argv0, const char *inifile); 
    357358void halt(); 
    358359void util_progress(); 
    359360 
    360361/*** Where to send error messages ***/ 
    361362#if IN_GCC 
    362363#define stdmsg stderr 
    363364#else 
    364365#define stdmsg stdout 
    365366#endif 
    366367 
    367368struct Dsymbol; 
    368369struct Library; 
  • trunk/src/module.c

    r180 r183  
    33// Copyright (c) 1999-2007 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    1515#ifdef _MSC_VER 
    1616#include <malloc.h> 
    1717#endif 
    1818 
    1919#if IN_GCC 
    2020#include "gdc_alloca.h" 
    2121#endif 
    2222 
    23 #include "mem.h" 
     23#include "rmem.h" 
    2424 
    2525#include "mars.h" 
    2626#include "module.h" 
    2727#include "parse.h" 
    2828#include "scope.h" 
    2929#include "identifier.h" 
    3030#include "id.h" 
    3131#include "import.h" 
    3232#include "dsymbol.h" 
    3333#include "hdrgen.h" 
    3434#include "lexer.h" 
    3535 
    3636#define MARS 1 
    3737#include "html.h" 
    3838 
    3939#ifdef IN_GCC 
    4040#include "d-dmd-gcc.h" 
    4141#endif 
    4242 
    4343ClassDeclaration *Module::moduleinfo; 
     
    5858    : Package(ident) 
    5959{ 
    6060    FileName *srcfilename; 
    6161    FileName *cfilename; 
    6262    FileName *hfilename; 
    6363    FileName *objfilename; 
    6464    FileName *symfilename; 
    6565 
    6666//    printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); 
    6767    this->arg = filename; 
    6868    md = NULL; 
    6969    errors = 0; 
    7070    numlines = 0; 
    7171    members = NULL; 
    7272    isHtml = 0; 
    7373    isDocFile = 0; 
    7474    needmoduleinfo = 0; 
    7575#ifdef IN_GCC 
    7676    strictlyneedmoduleinfo = 0; 
    7777#endif 
     78    selfimports = 0; 
    7879    insearch = 0; 
    7980    searchCacheIdent = NULL; 
    8081    searchCacheSymbol = NULL; 
    8182    searchCacheFlags = 0; 
    8283    semanticstarted = 0; 
    8384    semanticdone = 0; 
    8485    decldefs = NULL; 
    8586    vmoduleinfo = NULL; 
    8687    massert = NULL; 
    8788    marray = NULL; 
    8889    sictor = NULL; 
    8990    sctor = NULL; 
    9091    sdtor = NULL; 
    9192    stest = NULL; 
    9293    sfilename = NULL; 
    9394    root = 0; 
    9495    importedFrom = NULL; 
    9596    srcfile = NULL; 
    9697    docfile = NULL; 
    9798 
     
    898899 */ 
    899900 
    900901int Module::imports(Module *m) 
    901902{ 
    902903    //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); 
    903904    int aimports_dim = aimports.dim; 
    904905#if 0 
    905906    for (int i = 0; i < aimports.dim; i++) 
    906907    {   Module *mi = (Module *)aimports.data[i]; 
    907908    printf("\t[%d] %s\n", i, mi->toChars()); 
    908909    } 
    909910#endif 
    910911    for (int i = 0; i < aimports.dim; i++) 
    911912    {   Module *mi = (Module *)aimports.data[i]; 
    912913    if (mi == m) 
    913914        return TRUE; 
    914915    if (!mi->insearch) 
    915916    { 
    916917        mi->insearch = 1; 
    917918        int r = mi->imports(m); 
    918         mi->insearch = 0; 
    919919        if (r) 
    920920        return r; 
    921921    } 
    922922    } 
    923923    return FALSE; 
    924924} 
     925 
     926/************************************* 
     927 * Return !=0 if module imports itself. 
     928 */ 
     929 
     930int Module::selfImports() 
     931{ 
     932    //printf("Module::selfImports() %s\n", toChars()); 
     933    if (!selfimports) 
     934    { 
     935    for (int i = 0; i < amodules.dim; i++) 
     936    {   Module *mi = (Module *)amodules.data[i]; 
     937        //printf("\t[%d] %s\n", i, mi->toChars()); 
     938        mi->insearch = 0; 
     939    } 
     940 
     941    selfimports = imports(this) + 1; 
     942 
     943    for (int i = 0; i < amodules.dim; i++) 
     944    {   Module *mi = (Module *)amodules.data[i]; 
     945        //printf("\t[%d] %s\n", i, mi->toChars()); 
     946        mi->insearch = 0; 
     947    } 
     948    } 
     949    return selfimports - 1; 
     950} 
     951 
    925952 
    926953/* =========================== ModuleDeclaration ===================== */ 
    927954 
    928955ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) 
    929956{ 
    930957    this->packages = packages; 
    931958    this->id = id; 
    932959    this->safe = safe; 
    933960} 
    934961 
    935962char *ModuleDeclaration::toChars() 
    936963{ 
    937964    OutBuffer buf; 
    938965    int i; 
    939966 
    940967    if (packages && packages->dim) 
    941968    { 
    942969    for (i = 0; i < packages->dim; i++) 
    943970    {   Identifier *pid = (Identifier *)packages->data[i]; 
    944971 
  • trunk/src/module.h

    r180 r183  
    5555    static void init(); 
    5656 
    5757    static ClassDeclaration *moduleinfo; 
    5858 
    5959 
    6060    const char *arg;    // original argument name 
    6161    ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration 
    6262    File *srcfile;  // input source file 
    6363    File *objfile;  // output .obj file 
    6464    File *hdrfile;  // 'header' file 
    6565    File *symfile;  // output symbol file 
    6666    File *docfile;  // output documentation file 
    6767    unsigned errors;    // if any errors in file 
    6868    unsigned numlines;  // number of lines in source file 
    6969    int isHtml;     // if it is an HTML file 
    7070    int isDocFile;  // if it is a documentation input file, not D source 
    7171    int needmoduleinfo; 
    7272#ifdef IN_GCC 
    7373    int strictlyneedmoduleinfo; 
    7474#endif 
     75 
     76    int selfimports;        // 0: don't know, 1: does not, 2: does 
     77    int selfImports();      // returns !=0 if module imports itself 
    7578 
    7679    int insearch; 
    7780    Identifier *searchCacheIdent; 
    7881    Dsymbol *searchCacheSymbol; // cached value of search 
    7982    int searchCacheFlags;   // cached flags 
    8083 
    8184    int semanticstarted;    // has semantic() been started? 
    8285    int semanticdone;       // has semantic() been done? 
    8386    int root;           // != 0 if this is a 'root' module, 
    8487                // i.e. a module that will be taken all the 
    8588                // way to an object file 
    8689    Module *importedFrom;   // module from command line we're imported from, 
    8790                // i.e. a module that will be taken all the 
    8891                // way to an object file 
    8992 
    9093    Array *decldefs;        // top level declarations for this Module 
    9194 
    9295    Array aimports;     // all imported modules 
    9396 
    9497    ModuleInfoDeclaration *vmoduleinfo; 
  • trunk/src/mtype.c

    r182 r183  
    2222#if _MSC_VER 
    2323#include <malloc.h> 
    2424#include <complex> 
    2525#include <limits> 
    2626#elif __DMC__ 
    2727#include <complex.h> 
    2828#else 
    2929//#define signbit 56 
    3030#endif 
    3131 
    3232#if __APPLE__ 
    3333#include <math.h> 
    3434static double zero = 0; 
    3535#elif __GNUC__ 
    3636#include <math.h> 
    3737#include <bits/nan.h> 
    3838#include <bits/mathdef.h> 
    3939static double zero = 0; 
    4040#endif 
    4141 
    42 #include "mem.h" 
     42#include "rmem.h" 
    4343 
    4444#include "dsymbol.h" 
    4545#include "mtype.h" 
    4646#include "scope.h" 
    4747#include "init.h" 
    4848#include "expression.h" 
    4949#include "attrib.h" 
    5050#include "declaration.h" 
    5151#include "template.h" 
    5252#include "id.h" 
    5353#include "enum.h" 
    5454#include "import.h" 
    5555#include "aggregate.h" 
    5656#include "hdrgen.h" 
    5757 
    5858FuncDeclaration *hasThis(Scope *sc); 
    5959 
    6060 
    6161#define LOGDOTEXP   0   // log ::dotExp() 
    6262#define LOGDEFAULTINIT  0   // log ::defaultInit() 
     
    13651365    {   char *s = e->toChars(); 
    13661366    e = new StringExp(e->loc, s, strlen(s), 'c'); 
    13671367    Scope sc; 
    13681368    e = e->semantic(&sc); 
    13691369    return e; 
    13701370    } 
    13711371    return getProperty(e->loc, ident); 
    13721372} 
    13731373 
    13741374unsigned Type::memalign(unsigned salign) 
    13751375{ 
    13761376    return salign; 
    13771377} 
    13781378 
    13791379void Type::error(Loc loc, const char *format, ...) 
    13801380{ 
    13811381    va_list ap; 
    13821382    va_start(ap, format); 
    13831383    ::verror(loc, format, ap); 
    13841384    va_end( ap ); 
     1385} 
     1386 
     1387void Type::warning(Loc loc, const char *format, ...) 
     1388{ 
     1389    if (global.params.warnings && !global.gag) 
     1390    { 
     1391    fprintf(stdmsg, "warning - "); 
     1392    va_list ap; 
     1393    va_start(ap, format); 
     1394    ::verror(loc, format, ap); 
     1395    va_end( ap ); 
     1396    } 
    13851397} 
    13861398 
    13871399Identifier *Type::getTypeInfoIdent(int internal) 
    13881400{ 
    13891401    // _init_10TypeInfo_%s 
    13901402    OutBuffer buf; 
    13911403    Identifier *id; 
    13921404    char *name; 
    13931405    int len; 
    13941406 
    13951407    if (internal) 
    13961408    {   buf.writeByte(mangleChar[ty]); 
    13971409    if (ty == Tarray) 
    13981410        buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]); 
    13991411    } 
    14001412    else 
    14011413    toDecoBuffer(&buf); 
    14021414    len = buf.offset; 
    14031415    name = (char *)alloca(19 + sizeof(len) * 3 + len + 1); 
    14041416    buf.writeByte(0); 
     
    26242636        error(loc, "index %jd overflow for static array", d1); 
    26252637        dim = new IntegerExp(0, 1, tsize_t); 
    26262638        } 
    26272639    } 
    26282640    } 
    26292641    switch (tbn->ty) 
    26302642    { 
    26312643    case Ttuple: 
    26322644    {   // Index the tuple to get the type 
    26332645        assert(dim); 
    26342646        TypeTuple *tt = (TypeTuple *)tbn; 
    26352647        uinteger_t d = dim->toUInteger(); 
    26362648 
    26372649        if (d >= tt->arguments->dim) 
    26382650        {   error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); 
    26392651        return Type::terror; 
    26402652        } 
    26412653        Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; 
    26422654        return arg->type; 
    26432655    } 
     2656    case Tstruct: 
     2657    {   TypeStruct *ts = (TypeStruct *)tbn; 
     2658        if (ts->sym->isnested) 
     2659        error(loc, "cannot have array of inner structs %s", ts->toChars()); 
     2660        break; 
     2661    } 
    26442662    case Tfunction: 
    26452663    case Tnone: 
    26462664        error(loc, "can't have array of %s", tbn->toChars()); 
    26472665        tbn = next = tint32; 
    26482666        break; 
    26492667    } 
    26502668    if (tbn->isauto()) 
    26512669    error(loc, "cannot have array of auto %s", tbn->toChars()); 
    26522670    return merge(); 
    26532671} 
    26542672 
    26552673void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) 
    26562674{ 
    26572675    Type::toDecoBuffer(buf, flag); 
    26582676    if (dim) 
    26592677    buf->printf("%ju", dim->toInteger()); 
    26602678    if (next) 
    26612679    /* Note that static arrays are value types, so 
    26622680     * for a parameter, propagate the 0x100 to the next 
    26632681     * level, since for T[4][3], any const should apply to the T, 
     
    28352853unsigned TypeDArray::alignsize() 
    28362854{ 
    28372855    // A DArray consists of two ptr-sized values, so align it on pointer size 
    28382856    // boundary 
    28392857    return PTRSIZE; 
    28402858} 
    28412859 
    28422860Type *TypeDArray::semantic(Loc loc, Scope *sc) 
    28432861{   Type *tn = next; 
    28442862 
    28452863    tn = next->semantic(loc,sc); 
    28462864    Type *tbn = tn->toBasetype(); 
    28472865    switch (tbn->ty) 
    28482866    { 
    28492867    case Tfunction: 
    28502868    case Tnone: 
    28512869    case Ttuple: 
    28522870        error(loc, "can't have array of %s", tbn->toChars()); 
    28532871        tn = next = tint32; 
    28542872        break; 
     2873    case Tstruct: 
     2874    {   TypeStruct *ts = (TypeStruct *)tbn; 
     2875        if (ts->sym->isnested) 
     2876        error(loc, "cannot have array of inner structs %s", ts->toChars()); 
     2877        break; 
     2878    } 
    28552879    } 
    28562880    if (tn->isauto()) 
    28572881    error(loc, "cannot have array of auto %s", tn->toChars()); 
    28582882 
    28592883    next = tn; 
    28602884    transitive(); 
    28612885    return merge(); 
    28622886} 
    28632887 
    28642888void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag) 
    28652889{ 
    28662890    Type::toDecoBuffer(buf, flag); 
    28672891    if (next) 
    28682892    next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); 
    28692893} 
    28702894 
    28712895void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    28722896{ 
    28732897    if (mod != this->mod) 
    28742898    {   toCBuffer3(buf, hgs, mod); 
     
    36513675    buf->writeByte(mc); 
    36523676    if (ispure || isnothrow || isref) 
    36533677    { 
    36543678    if (ispure) 
    36553679        buf->writestring("Na"); 
    36563680    if (isnothrow) 
    36573681        buf->writestring("Nb"); 
    36583682    if (isref) 
    36593683        buf->writestring("Nc"); 
    36603684    } 
    36613685    // Write argument types 
    36623686    Argument::argsToDecoBuffer(buf, parameters); 
    36633687    //if (buf->data[buf->offset - 1] == '@') halt(); 
    36643688    buf->writeByte('Z' - varargs);  // mark end of arg list 
    36653689    next->toDecoBuffer(buf); 
    36663690    inuse--; 
    36673691} 
    36683692 
    36693693void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) 
    36703694{ 
    3671     //printf("TypeFunction::toCBuffer() this = %p %s\n", this, toChars()); 
     3695    //printf("TypeFunction::toCBuffer() this = %p\n", this); 
    36723696    const char *p = NULL; 
    36733697 
    36743698    if (inuse) 
    36753699    {   inuse = 2;      // flag error to caller 
    36763700    return; 
    36773701    } 
    36783702    inuse++; 
    36793703 
    36803704    /* Use 'storage class' style for attributes 
    36813705     */ 
    36823706    if (mod & MODconst) 
    36833707    buf->writestring("const "); 
    36843708    if (mod & MODinvariant) 
    36853709    buf->writestring("immutable "); 
    36863710    if (mod & MODshared) 
    36873711    buf->writestring("shared "); 
    36883712 
    36893713    if (ispure) 
    36903714    buf->writestring("pure "); 
    36913715    if (isnothrow) 
     
    37043728        case LINKwindows:   p = "Windows "; break; 
    37053729        case LINKpascal:    p = "Pascal ";  break; 
    37063730        case LINKcpp:   p = "C++ "; break; 
    37073731        default: 
    37083732        assert(0); 
    37093733    } 
    37103734    } 
    37113735 
    37123736    if (!hgs->hdrgen && p) 
    37133737    buf->writestring(p); 
    37143738    if (ident) 
    37153739    {   buf->writeByte(' '); 
    37163740    buf->writestring(ident->toHChars2()); 
    37173741    } 
    37183742    Argument::argsToCBuffer(buf, hgs, parameters, varargs); 
    37193743    inuse--; 
    37203744} 
    37213745 
    37223746void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    37233747{ 
    3724     //printf("TypeFunction::toCBuffer2() this = %p %s\n", this, toChars()); 
     3748    //printf("TypeFunction::toCBuffer2() this = %p, ref = %d\n", this, isref); 
    37253749    const char *p = NULL; 
    37263750 
    37273751    if (inuse) 
    37283752    {   inuse = 2;      // flag error to caller 
    37293753    return; 
    37303754    } 
    37313755    inuse++; 
    37323756    if (next) 
    37333757    next->toCBuffer2(buf, hgs, 0); 
    37343758    if (hgs->ddoc != 1) 
    37353759    { 
    37363760    switch (linkage) 
    37373761    { 
    37383762        case LINKd:     p = NULL;   break; 
    37393763        case LINKc:     p = "C ";   break; 
    37403764        case LINKwindows:   p = "Windows "; break; 
    37413765        case LINKpascal:    p = "Pascal ";  break; 
    37423766        case LINKcpp:   p = "C++ "; break; 
    37433767        default: 
    37443768        assert(0); 
     
    49835007    buf->printf("%s", name); 
    49845008} 
    49855009 
    49865010void TypeEnum::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    49875011{ 
    49885012    if (mod != this->mod) 
    49895013    {   toCBuffer3(buf, hgs, mod); 
    49905014    return; 
    49915015    } 
    49925016    buf->writestring(sym->toChars()); 
    49935017} 
    49945018 
    49955019Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident) 
    49965020{ 
    49975021#if LOGDOTEXP 
    49985022    printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); 
    49995023#endif 
    50005024    Dsymbol *s = sym->search(e->loc, ident, 0); 
    50015025    if (!s) 
    50025026    { 
    5003     return getProperty(e->loc, ident); 
     5027    if (ident == Id::max || 
     5028        ident == Id::min || 
     5029        ident == Id::init || 
     5030        ident == Id::stringof || 
     5031        !sym->memtype 
     5032       ) 
     5033    { 
     5034        return getProperty(e->loc, ident); 
     5035    } 
     5036    return sym->memtype->dotExp(sc, e, ident); 
    50045037    } 
    50055038    EnumMember *m = s->isEnumMember(); 
    50065039    Expression *em = m->value->copy(); 
    50075040    em->loc = e->loc; 
    50085041    return em; 
    50095042} 
    50105043 
    50115044Expression *TypeEnum::getProperty(Loc loc, Identifier *ident) 
    50125045{   Expression *e; 
    50135046 
    50145047    if (ident == Id::max) 
    50155048    { 
    50165049    if (!sym->maxval) 
    50175050        goto Lfwd; 
    50185051    e = sym->maxval; 
    50195052    } 
    50205053    else if (ident == Id::min) 
    50215054    { 
    50225055    if (!sym->minval) 
    50235056        goto Lfwd; 
     
    56845717{ 
    56855718    /* If any of the fields are const or invariant, 
    56865719     * then one cannot assign this struct. 
    56875720     */ 
    56885721    for (size_t i = 0; i < sym->fields.dim; i++) 
    56895722    {   VarDeclaration *v = (VarDeclaration *)sym->fields.data[i]; 
    56905723    if (v->isConst() || v->isInvariant()) 
    56915724        return FALSE; 
    56925725    } 
    56935726    return TRUE; 
    56945727} 
    56955728 
    56965729int TypeStruct::hasPointers() 
    56975730{ 
    56985731    StructDeclaration *s = sym; 
    56995732 
    57005733    sym->size(0);       // give error for forward references 
    57015734    for (size_t i = 0; i < s->fields.dim; i++) 
    57025735    { 
    57035736    Dsymbol *sm = (Dsymbol *)s->fields.data[i]; 
    5704     if (sm->hasPointers()) 
     5737    Declaration *d = sm->isDeclaration(); 
     5738    if (d->storage_class & STCref || d->hasPointers()) 
    57055739        return TRUE; 
    57065740    } 
    57075741    return FALSE; 
    57085742} 
    57095743 
    57105744MATCH TypeStruct::implicitConvTo(Type *to) 
    57115745{   MATCH m; 
    57125746 
    57135747    //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars()); 
    57145748    if (ty == to->ty && sym == ((TypeStruct *)to)->sym) 
    57155749    {   m = MATCHexact;     // exact match 
    57165750    if (mod != to->mod) 
    57175751    { 
    57185752        if (to->mod == MODconst) 
    57195753        m = MATCHconst; 
    57205754        else 
    57215755        {   /* Check all the fields. If they can all be converted, 
    57225756         * allow the conversion. 
    57235757         */ 
    57245758        for (int i = 0; i < sym->fields.dim; i++) 
  • trunk/src/mtype.h

    r182 r183  
    266266    virtual ClassDeclaration *isClassHandle(); 
    267267    virtual Expression *getProperty(Loc loc, Identifier *ident); 
    268268    virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    269269    virtual unsigned memalign(unsigned salign); 
    270270    virtual Expression *defaultInit(Loc loc = 0); 
    271271    virtual int isZeroInit();       // if initializer is 0 
    272272    virtual dt_t **toDt(dt_t **pdt); 
    273273    Identifier *getTypeInfoIdent(int internal); 
    274274    virtual MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    275275    virtual void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); 
    276276    Expression *getInternalTypeInfo(Scope *sc); 
    277277    Expression *getTypeInfo(Scope *sc); 
    278278    virtual TypeInfoDeclaration *getTypeInfoDeclaration(); 
    279279    virtual int builtinTypeInfo(); 
    280280    virtual Type *reliesOnTident(); 
    281281    virtual Expression *toExpression(); 
    282282    virtual int hasPointers(); 
    283283    virtual Type *nextOf(); 
    284284 
    285285    static void error(Loc loc, const char *format, ...); 
     286    static void warning(Loc loc, const char *format, ...); 
    286287 
    287288    // For backend 
    288289    virtual unsigned totym(); 
    289290    virtual type *toCtype(); 
    290291    virtual type *toCParamtype(); 
    291292    virtual Symbol *toSymbol(); 
    292293 
    293294    // For eliminating dynamic_cast 
    294295    virtual TypeBasic *isTypeBasic(); 
    295296}; 
    296297 
    297298struct TypeNext : Type 
    298299{ 
    299300    Type *next; 
    300301 
    301302    TypeNext(TY ty, Type *next); 
    302303    void toDecoBuffer(OutBuffer *buf, int flag); 
    303304    void checkDeprecated(Loc loc, Scope *sc); 
    304305    Type *reliesOnTident(); 
    305306    Type *nextOf(); 
     
    794795    Argument(unsigned storageClass, Type *type, Identifier *ident, Expression *defaultArg); 
    795796    Argument *syntaxCopy(); 
    796797    Type *isLazyArray(); 
    797798    void toDecoBuffer(OutBuffer *buf); 
    798799    static Arguments *arraySyntaxCopy(Arguments *args); 
    799800    static char *argsTypesToChars(Arguments *args, int varargs); 
    800801    static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs); 
    801802    static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *arguments, int varargs); 
    802803    static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments); 
    803804    static int isTPL(Arguments *arguments); 
    804805    static size_t dim(Arguments *arguments); 
    805806    static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL); 
    806807}; 
    807808 
    808809extern int PTRSIZE; 
    809810extern int REALSIZE; 
    810811extern int REALPAD; 
    811812extern int Tsize_t; 
    812813extern int Tptrdiff_t; 
    813814 
     815int arrayTypeCompatible(Loc loc, Type *t1, Type *t2); 
     816 
    814817#endif /* DMD_MTYPE_H */ 
  • trunk/src/opover.c

    r182 r183  
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <ctype.h> 
    1414#include <assert.h> 
    1515#if _MSC_VER 
    1616#include <complex> 
    1717#else 
    1818#include <complex.h> 
    1919#endif 
    2020 
    2121#ifdef __APPLE__ 
    2222#define integer_t dmd_integer_t 
    2323#endif 
    2424 
    25 #if IN_GCC 
    26 #include "mem.h" 
    27 #elif linux || __APPLE__ 
    28 #include "../root/mem.h" 
    29 #elif _WIN32 
    30 #include "..\root\mem.h" 
    31 #endif 
     25#include "rmem.h" 
    3226 
    3327//#include "port.h" 
    3428#include "mtype.h" 
    3529#include "init.h" 
    3630#include "expression.h" 
    3731#include "id.h" 
    3832#include "declaration.h" 
    3933#include "aggregate.h" 
    4034#include "template.h" 
    4135 
    4236static void inferApplyArgTypesX(FuncDeclaration *fstart, Arguments *arguments); 
    4337static void inferApplyArgTypesZ(TemplateDeclaration *tstart, Arguments *arguments); 
    4438static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments); 
    4539static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments); 
    4640 
    4741/******************************** Expression **************************/ 
    4842 
    4943 
    5044/*********************************** 
    5145 * Determine if operands of binary op can be reversed 
  • trunk/src/parse.c

    r181 r183  
    11 
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111// This is the D parser 
    1212 
    1313#include <stdio.h> 
    1414#include <assert.h> 
    1515 
    16 #include "mem.h" 
     16#include "rmem.h" 
    1717#include "lexer.h" 
    1818#include "parse.h" 
    1919#include "init.h" 
    2020#include "attrib.h" 
    2121#include "cond.h" 
    2222#include "mtype.h" 
    2323#include "template.h" 
    2424#include "staticassert.h" 
    2525#include "expression.h" 
    2626#include "statement.h" 
    2727#include "module.h" 
    2828#include "dsymbol.h" 
    2929#include "import.h" 
    3030#include "declaration.h" 
    3131#include "aggregate.h" 
    3232#include "enum.h" 
    3333#include "id.h" 
    3434#include "version.h" 
    3535 
    3636// How multiple declarations are parsed. 
     
    370370            break; 
    371371        } 
    372372 
    373373        /* Look for auto initializers: 
    374374         *  storage_class identifier = initializer; 
    375375         */ 
    376376        if (token.value == TOKidentifier && 
    377377            peek(&token)->value == TOKassign) 
    378378        { 
    379379            a = parseAutoDeclarations(storageClass, comment); 
    380380            decldefs->append(a); 
    381381            continue; 
    382382        } 
    383383 
    384384        /* Look for return type inference for template functions. 
    385385         */ 
    386386        Token *tk; 
    387387        if (token.value == TOKidentifier && 
    388388            (tk = peek(&token))->value == TOKlparen && 
    389389            skipParens(tk, &tk) && 
    390             peek(tk)->value == TOKlparen) 
     390            (peek(tk)->value == TOKlparen || 
     391             peek(tk)->value == TOKlcurly) 
     392           ) 
    391393        { 
    392394            a = parseDeclarations(storageClass); 
    393395            decldefs->append(a); 
    394396            continue; 
    395397        } 
    396398        a = parseBlock(); 
    397399        s = new StorageClassDeclaration(storageClass, a); 
    398400        break; 
    399401 
    400402        case TOKextern: 
    401403        if (peek(&token)->value != TOKlparen) 
    402404        {   stc = STCextern; 
    403405            goto Lstc; 
    404406        } 
    405407        { 
    406408        enum LINK linksave = linkage; 
    407409        linkage = parseLinkage(); 
    408410        a = parseBlock(); 
    409411        s = new LinkDeclaration(linkage, a); 
    410412        linkage = linksave; 
     
    17311733/****************************************** 
    17321734 * Parse template argument list. 
    17331735 * Input: 
    17341736 *  current token is opening '(' 
    17351737 * Output: 
    17361738 *  current token is one after closing ')' 
    17371739 */ 
    17381740 
    17391741Objects *Parser::parseTemplateArgumentList() 
    17401742{ 
    17411743    //printf("Parser::parseTemplateArgumentList()\n"); 
    17421744    if (token.value != TOKlparen && token.value != TOKlcurly) 
    17431745    {   error("!(TemplateArgumentList) expected following TemplateIdentifier"); 
    17441746    return new Objects(); 
    17451747    } 
    17461748    return parseTemplateArgumentList2(); 
    17471749} 
    17481750 
    17491751Objects *Parser::parseTemplateArgumentList2() 
    17501752{ 
     1753    //printf("Parser::parseTemplateArgumentList2()\n"); 
    17511754    Objects *tiargs = new Objects(); 
    17521755    enum TOK endtok = TOKrparen; 
    17531756    nextToken(); 
    17541757 
    17551758    // Get TemplateArgumentList 
    17561759    if (token.value != endtok) 
    17571760    { 
    17581761    while (1) 
    17591762    { 
    17601763        // See if it is an Expression or a Type 
    17611764        if (isDeclaration(&token, 0, TOKreserved, NULL)) 
    17621765        {   // Template argument is a type 
    17631766        Type *ta = parseType(); 
    17641767        tiargs->push(ta); 
    17651768        } 
    17661769        else 
    17671770        {   // Template argument is an expression 
    17681771        Expression *ea = parseAssignExp(); 
    17691772        tiargs->push(ea); 
    17701773        } 
     
    38893892    if (token.value != value) 
    38903893    error("found '%s' when expecting '%s' following '%s'", 
    38913894        token.toChars(), Token::toChars(value), string); 
    38923895    nextToken(); 
    38933896} 
    38943897 
    38953898/************************************ 
    38963899 * Determine if the scanner is sitting on the start of a declaration. 
    38973900 * Input: 
    38983901 *  needId  0   no identifier 
    38993902 *      1   identifier optional 
    39003903 *      2   must have identifier 
    39013904 */ 
    39023905 
    39033906int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt) 
    39043907{ 
    39053908    //printf("isDeclaration(needId = %d)\n", needId); 
    39063909    int haveId = 0; 
    39073910 
    39083911#if V2 
    3909     if ((t->value == TOKconst || t->value == TOKinvariant || token.value == TOKimmutable || token.value == TOKshared) && 
     3912    if ((t->value == TOKconst || 
     3913     t->value == TOKinvariant || 
     3914     t->value == TOKimmutable || 
     3915     t->value == TOKshared) && 
    39103916    peek(t)->value != TOKlparen) 
    39113917    {   /* const type 
    39123918     * immutable type 
    39133919     * shared type 
    39143920     */ 
    39153921    t = peek(t); 
    39163922    } 
    39173923#endif 
    39183924 
    39193925    if (!isBasicType(&t)) 
     3926    { 
    39203927    goto Lisnot; 
     3928    } 
    39213929    if (!isDeclarator(&t, &haveId, endtok)) 
    39223930    goto Lisnot; 
    39233931    if ( needId == 1 || 
    39243932    (needId == 0 && !haveId) || 
    39253933    (needId == 2 &&  haveId)) 
    39263934    {   if (pt) 
    39273935        *pt = t; 
    39283936    goto Lis; 
    39293937    } 
    39303938    else 
    39313939    goto Lisnot; 
    39323940 
    39333941Lis: 
    39343942    //printf("\tis declaration\n"); 
    39353943    return TRUE; 
    39363944 
    39373945Lisnot: 
    39383946    //printf("\tis not declaration\n"); 
    39393947    return FALSE; 
    39403948} 
     
    40244032    case TOKtypeof: 
    40254033        /* typeof(exp).identifier... 
    40264034         */ 
    40274035        t = peek(t); 
    40284036        if (t->value != TOKlparen) 
    40294037        goto Lfalse; 
    40304038        if (!skipParens(t, &t)) 
    40314039        goto Lfalse; 
    40324040        goto L2; 
    40334041 
    40344042    case TOKconst: 
    40354043    case TOKinvariant: 
    40364044    case TOKimmutable: 
    40374045    case TOKshared: 
    40384046        // const(type)  or  immutable(type)  or  shared(type) 
    40394047        t = peek(t); 
    40404048        if (t->value != TOKlparen) 
    40414049        goto Lfalse; 
    40424050        t = peek(t); 
    40434051        if (!isDeclaration(t, 0, TOKrparen, &t)) 
     4052        { 
    40444053        goto Lfalse; 
     4054        } 
    40454055        t = peek(t); 
    40464056        break; 
    40474057 
    40484058    default: 
    40494059        goto Lfalse; 
    40504060    } 
    40514061    *pt = t; 
    40524062    //printf("is\n"); 
    40534063    return TRUE; 
    40544064 
    40554065Lfalse: 
    40564066    //printf("is not\n"); 
    40574067    return FALSE; 
    40584068} 
    40594069 
    40604070int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok) 
    40614071{   // This code parallels parseDeclarator() 
    40624072    Token *t = *pt; 
    40634073    int parens; 
    40644074 
  • trunk/src/readme.txt

    r5 r183  
    11 
    22        The D Programming Language 
    33        Compiler Front End Source 
    4         Copyright (c) 1999-2002, by Digital Mars 
    5         www.digitalmars.com 
     4        Copyright (c) 1999-2009, by Digital Mars 
     5        http://www.digitalmars.com 
    66        All Rights Reserved 
    77 
    88 
    99This is the source code to the front end Digital Mars D compiler. 
    1010It covers the lexical analysis, parsing, and semantic analysis 
    1111of the D Programming Language defined in the documents at 
    12 www.digitalmars.com/d/ 
    13  
    14 The optimizer, code generator, and object file generator are not part 
    15 of this source, hence the source does not currently constitute a complete, 
    16 compilable program. However, many people have expressed a strong interested 
    17 in producing a D compiler with the GNU compiler sources. This release should 
    18 enable that. 
     12http://www.digitalmars.com/d/ 
    1913 
    2014These sources are free, they are redistributable and modifiable 
    2115under the terms of the GNU General Public License (attached as gpl.txt), 
    2216or the Artistic License (attached as artistic.txt). 
    2317 
     18The optimizer and code generator sources are  
     19covered under a separate license, backendlicense.txt. 
     20 
    2421It does not apply to anything else distributed by Digital Mars, 
    2522including D compiler executables. 
    2623 
    2724-Walter Bright 
  • trunk/src/root/array.c

    r103 r183  
    2020#if IN_GCC 
    2121#include "gdc_alloca.h" 
    2222#endif 
    2323 
    2424#if _WIN32 
    2525#include <windows.h> 
    2626#endif 
    2727 
    2828#ifndef _WIN32 
    2929#include <sys/types.h> 
    3030#include <sys/stat.h> 
    3131#include <fcntl.h> 
    3232#include <errno.h> 
    3333#include <unistd.h> 
    3434#include <utime.h> 
    3535#endif 
    3636 
    3737#include "port.h" 
    3838#include "root.h" 
    3939#include "dchar.h" 
    40 #include "mem.h" 
     40#include "rmem.h" 
    4141 
    4242 
    4343/********************************* Array ****************************/ 
    4444 
    4545Array::Array() 
    4646{ 
    4747    data = NULL; 
    4848    dim = 0; 
    4949    allocdim = 0; 
    5050} 
    5151 
    5252Array::~Array() 
    5353{ 
    5454    mem.free(data); 
    5555} 
    5656 
    5757void Array::mark() 
    5858{   unsigned u; 
    5959 
    6060    mem.mark(data); 
  • trunk/src/root/dchar.c

    r111 r183  
    11 
    22// Copyright (c) 1999-2006 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <stdint.h> 
    1414#include <assert.h> 
    1515 
    1616#include "dchar.h" 
    17 #include "mem.h" 
     17#include "rmem.h" 
    1818 
    1919#if M_UNICODE 
    2020 
    2121// Converts a char string to Unicode 
    2222 
    2323dchar *Dchar::dup(char *p) 
    2424{ 
    2525    dchar *s; 
    2626    size_t len; 
    2727 
    2828    if (!p) 
    2929    return NULL; 
    3030    len = strlen(p); 
    3131    s = (dchar *)mem.malloc((len + 1) * sizeof(dchar)); 
    3232    for (unsigned i = 0; i < len; i++) 
    3333    { 
    3434    s[i] = (dchar)(p[i] & 0xFF); 
    3535    } 
    3636    s[len] = 0; 
    3737    return s; 
  • trunk/src/root/lstring.c

    r179 r183  
    11// lstring.c 
    22 
    33// Copyright (c) 1999-2002 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdlib.h> 
    1212 
    1313#include "dchar.h" 
    14 #include "mem.h" 
     14#include "rmem.h" 
    1515#include "lstring.h" 
    1616 
    1717#ifdef _MSC_VER // prevent compiler internal crash 
    1818Lstring Lstring::zero; 
    1919#else 
    2020Lstring Lstring::zero = LSTRING_EMPTY(); 
    2121#endif 
    2222 
    2323Lstring *Lstring::ctor(const dchar *p, unsigned length) 
    2424{ 
    2525    Lstring *s; 
    2626 
    2727    s = alloc(length); 
    2828    memcpy(s->string, p, length * sizeof(dchar)); 
    2929    return s; 
    3030} 
    3131 
    3232Lstring *Lstring::alloc(unsigned length) 
    3333{ 
    3434    Lstring *s; 
  • trunk/src/root/rmem.c

    r182 r183  
    11 
    22/* Copyright (c) 2000 Digital Mars  */ 
    33/* All Rights Reserved          */ 
    44 
    55#include <stdio.h> 
    66#include <stdlib.h> 
    77#include <string.h> 
    88 
    99#if linux || __APPLE__ || __FreeBSD__ 
    10 #include "../root/mem.h" 
     10#include "../root/rmem.h" 
    1111#else 
    12 #include "mem.h" 
     12#include "rmem.h" 
    1313#endif 
    1414 
    1515/* This implementation of the storage allocator uses the standard C allocation package. 
    1616 */ 
    1717 
    1818Mem mem; 
    1919 
    2020void Mem::init() 
    2121{ 
    2222} 
    2323 
    2424char *Mem::strdup(const char *s) 
    2525{ 
    2626    char *p; 
    2727 
    2828    if (s) 
    2929    { 
    3030    p = ::strdup(s); 
    3131    if (p) 
    3232        return p; 
  • trunk/src/root/root.c

    r182 r183  
    1919#include <string> 
    2020#endif 
    2121 
    2222#if _WIN32 
    2323#include <windows.h> 
    2424#include <direct.h> 
    2525#endif 
    2626 
    2727#if linux || __APPLE__ || __FreeBSD__ 
    2828#include <sys/types.h> 
    2929#include <sys/stat.h> 
    3030#include <fcntl.h> 
    3131#include <errno.h> 
    3232#include <unistd.h> 
    3333#include <utime.h> 
    3434#endif 
    3535 
    3636#include "port.h" 
    3737#include "root.h" 
    3838#include "dchar.h" 
    39 #include "mem.h" 
     39#include "rmem.h" 
    4040 
    4141#if 0 //__SC__ //def DEBUG 
    4242extern "C" void __cdecl _assert(void *e, void *f, unsigned line) 
    4343{ 
    4444    printf("Assert('%s','%s',%d)\n",e,f,line); 
    4545    fflush(stdout); 
    4646    *(char *)0 = 0; 
    4747} 
    4848#endif 
    4949 
    5050 
    5151/************************************* 
    5252 * Convert wchar string to ascii string. 
    5353 */ 
    5454 
    5555char *wchar2ascii(wchar_t *us) 
    5656{ 
    5757    return wchar2ascii(us, wcslen(us)); 
    5858} 
    5959 
  • trunk/src/root/stringtable.c

    r172 r183  
    11 
    22// Copyright (c) 1999-2008 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010 
    1111#include <stdio.h> 
    1212#include <string.h> 
    1313#include <stdlib.h> 
    1414 
    1515#include "root.h" 
    16 #include "mem.h" 
     16#include "rmem.h" 
    1717#include "dchar.h" 
    1818#include "lstring.h" 
    1919#include "stringtable.h" 
    2020 
    2121StringTable::StringTable(unsigned size) 
    2222{ 
    2323    table = (void **)mem.calloc(size, sizeof(void *)); 
    2424    tabledim = size; 
    2525    count = 0; 
    2626} 
    2727 
    2828StringTable::~StringTable() 
    2929{ 
    3030    unsigned i; 
    3131 
    3232    // Zero out dangling pointers to help garbage collector. 
    3333    // Should zero out StringEntry's too. 
    3434    for (i = 0; i < count; i++) 
    3535    table[i] = NULL; 
    3636 
  • trunk/src/scope.c

    r169 r183  
    236236    } 
    237237    return NULL; 
    238238    } 
    239239 
    240240    for (sc = this; sc; sc = sc->enclosing) 
    241241    { 
    242242    assert(sc != sc->enclosing); 
    243243    if (sc->scopesym) 
    244244    { 
    245245        //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind()); 
    246246        s = sc->scopesym->search(loc, ident, 0); 
    247247        if (s) 
    248248        { 
    249249        if ((global.params.warnings || 
    250250            global.params.Dversion > 1) && 
    251251            ident == Id::length && 
    252252            sc->scopesym->isArrayScopeSymbol() && 
    253253            sc->enclosing && 
    254254            sc->enclosing->search(loc, ident, NULL)) 
    255255        { 
    256             if (global.params.warnings) 
    257             fprintf(stdmsg, "warning - "); 
    258             error(s->loc, "array 'length' hides other 'length' name in outer scope"); 
     256            warning(s->loc, "array 'length' hides other 'length' name in outer scope"); 
    259257        } 
    260258 
    261259        //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind()); 
    262260        if (pscopesym) 
    263261            *pscopesym = sc->scopesym; 
    264262        return s; 
    265263        } 
    266264    } 
    267265    } 
    268266 
    269267    return NULL; 
    270268} 
    271269 
    272270Dsymbol *Scope::insert(Dsymbol *s) 
    273271{   Scope *sc; 
    274272 
    275273    for (sc = this; sc; sc = sc->enclosing) 
    276274    { 
    277275    //printf("\tsc = %p\n", sc); 
    278276    if (sc->scopesym) 
  • trunk/src/statement.c

    r182 r183  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    15 #include "mem.h" 
     15#include "rmem.h" 
    1616 
    1717#include "statement.h" 
    1818#include "expression.h" 
    1919#include "cond.h" 
    2020#include "init.h" 
    2121#include "staticassert.h" 
    2222#include "mtype.h" 
    2323#include "scope.h" 
    2424#include "declaration.h" 
    2525#include "aggregate.h" 
    2626#include "id.h" 
    2727#include "hdrgen.h" 
    2828#include "parse.h" 
    2929#include "template.h" 
    3030 
    3131/******************************** Statement ***************************/ 
    3232 
    3333Statement::Statement(Loc loc) 
    3434    : loc(loc) 
    3535{ 
     
    7777Statement *Statement::semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue) 
    7878{   Scope *scd; 
    7979    Statement *s; 
    8080 
    8181    scd = sc->push(); 
    8282    if (sbreak) 
    8383    scd->sbreak = sbreak; 
    8484    if (scontinue) 
    8585    scd->scontinue = scontinue; 
    8686    s = semantic(scd); 
    8787    scd->pop(); 
    8888    return s; 
    8989} 
    9090 
    9191void Statement::error(const char *format, ...) 
    9292{ 
    9393    va_list ap; 
    9494    va_start(ap, format); 
    9595    ::verror(loc, format, ap); 
    9696    va_end( ap ); 
     97} 
     98 
     99void Statement::warning(const char *format, ...) 
     100{ 
     101    if (global.params.warnings && !global.gag) 
     102    { 
     103    fprintf(stdmsg, "warning - "); 
     104    va_list ap; 
     105    va_start(ap, format); 
     106    ::verror(loc, format, ap); 
     107    va_end( ap ); 
     108    } 
    97109} 
    98110 
    99111int Statement::hasBreak() 
    100112{ 
    101113    //printf("Statement::hasBreak()\n"); 
    102114    return FALSE; 
    103115} 
    104116 
    105117int Statement::hasContinue() 
    106118{ 
    107119    return FALSE; 
    108120} 
    109121 
    110122// TRUE if statement uses exception handling 
    111123 
    112124int Statement::usesEH() 
    113125{ 
    114126    return FALSE; 
    115127} 
    116128 
     
    526538    for (int i = 0; i < statements->dim; i++) 
    527539    {   Statement *s = (Statement *) statements->data[i]; 
    528540    if (s && s->usesEH()) 
    529541        return TRUE; 
    530542    } 
    531543    return FALSE; 
    532544} 
    533545 
    534546int CompoundStatement::blockExit() 
    535547{ 
    536548    //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); 
    537549    int result = BEfallthru; 
    538550    for (size_t i = 0; i < statements->dim; i++) 
    539551    {   Statement *s = (Statement *) statements->data[i]; 
    540552    if (s) 
    541553    { 
    542554//printf("result = x%x\n", result); 
    543555//printf("%s\n", s->toChars()); 
    544556        if (!(result & BEfallthru) && !s->comeFrom()) 
    545557        { 
    546         if (global.params.warnings) 
    547         {   fprintf(stdmsg, "warning - "); 
    548             s->error("statement is not reachable"); 
    549         } 
     558        s->warning("statement is not reachable"); 
    550559        } 
    551560 
    552561        result &= ~BEfallthru; 
    553562        result |= s->blockExit(); 
    554563    } 
    555564    } 
    556565    return result; 
    557566} 
    558567 
    559568 
    560569int CompoundStatement::comeFrom() 
    561570{   int comefrom = FALSE; 
    562571 
    563572    //printf("CompoundStatement::comeFrom()\n"); 
    564573    for (int i = 0; i < statements->dim; i++) 
    565574    {   Statement *s = (Statement *)statements->data[i]; 
    566575 
    567576    if (!s) 
    568577        continue; 
    569578 
     
    10731082{ 
    10741083    return (init && init->usesEH()) || body->usesEH(); 
    10751084} 
    10761085 
    10771086int ForStatement::blockExit() 
    10781087{   int result = BEfallthru; 
    10791088 
    10801089    if (init) 
    10811090    {   result = init->blockExit(); 
    10821091    if (!(result & BEfallthru)) 
    10831092        return result; 
    10841093    } 
    10851094    if (condition) 
    10861095    {   if (condition->canThrow()) 
    10871096        result |= BEthrow; 
    10881097    } 
    10891098    else 
    10901099    result &= ~BEfallthru;  // the body must do the exiting 
    10911100    if (body) 
    10921101    {   int r = body->blockExit(); 
    1093     if (r & BEbreak
     1102    if (r & (BEbreak | BEgoto)
    10941103        result |= BEfallthru; 
    1095     result |= r & ~(BEbreak | BEcontinue); 
     1104    result |= r & ~(BEfallthru | BEbreak | BEcontinue); 
    10961105    } 
    10971106    if (increment && increment->canThrow()) 
    10981107    result |= BEthrow; 
    10991108    return result; 
    11001109} 
    11011110 
    11021111 
    11031112int ForStatement::comeFrom() 
    11041113{ 
    11051114    //printf("ForStatement::comeFrom()\n"); 
    11061115    if (body) 
    11071116    {   int result = body->comeFrom(); 
    11081117    //printf("result = %d\n", result); 
    11091118    return result; 
    11101119    } 
    11111120    return FALSE; 
    11121121} 
    11131122 
    11141123void ForStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    11151124{ 
     
    14351444            ? (AggregateDeclaration *)((TypeClass  *)tab)->sym 
    14361445            : (AggregateDeclaration *)((TypeStruct *)tab)->sym; 
    14371446        Identifier *idhead; 
    14381447        Identifier *idnext; 
    14391448        if (op == TOKforeach) 
    14401449        {   idhead = Id::Fhead; 
    14411450        idnext = Id::Fnext; 
    14421451        } 
    14431452        else 
    14441453        {   idhead = Id::Ftoe; 
    14451454        idnext = Id::Fretreat; 
    14461455        } 
    14471456        Dsymbol *shead = search_function(ad, idhead); 
    14481457        if (!shead) 
    14491458        goto Lapply; 
    14501459 
    14511460        /* Generate a temporary __r and initialize it with the aggregate. 
    14521461         */ 
    14531462        Identifier *id = Identifier::generateId("__r"); 
    14541463        VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr)); 
    1455         r->semantic(sc); 
     1464//      r->semantic(sc); 
     1465//printf("r: %s, init: %s\n", r->toChars(), r->init->toChars()); 
    14561466        Statement *init = new DeclarationStatement(loc, r); 
     1467//printf("init: %s\n", init->toChars()); 
    14571468 
    14581469        // !__r.empty 
    14591470        Expression *e = new VarExp(loc, r); 
    14601471        e = new DotIdExp(loc, e, Id::Fempty); 
    14611472        Expression *condition = new NotExp(loc, e); 
    14621473 
    14631474        // __r.next 
    14641475        e = new VarExp(loc, r); 
    14651476        Expression *increment = new DotIdExp(loc, e, idnext); 
    14661477 
    14671478        /* Declaration statement for e: 
    14681479         *    auto e = __r.idhead; 
    14691480         */ 
    14701481        e = new VarExp(loc, r); 
    14711482        Expression *einit = new DotIdExp(loc, e, idhead); 
    1472       einit = einit->semantic(sc); 
     1483//        einit = einit->semantic(sc); 
    14731484        Argument *arg = (Argument *)arguments->data[0]; 
    14741485        VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); 
    14751486        ve->storage_class |= STCforeach; 
    14761487        ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant); 
    14771488 
    14781489        DeclarationExp *de = new DeclarationExp(loc, ve); 
    14791490 
    14801491        Statement *body = new CompoundStatement(loc, 
    14811492        new DeclarationStatement(loc, de), this->body); 
    14821493 
    14831494        s = new ForStatement(loc, init, condition, increment, body); 
    14841495        s = s->semantic(sc); 
    14851496        break; 
    14861497    } 
    14871498#endif 
    14881499    case Tdelegate: 
    14891500    Lapply: 
    14901501    {   FuncDeclaration *fdapply; 
    14911502        Arguments *args; 
    14921503        Expression *ec; 
     
    24382449        for (int j = 0; j < scx->sw->cases->dim; j++) 
    24392450        { 
    24402451        CaseStatement *cs = (CaseStatement *)scx->sw->cases->data[j]; 
    24412452 
    24422453        if (cs->exp->equals(gcs->exp)) 
    24432454        { 
    24442455            gcs->cs = cs; 
    24452456            goto Lfoundcase; 
    24462457        } 
    24472458        } 
    24482459    } 
    24492460    gcs->error("case %s not found", gcs->exp->toChars()); 
    24502461 
    24512462     Lfoundcase: 
    24522463    ; 
    24532464    } 
    24542465 
    24552466    if (!sc->sw->sdefault) 
    24562467    {   hasNoDefault = 1; 
    24572468 
    2458     if (global.params.warnings) 
    2459     {   fprintf(stdmsg, "warning - "); 
    2460         error("switch statement has no default"); 
    2461     } 
     2469    warning("switch statement has no default"); 
    24622470 
    24632471    // Generate runtime error if the default is hit 
    24642472    Statements *a = new Statements(); 
    24652473    CompoundStatement *cs; 
    24662474    Statement *s; 
    24672475 
    24682476    if (global.params.useSwitchError) 
    24692477        s = new SwitchErrorStatement(loc); 
    24702478    else 
    24712479    {   Expression *e = new HaltExp(loc); 
    24722480        s = new ExpStatement(loc, e); 
    24732481    } 
    24742482 
    24752483    a->reserve(4); 
    24762484    a->push(body); 
    24772485    a->push(new BreakStatement(loc, NULL)); 
    24782486    sc->sw->sdefault = new DefaultStatement(loc, s); 
    24792487    a->push(sc->sw->sdefault); 
    24802488    cs = new CompoundStatement(loc, a); 
    24812489    body = cs; 
  • trunk/src/statement.h

    r180 r183  
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#ifndef DMD_STATEMENT_H 
    1212#define DMD_STATEMENT_H 
    1313 
    1414#ifdef __DMC__ 
    1515#pragma once 
    1616#endif /* __DMC__ */ 
    1717 
    1818#include "root.h" 
    1919 
    2020#include "arraytypes.h" 
    2121#include "dsymbol.h" 
     22#include "lexer.h" 
    2223 
    2324struct OutBuffer; 
    2425struct Scope; 
    2526struct Expression; 
    2627struct LabelDsymbol; 
    2728struct Identifier; 
    2829struct IfStatement; 
    2930struct DeclarationStatement; 
    3031struct DefaultStatement; 
    3132struct VarDeclaration; 
    3233struct Condition; 
    3334struct Module; 
    3435struct Token; 
    3536struct InlineCostState; 
    3637struct InlineDoState; 
    3738struct InlineScanState; 
    3839struct ReturnStatement; 
    3940struct CompoundStatement; 
    4041struct Argument; 
    4142struct StaticAssert; 
     
    7071    BEthrow =    2, 
    7172    BEreturn =   4, 
    7273    BEgoto =     8, 
    7374    BEhalt =     0x10, 
    7475    BEbreak =    0x20, 
    7576    BEcontinue = 0x40, 
    7677    BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt), 
    7778}; 
    7879 
    7980struct Statement : Object 
    8081{ 
    8182    Loc loc; 
    8283 
    8384    Statement(Loc loc); 
    8485    virtual Statement *syntaxCopy(); 
    8586 
    8687    void print(); 
    8788    char *toChars(); 
    8889 
    8990    void error(const char *format, ...); 
     91    void warning(const char *format, ...); 
    9092    virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    9193    virtual TryCatchStatement *isTryCatchStatement() { return NULL; } 
    9294    virtual GotoStatement *isGotoStatement() { return NULL; } 
    9395    virtual AsmStatement *isAsmStatement() { return NULL; } 
    9496#ifdef _DH 
    9597    int incontract; 
    9698#endif 
    9799    virtual ScopeStatement *isScopeStatement() { return NULL; } 
    98100    virtual Statement *semantic(Scope *sc); 
    99101    Statement *semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue); 
    100102    virtual int hasBreak(); 
    101103    virtual int hasContinue(); 
    102104    virtual int usesEH(); 
    103105    virtual int blockExit(); 
    104106    virtual int comeFrom(); 
    105107    virtual void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); 
    106108    virtual Statements *flatten(Scope *sc); 
    107109    virtual Expression *interpret(InterState *istate); 
    108110 
    109111    virtual int inlineCost(InlineCostState *ics); 
  • trunk/src/struct.c

    r182 r183  
    22// Compiler implementation of the D programming language 
    33// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <assert.h> 
    1313 
    1414#include "root.h" 
    1515#include "aggregate.h" 
    1616#include "scope.h" 
    1717#include "mtype.h" 
    1818#include "declaration.h" 
    1919#include "module.h" 
    2020#include "id.h" 
    2121#include "statement.h" 
     22#include "template.h" 
    2223 
    2324/********************************* AggregateDeclaration ****************************/ 
    2425 
    2526AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) 
    2627    : ScopeDsymbol(id) 
    2728{ 
    2829    this->loc = loc; 
    2930 
    3031    storage_class = 0; 
    3132    protection = PROTpublic; 
    3233    type = NULL; 
    3334    handle = NULL; 
    3435    structsize = 0;     // size of struct 
    3536    alignsize = 0;      // size of struct for alignment purposes 
    3637    structalign = 0;        // struct member alignment in effect 
    3738    hasUnions = 0; 
    3839    sizeok = 0;         // size not determined yet 
    3940    isdeprecated = 0; 
    4041    inv = NULL; 
    4142    aggNew = NULL; 
    4243    aggDelete = NULL; 
    4344 
    4445    stag = NULL; 
    4546    sinit = NULL; 
    4647    scope = NULL; 
     48    isnested = 0; 
     49    vthis = NULL; 
     50 
    4751#if V2 
    48     dtor = NULL; 
    49  
    5052    ctor = NULL; 
    5153    defaultCtor = NULL; 
    5254#endif 
     55    dtor = NULL; 
    5356} 
    5457 
    5558enum PROT AggregateDeclaration::prot() 
    5659{ 
    5760    return protection; 
    5861} 
    5962 
    6063void AggregateDeclaration::semantic2(Scope *sc) 
    6164{ 
    6265    //printf("AggregateDeclaration::semantic2(%s)\n", toChars()); 
    6366    if (scope) 
    6467    {   error("has forward references"); 
    6568    return; 
    6669    } 
    6770    if (members) 
    6871    { 
    6972    sc = sc->push(this); 
    7073    for (size_t i = 0; i < members->dim; i++) 
    7174    { 
    7275        Dsymbol *s = (Dsymbol *)members->data[i]; 
     
    146149    int sa = size; 
    147150    if (sa == 0 || salign < sa) 
    148151        sa = salign; 
    149152    *poffset = (*poffset + sa - 1) & ~(sa - 1); 
    150153    } 
    151154    //printf("result = %d\n",offset); 
    152155} 
    153156 
    154157 
    155158void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) 
    156159{ 
    157160    unsigned memsize;       // size of member 
    158161    unsigned memalignsize;  // size of member for alignment purposes 
    159162    unsigned xalign;        // alignment boundaries 
    160163 
    161164    //printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars()); 
    162165    assert(!(v->storage_class & (STCstatic | STCextern | STCparameter | STCtls))); 
    163166 
    164167    // Check for forward referenced types which will fail the size() call 
    165168    Type *t = v->type->toBasetype(); 
     169    if (v->storage_class & STCref) 
     170    {   // References are the size of a pointer 
     171    t = Type::tvoidptr; 
     172    } 
    166173    if (t->ty == Tstruct /*&& isStructDeclaration()*/) 
    167174    {   TypeStruct *ts = (TypeStruct *)t; 
    168175#if V2 
    169176    if (ts->sym == this) 
    170177    { 
    171178        error("cannot have field %s with same struct type", v->toChars()); 
    172179    } 
    173180#endif 
    174181 
    175182    if (ts->sym->sizeok != 1) 
    176183    { 
    177184        sizeok = 2;     // cannot finish; flag as forward referenced 
    178185        return; 
    179186    } 
    180187    } 
    181188    if (t->ty == Tident) 
    182189    { 
    183190    sizeok = 2;     // cannot finish; flag as forward referenced 
    184191    return; 
    185192    } 
    186193 
    187     memsize = v->type->size(loc); 
    188     memalignsize = v->type->alignsize(); 
    189     xalign = v->type->memalign(sc->structalign); 
     194    memsize = t->size(loc); 
     195    memalignsize = t->alignsize(); 
     196    xalign = t->memalign(sc->structalign); 
    190197    alignmember(xalign, memalignsize, &sc->offset); 
    191198    v->offset = sc->offset; 
    192199    sc->offset += memsize; 
    193200    if (sc->offset > structsize) 
    194201    structsize = sc->offset; 
    195202    if (sc->structalign < memalignsize) 
    196203    memalignsize = sc->structalign; 
    197204    if (alignsize < memalignsize) 
    198205    alignsize = memalignsize; 
    199206    //printf("\talignsize = %d\n", alignsize); 
    200207 
    201208    v->storage_class |= STCfield; 
    202209    //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize); 
    203210    fields.push(v); 
     211} 
     212 
     213 
     214/**************************************** 
     215 * Returns !=0 if there's an extra member which is the 'this' 
     216 * pointer to the enclosing context (enclosing aggregate or function) 
     217 */ 
     218 
     219int AggregateDeclaration::isNested() 
     220{ 
     221    return isnested; 
    204222} 
    205223 
    206224 
    207225/********************************* StructDeclaration ****************************/ 
    208226 
    209227StructDeclaration::StructDeclaration(Loc loc, Identifier *id) 
    210228    : AggregateDeclaration(loc, id) 
    211229{ 
    212230    zeroInit = 0;   // assume false until we do semantic processing 
    213231#if V2 
    214232    hasIdentityAssign = 0; 
    215233    cpctor = NULL; 
    216234    postblit = NULL; 
    217235#endif 
    218236 
    219237    // For forward references 
    220238    type = new TypeStruct(this); 
    221239} 
    222240 
    223241Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s) 
     
    264282#else 
    265283    handle = type->pointerTo(); 
    266284#endif 
    267285    structalign = sc->structalign; 
    268286    protection = sc->protection; 
    269287    storage_class |= sc->stc; 
    270288    if (sc->stc & STCdeprecated) 
    271289    isdeprecated = 1; 
    272290    assert(!isAnonymous()); 
    273291    if (sc->stc & STCabstract) 
    274292    error("structs, unions cannot be abstract"); 
    275293#if V2 
    276294    if (storage_class & STCinvariant) 
    277295        type = type->invariantOf(); 
    278296    else if (storage_class & STCconst) 
    279297        type = type->constOf(); 
    280298#endif 
    281299 
    282300    if (sizeok == 0)        // if not already done the addMember step 
    283301    { 
     302    int hasfunctions = 0; 
    284303    for (i = 0; i < members->dim; i++) 
    285304    { 
    286305        Dsymbol *s = (Dsymbol *)members->data[i]; 
    287306        //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); 
    288307        s->addMember(sc, this, 1); 
    289     } 
     308        if (s->isFuncDeclaration()) 
     309        hasfunctions = 1; 
     310    } 
     311 
     312    // If nested struct, add in hidden 'this' pointer to outer scope 
     313    if (hasfunctions && !(storage_class & STCstatic)) 
     314        {   Dsymbol *s = toParent2(); 
     315            if (s) 
     316            { 
     317                AggregateDeclaration *ad = s->isAggregateDeclaration(); 
     318                FuncDeclaration *fd = s->isFuncDeclaration(); 
     319 
     320        TemplateInstance *ti; 
     321                if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd) 
     322                {   isnested = 1; 
     323                    Type *t; 
     324                    if (ad) 
     325                        t = ad->handle; 
     326                    else if (fd) 
     327                    {   AggregateDeclaration *ad = fd->isMember2(); 
     328                        if (ad) 
     329                            t = ad->handle; 
     330                        else 
     331                t = Type::tvoidptr; 
     332                    } 
     333                    else 
     334                        assert(0); 
     335            if (t->ty == Tstruct) 
     336            t = Type::tvoidptr; // t should not be a ref type 
     337                    assert(!vthis); 
     338                    vthis = new ThisDeclaration(t); 
     339            //vthis->storage_class |= STCref; 
     340                    members->push(vthis); 
     341                } 
     342            } 
     343        } 
    290344    } 
    291345 
    292346    sizeok = 0; 
    293347    sc2 = sc->push(this); 
    294348    sc2->stc &= storage_class & (STCconst | STCinvariant); 
    295349    sc2->parent = this; 
    296350    if (isUnionDeclaration()) 
    297351    sc2->inunion = 1; 
    298352    sc2->protection = PROTpublic; 
    299353    sc2->explicitProtection = 0; 
    300354 
    301355    int members_dim = members->dim; 
    302356    for (i = 0; i < members_dim; i++) 
    303357    { 
    304358    Dsymbol *s = (Dsymbol *)members->data[i]; 
    305359    s->semantic(sc2); 
    306360    if (isUnionDeclaration()) 
    307361        sc2->offset = 0; 
    308362#if 0 
    309363    if (sizeok == 2) 
    310364    {   //printf("forward reference\n"); 
    311365        break; 
    312366    } 
    313367#endif 
     368    Type *t; 
     369    if (s->isDeclaration() && 
     370        (t = s->isDeclaration()->type) != NULL && 
     371        t->toBasetype()->ty == Tstruct) 
     372    {   StructDeclaration *sd = (StructDeclaration *)t->toDsymbol(sc); 
     373        if (sd->isnested) 
     374        error("inner struct %s cannot be a field", sd->toChars()); 
     375    } 
    314376    } 
    315377 
    316378    /* The TypeInfo_Struct is expecting an opEquals and opCmp with 
    317379     * a parameter that is a pointer to the struct. But if there 
    318380     * isn't one, but is an opEquals or opCmp with a value, write 
    319381     * another that is a shell around the value: 
    320382     *  int opCmp(struct *p) { return opCmp(*p); } 
    321383     */ 
    322384 
    323385    TypeFunction *tfeqptr; 
    324386    { 
    325387    Arguments *arguments = new Arguments; 
    326388    Argument *arg = new Argument(STCin, handle, Id::p, NULL); 
    327389 
    328390    arguments->push(arg); 
    329391    tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); 
    330392    tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc); 
    331393    } 
    332394 
    333395    TypeFunction *tfeq; 
  • trunk/src/template.c

    r181 r183  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111// Handle template implementation 
    1212 
    1313#include <stdio.h> 
    1414#include <assert.h> 
    1515 
    1616#include "root.h" 
    17 #include "mem.h" 
     17#include "rmem.h" 
    1818#include "stringtable.h" 
    1919 
    2020#include "mtype.h" 
    2121#include "template.h" 
    2222#include "init.h" 
    2323#include "expression.h" 
    2424#include "scope.h" 
    2525#include "module.h" 
    2626#include "aggregate.h" 
    2727#include "declaration.h" 
    2828#include "dsymbol.h" 
    2929#include "mars.h" 
    3030#include "dsymbol.h" 
    3131#include "identifier.h" 
    3232#include "hdrgen.h" 
    3333 
    3434#if WINDOWS_SEH 
    3535#include <windows.h> 
    3636long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); 
    3737#endif 
     
    169169    { 
    170170        printf("match %d\n", e1->equals(e2)); 
    171171        e1->print(); 
    172172        e2->print(); 
    173173        e1->type->print(); 
    174174        e2->type->print(); 
    175175    } 
    176176#endif 
    177177    if (!e2) 
    178178        goto Lnomatch; 
    179179    if (!e1->equals(e2)) 
    180180        goto Lnomatch; 
    181181    } 
    182182    else if (s1) 
    183183    { 
    184184    //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); 
    185185    if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) 
    186186    { 
    187187        goto Lnomatch; 
    188188    } 
     189#if V2 
    189190    VarDeclaration *v1 = s1->isVarDeclaration(); 
    190191    VarDeclaration *v2 = s2->isVarDeclaration(); 
    191192    if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) 
    192193    {   ExpInitializer *ei1 = v1->init->isExpInitializer(); 
    193194        ExpInitializer *ei2 = v2->init->isExpInitializer(); 
    194195        if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) 
    195196        goto Lnomatch; 
    196197    } 
     198#endif 
    197199    } 
    198200    else if (v1) 
    199201    { 
    200202    if (!v2) 
    201203        goto Lnomatch; 
    202204    if (v1->objects.dim != v2->objects.dim) 
    203205        goto Lnomatch; 
    204206    for (size_t i = 0; i < v1->objects.dim; i++) 
    205207    { 
    206208        if (!match((Object *)v1->objects.data[i], 
    207209               (Object *)v2->objects.data[i], 
    208210               tempdecl, sc)) 
    209211        goto Lnomatch; 
    210212    } 
    211213    } 
    212214    //printf("match\n"); 
    213215    return 1;   // match 
    214216Lnomatch: 
    215217    //printf("nomatch\n"); 
    216218    return 0;   // nomatch; 
     
    244246    { 
    245247        if (i) 
    246248        buf->writeByte(','); 
    247249        Object *o = (Object *)args->data[i]; 
    248250        ObjectToCBuffer(buf, hgs, o); 
    249251    } 
    250252    } 
    251253    else if (!oarg) 
    252254    { 
    253255    buf->writestring("NULL"); 
    254256    } 
    255257    else 
    256258    { 
    257259#ifdef DEBUG 
    258260    printf("bad Object = %p\n", oarg); 
    259261#endif 
    260262    assert(0); 
    261263    } 
    262264} 
    263265 
     266#if V2 
    264267Object *objectSyntaxCopy(Object *o) 
    265268{ 
    266269    if (!o) 
    267270    return NULL; 
    268271    Type *t = isType(o); 
    269272    if (t) 
    270273    return t->syntaxCopy(); 
    271274    Expression *e = isExpression(o); 
    272275    if (e) 
    273276    return e->syntaxCopy(); 
    274277    return o; 
    275278} 
     279#endif 
    276280 
    277281 
    278282/* ======================== TemplateDeclaration ============================= */ 
    279283 
    280284TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, 
    281285    TemplateParameters *parameters, Expression *constraint, Array *decldefs) 
    282286    : ScopeDsymbol(id) 
    283287{ 
    284288#if LOG 
    285289    printf("TemplateDeclaration(this = %p, id = '%s')\n", this, id->toChars()); 
    286290#endif 
    287291#if 0 
    288292    if (parameters) 
    289293    for (int i = 0; i < parameters->dim; i++) 
    290294    {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    291295        //printf("\tparameter[%d] = %p\n", i, tp); 
    292296        TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); 
    293297 
    294298        if (ttp) 
    295299        { 
    296300        printf("\tparameter[%d] = %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); 
    297301        } 
    298302    } 
    299303#endif 
    300304    this->loc = loc; 
    301305    this->parameters = parameters; 
    302306    this->origParameters = parameters; 
     307#if V2 
    303308    this->constraint = constraint; 
     309#endif 
    304310    this->members = decldefs; 
    305311    this->overnext = NULL; 
    306312    this->overroot = NULL; 
    307313    this->scope = NULL; 
    308314    this->onemember = NULL; 
    309315} 
    310316 
    311317Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) 
    312318{ 
    313319    //printf("TemplateDeclaration::syntaxCopy()\n"); 
    314320    TemplateDeclaration *td; 
    315321    TemplateParameters *p; 
    316322    Array *d; 
    317323 
    318324    p = NULL; 
    319325    if (parameters) 
    320326    { 
    321327    p = new TemplateParameters(); 
    322328    p->setDim(parameters->dim); 
    323329    for (int i = 0; i < p->dim; i++) 
    324330    {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    325331        p->data[i] = (void *)tp->syntaxCopy(); 
    326332    } 
    327333    } 
     334#if V2 
    328335    Expression *e = NULL; 
    329336    if (constraint) 
    330337    e = constraint->syntaxCopy(); 
     338#endif 
    331339    d = Dsymbol::arraySyntaxCopy(members); 
    332340    td = new TemplateDeclaration(loc, ident, p, e, d); 
    333341    return td; 
    334342} 
    335343 
    336344void TemplateDeclaration::semantic(Scope *sc) 
    337345{ 
    338346#if LOG 
    339347    printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); 
    340348#endif 
    341349    if (scope) 
    342350    return;     // semantic() already run 
    343351 
    344352    if (sc->func) 
    345353    { 
    346354#if V1 
    347355    error("cannot declare template at function scope %s", sc->func->toChars()); 
    348356#endif 
    349357    } 
    350358 
     
    356364    } 
    357365 
    358366    if (/*global.params.useAssert &&*/ sc->module) 
    359367    { 
    360368    // Generate this function as it may be used 
    361369    // when template is instantiated in other modules 
    362370    sc->module->toModuleAssert(); 
    363371    } 
    364372 
    365373    /* Remember Scope for later instantiations, but make 
    366374     * a copy since attributes can change. 
    367375     */ 
    368376    this->scope = new Scope(*sc); 
    369377    this->scope->setNoFree(); 
    370378 
    371379    // Set up scope for parameters 
    372380    ScopeDsymbol *paramsym = new ScopeDsymbol(); 
    373381    paramsym->parent = sc->parent; 
    374382    Scope *paramscope = sc->push(paramsym); 
    375383    paramscope->parameterSpecialization = 1; 
     384    paramscope->stc = 0; 
    376385 
    377386    if (global.params.doDocComments) 
    378387    { 
    379388    origParameters = new TemplateParameters(); 
    380389    origParameters->setDim(parameters->dim); 
    381390    for (int i = 0; i < parameters->dim; i++) 
    382391    { 
    383392        TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    384393        origParameters->data[i] = (void *)tp->syntaxCopy(); 
    385394    } 
    386395    } 
    387396 
    388397    for (int i = 0; i < parameters->dim; i++) 
    389398    { 
    390399    TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    391400 
    392401    tp->declareParameter(paramscope); 
    393402    } 
    394403 
    395404    for (int i = 0; i < parameters->dim; i++) 
     
    516525    int parameters_dim = parameters->dim; 
    517526    int variadic = isVariadic() != NULL; 
    518527 
    519528    // If more arguments than parameters, no match 
    520529    if (ti->tiargs->dim > parameters_dim && !variadic) 
    521530    { 
    522531#if LOGM 
    523532    printf(" no match: more arguments than parameters\n"); 
    524533#endif 
    525534    return MATCHnomatch; 
    526535    } 
    527536 
    528537    assert(dedtypes_dim == parameters_dim); 
    529538    assert(dedtypes_dim >= ti->tiargs->dim || variadic); 
    530539 
    531540    // Set up scope for parameters 
    532541    assert((size_t)scope > 0x10000); 
    533542    ScopeDsymbol *paramsym = new ScopeDsymbol(); 
    534543    paramsym->parent = scope->parent; 
    535544    Scope *paramscope = scope->push(paramsym); 
     545    paramscope->stc = 0; 
    536546 
    537547    // Attempt type deduction 
    538548    m = MATCHexact; 
    539549    for (int i = 0; i < dedtypes_dim; i++) 
    540550    {   MATCH m2; 
    541551    TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    542552    Declaration *sparam; 
    543553 
    544554    //printf("\targument [%d]\n", i); 
    545555#if LOGM 
    546556    //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null"); 
    547557    TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); 
    548558    if (ttp) 
    549559        printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); 
    550560#endif 
    551561 
    552562#if V1 
    553563    m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); 
    554564#else 
    555565    m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam, (flag & 2) ? 1 : 0); 
     
    805815 
    806816    assert(fd->type->ty == Tfunction); 
    807817    fdtype = (TypeFunction *)fd->type; 
    808818 
    809819    nfparams = Argument::dim(fdtype->parameters); // number of function parameters 
    810820    nfargs = fargs->dim;        // number of function arguments 
    811821 
    812822    /* Check for match of function arguments with variadic template 
    813823     * parameter, such as: 
    814824     * 
    815825     * template Foo(T, A...) { void Foo(T t, A a); } 
    816826     * void main() { Foo(1,2,3); } 
    817827     */ 
    818828    if (tp)             // if variadic 
    819829    { 
    820830    if (nfparams == 0)      // if no function parameters 
    821831    { 
    822832        Tuple *t = new Tuple(); 
    823833        //printf("t = %p\n", t); 
    824834        dedargs->data[parameters->dim - 1] = (void *)t; 
     835        declareParameter(paramscope, tp, t); 
    825836        goto L2; 
    826837    } 
    827838    else if (nfargs < nfparams - 1) 
    828839        goto L1; 
    829840    else 
    830841    { 
    831842        /* Figure out which of the function parameters matches 
    832843         * the tuple template parameter. Do this by matching 
    833844         * type identifiers. 
    834845         * Set the index of this function parameter to fptupindex. 
    835846         */ 
    836847        for (fptupindex = 0; fptupindex < nfparams; fptupindex++) 
    837848        { 
    838849        Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex]; 
    839850        if (fparam->type->ty != Tident) 
    840851            continue; 
    841852        TypeIdentifier *tid = (TypeIdentifier *)fparam->type; 
    842853        if (!tp->ident->equals(tid->ident) || tid->idents.dim) 
    843854            continue; 
    844855 
    845856        if (fdtype->varargs)    // variadic function doesn't 
    846857            goto Lnomatch;  // go with variadic template 
    847858 
    848859        /* The types of the function arguments 
    849860         * now form the tuple argument. 
    850861         */ 
    851862        Tuple *t = new Tuple(); 
    852863        dedargs->data[parameters->dim - 1] = (void *)t; 
    853864 
    854865        tuple_dim = nfargs - (nfparams - 1); 
    855866        t->objects.setDim(tuple_dim); 
    856867        for (i = 0; i < tuple_dim; i++) 
    857868        {   Expression *farg = (Expression *)fargs->data[fptupindex + i]; 
    858869            t->objects.data[i] = (void *)farg->type; 
    859870        } 
     871        declareParameter(paramscope, tp, t); 
    860872        goto L2; 
    861873        } 
    862874        fptupindex = -1; 
    863875    } 
    864876    } 
    865877 
    866878L1: 
    867879    if (nfparams == nfargs) 
    868880    ; 
    869881    else if (nfargs > nfparams) 
    870882    { 
    871883    if (fdtype->varargs == 0) 
    872884        goto Lnomatch;      // too many args, no match 
    873885    match = MATCHconvert;       // match ... with a conversion 
    874886    } 
    875887 
    876888L2: 
    877889#if V2 
    878890    // Match 'ethis' to any TemplateThisParameter's 
    879891    if (ethis) 
     
    18681880    else if (tempinst->tempdecl != tp->tempinst->tempdecl) 
    18691881        goto Lnomatch; 
    18701882 
    18711883      L2: 
    18721884    if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim) 
    18731885        goto Lnomatch; 
    18741886 
    18751887    for (int i = 0; i < tempinst->tiargs->dim; i++) 
    18761888    { 
    18771889        //printf("\ttest: tempinst->tiargs[%d]\n", i); 
    18781890        int j; 
    18791891        Object *o1 = (Object *)tempinst->tiargs->data[i]; 
    18801892        Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; 
    18811893 
    18821894        Type *t1 = isType(o1); 
    18831895        Type *t2 = isType(o2); 
    18841896 
    18851897        Expression *e1 = isExpression(o1); 
    18861898        Expression *e2 = isExpression(o2); 
    18871899 
     1900        Dsymbol *s1 = isDsymbol(o1); 
     1901        Dsymbol *s2 = isDsymbol(o2); 
     1902 
     1903        Tuple *v1 = isTuple(o1); 
     1904        Tuple *v2 = isTuple(o2); 
    18881905#if 0 
    18891906        if (t1) printf("t1 = %s\n", t1->toChars()); 
    18901907        if (t2) printf("t2 = %s\n", t2->toChars()); 
    18911908        if (e1) printf("e1 = %s\n", e1->toChars()); 
    18921909        if (e2) printf("e2 = %s\n", e2->toChars()); 
     1910        if (s1) printf("s1 = %s\n", s1->toChars()); 
     1911        if (s2) printf("s2 = %s\n", s2->toChars()); 
     1912        if (v1) printf("v1 = %s\n", v1->toChars()); 
     1913        if (v2) printf("v2 = %s\n", v2->toChars()); 
    18931914#endif 
    18941915 
    18951916        if (t1 && t2) 
    18961917        { 
    18971918        if (!t1->deduceType(sc, t2, parameters, dedtypes)) 
    18981919            goto Lnomatch; 
    18991920        } 
    19001921        else if (e1 && e2) 
    19011922        { 
    19021923        if (!e1->equals(e2)) 
    19031924        {   if (e2->op == TOKvar) 
    19041925            { 
    19051926            /* 
    19061927             * (T:Number!(e2), int e2) 
    19071928             */ 
    19081929            j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters); 
    19091930            goto L1; 
    19101931            } 
    19111932            goto Lnomatch; 
    19121933        } 
     
    19191940            goto Lnomatch; 
    19201941        TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; 
    19211942        // BUG: use tp->matchArg() instead of the following 
    19221943        TemplateValueParameter *tv = tp->isTemplateValueParameter(); 
    19231944        if (!tv) 
    19241945            goto Lnomatch; 
    19251946        Expression *e = (Expression *)dedtypes->data[j]; 
    19261947        if (e) 
    19271948        { 
    19281949            if (!e1->equals(e)) 
    19291950            goto Lnomatch; 
    19301951        } 
    19311952        else 
    19321953        {   Type *vt = tv->valType->semantic(0, sc); 
    19331954            MATCH m = (MATCH)e1->implicitConvTo(vt); 
    19341955            if (!m) 
    19351956            goto Lnomatch; 
    19361957            dedtypes->data[j] = e1; 
    19371958        } 
    19381959        } 
    1939         // BUG: Need to handle alias and tuple parameters 
     1960        else if (s1 && t2 && t2->ty == Tident) 
     1961        { 
     1962        j = templateParameterLookup(t2, parameters); 
     1963        if (j == -1) 
     1964            goto Lnomatch; 
     1965        TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; 
     1966        // BUG: use tp->matchArg() instead of the following 
     1967        TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); 
     1968        if (!ta) 
     1969            goto Lnomatch; 
     1970        Dsymbol *s = (Dsymbol *)dedtypes->data[j]; 
     1971        if (s) 
     1972        { 
     1973            if (!s1->equals(s)) 
     1974            goto Lnomatch; 
     1975        } 
     1976        else 
     1977        { 
     1978            dedtypes->data[j] = s1; 
     1979        } 
     1980        } 
     1981        else if (s1 && s2) 
     1982        { 
     1983        if (!s1->equals(s2)) 
     1984            goto Lnomatch; 
     1985        } 
     1986        // BUG: Need to handle tuple parameters 
    19401987        else 
    19411988        goto Lnomatch; 
    19421989    } 
    19431990    } 
    19441991    return Type::deduceType(sc, tparam, parameters, dedtypes); 
    19451992 
    19461993Lnomatch: 
    19471994    return MATCHnomatch; 
    19481995} 
    19491996 
    19501997MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes) 
    19511998{ 
    19521999    //printf("TypeStruct::deduceType()\n"); 
    19532000    //printf("\tthis->parent   = %s, ", sym->parent->toChars()); print(); 
    19542001    //printf("\ttparam = %d, ", tparam->ty); tparam->print(); 
    19552002 
    19562003    /* If this struct is a template struct, and we're matching 
    19572004     * it against a template instance, convert the struct type 
    19582005     * to a template instance, too, and try again. 
    19592006     */ 
     
    25532600    dedtypes->data[i] = sa; 
    25542601 
    25552602    s = isDsymbol(sa); 
    25562603    if (s) 
    25572604    *psparam = new AliasDeclaration(loc, ident, s); 
    25582605    else 
    25592606    { 
    25602607    assert(ea); 
    25612608 
    25622609        // Declare manifest constant 
    25632610        Initializer *init = new ExpInitializer(loc, ea); 
    25642611        VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); 
    25652612        v->storage_class = STCmanifest; 
    25662613        v->semantic(sc); 
    25672614    *psparam = v; 
    25682615    } 
    25692616    return MATCHexact; 
    25702617 
    25712618Lnomatch: 
    25722619    *psparam = NULL; 
     2620    //printf("\tm = %d\n", MATCHnomatch); 
    25732621    return MATCHnomatch; 
    25742622} 
    25752623 
    25762624 
    25772625void TemplateAliasParameter::print(Object *oarg, Object *oded) 
    25782626{ 
    25792627    printf(" %s\n", ident->toChars()); 
    25802628 
    25812629    Dsymbol *sa = isDsymbol(oded); 
    25822630    assert(sa); 
    25832631 
    25842632    printf("\tArgument alias: %s\n", sa->toChars()); 
    25852633} 
    25862634 
    25872635void TemplateAliasParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    25882636{ 
    25892637    buf->writestring("alias "); 
    25902638    if (specType) 
    25912639    {   HdrGenState hgs; 
    25922640    specType->toCBuffer(buf, ident, &hgs); 
     
    31553203        return; 
    31563204    } 
    31573205    } 
    31583206    else 
    31593207    { 
    31603208    /* Run semantic on each argument, place results in tiargs[] 
    31613209     * (if we havetempdecl, then tiargs is already evaluated) 
    31623210     */ 
    31633211    semanticTiargs(sc); 
    31643212 
    31653213    tempdecl = findTemplateDeclaration(sc); 
    31663214    if (tempdecl) 
    31673215        tempdecl = findBestMatch(sc); 
    31683216    if (!tempdecl || global.errors) 
    31693217    {   inst = this; 
    31703218        //printf("error return %p, %d\n", tempdecl, global.errors); 
    31713219        return;     // error recovery 
    31723220    } 
    31733221    } 
    31743222 
    3175     isNested(tiargs); 
     3223    hasNestedArgs(tiargs); 
    31763224 
    31773225    /* See if there is an existing TemplateInstantiation that already 
    31783226     * implements the typeargs. If so, just refer to that one instead. 
    31793227     */ 
    31803228 
    31813229    for (size_t i = 0; i < tempdecl->instances.dim; i++) 
    31823230    { 
    31833231    TemplateInstance *ti = (TemplateInstance *)tempdecl->instances.data[i]; 
    31843232#if LOG 
    31853233    printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti->toChars()); 
    31863234#endif 
    31873235    assert(tdtypes.dim == ti->tdtypes.dim); 
    31883236 
    31893237    // Nesting must match 
    31903238    if (isnested != ti->isnested) 
    31913239        continue; 
    31923240#if 0 
    31933241    if (isnested && sc->parent != ti->parent) 
    31943242        continue; 
    31953243#endif 
     
    32383286    int dosemantic3 = 0; 
    32393287    {   Array *a; 
    32403288 
    32413289    Scope *scx = sc; 
    32423290#if 0 
    32433291    for (scx = sc; scx; scx = scx->enclosing) 
    32443292        if (scx->scopesym) 
    32453293        break; 
    32463294#endif 
    32473295 
    32483296    //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 
    32493297    if (scx && scx->scopesym && 
    32503298        scx->scopesym->members && !scx->scopesym->isTemplateMixin() 
    32513299#if 0 // removed because it bloated compile times 
    32523300        /* The problem is if A imports B, and B imports A, and both A 
    32533301         * and B instantiate the same template, does the compilation of A 
    32543302         * or the compilation of B do the actual instantiation? 
    32553303         * 
    32563304         * see bugzilla 2500. 
    32573305         */ 
    3258         && !scx->module->imports(scx->module
     3306        && !scx->module->selfImports(
    32593307#endif 
    32603308       ) 
    32613309    { 
    32623310        //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 
    32633311        a = scx->scopesym->members; 
    32643312    } 
    32653313    else 
    32663314    {   Module *m = sc->module->importedFrom; 
    32673315        //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); 
    32683316        a = m->members; 
    32693317        if (m->semanticdone >= 3) 
    32703318        dosemantic3 = 1; 
    32713319    } 
    32723320    for (int i = 0; 1; i++) 
    32733321    { 
    32743322        if (i == a->dim) 
    32753323        { 
    32763324        a->push(this); 
    32773325        break; 
    32783326        } 
     
    32823330    } 
    32833331#endif 
    32843332 
    32853333    // Copy the syntax trees from the TemplateDeclaration 
    32863334    members = Dsymbol::arraySyntaxCopy(tempdecl->members); 
    32873335 
    32883336    // Create our own scope for the template parameters 
    32893337    Scope *scope = tempdecl->scope; 
    32903338    if (!scope) 
    32913339    { 
    32923340    error("forward reference to template declaration %s\n", tempdecl->toChars()); 
    32933341    return; 
    32943342    } 
    32953343 
    32963344#if LOG 
    32973345    printf("\tcreate scope for template parameters '%s'\n", toChars()); 
    32983346#endif 
    32993347    argsym = new ScopeDsymbol(); 
    33003348    argsym->parent = scope->parent; 
    33013349    scope = scope->push(argsym); 
     3350//    scope->stc = 0; 
    33023351 
    33033352    // Declare each template parameter as an alias for the argument type 
    3304     declareParameters(scope); 
     3353    Scope *paramscope = scope->push(); 
     3354    paramscope->stc = 0; 
     3355    declareParameters(paramscope); 
     3356    paramscope->pop(); 
    33053357 
    33063358    // Add members of template instance to template instance symbol table 
    33073359//    parent = scope->scopesym; 
    33083360    symtab = new DsymbolTable(); 
    33093361    int memnum = 0; 
    33103362    for (int i = 0; i < members->dim; i++) 
    33113363    { 
    33123364    Dsymbol *s = (Dsymbol *)members->data[i]; 
    33133365#if LOG 
    33143366    printf("\t[%d] adding member '%s' %p kind %s to '%s', memnum = %d\n", i, s->toChars(), s, s->kind(), this->toChars(), memnum); 
    33153367#endif 
    33163368    memnum |= s->addMember(scope, this, memnum); 
    33173369    } 
    33183370#if LOG 
    33193371    printf("adding members done\n"); 
    33203372#endif 
    33213373 
    33223374    /* See if there is only one member of template instance, and that 
    33233375     * member has the same name as the template instance. 
    33243376     * If so, this template instance becomes an alias for that member. 
     
    37543806        assert(ea); 
    37553807        ea = ea->castTo(tvp->valType); 
    37563808        ea = ea->optimize(WANTvalue | WANTinterpret); 
    37573809        tiargs->data[i] = (Object *)ea; 
    37583810    } 
    37593811    } 
    37603812#endif 
    37613813 
    37623814#if LOG 
    37633815    printf("\tIt's a match with template declaration '%s'\n", tempdecl->toChars()); 
    37643816#endif 
    37653817    return tempdecl; 
    37663818} 
    37673819 
    37683820 
    37693821/***************************************** 
    37703822 * Determines if a TemplateInstance will need a nested 
    37713823 * generation of the TemplateDeclaration. 
    37723824 */ 
    37733825 
    3774 int TemplateInstance::isNested(Objects *args) 
     3826int TemplateInstance::hasNestedArgs(Objects *args) 
    37753827{   int nested = 0; 
    3776     //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars()); 
     3828    //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); 
    37773829 
    37783830    /* A nested instance happens when an argument references a local 
    37793831     * symbol that is on the stack. 
    37803832     */ 
    37813833    for (size_t i = 0; i < args->dim; i++) 
    37823834    {   Object *o = (Object *)args->data[i]; 
    37833835    Expression *ea = isExpression(o); 
    37843836    Dsymbol *sa = isDsymbol(o); 
    37853837    Tuple *va = isTuple(o); 
    37863838    if (ea) 
    37873839    { 
    37883840        if (ea->op == TOKvar) 
    37893841        { 
    37903842        sa = ((VarExp *)ea)->var; 
    37913843        goto Lsa; 
    37923844        } 
    37933845        if (ea->op == TOKfunction) 
    37943846        { 
    37953847        sa = ((FuncExp *)ea)->fd; 
    37963848        goto Lsa; 
     
    38253877            for (Dsymbol *p = dparent; p; p = p->parent) 
    38263878            { 
    38273879                if (p == isnested) 
    38283880                {   isnested = dparent; 
    38293881                goto L1;    // dparent is most nested 
    38303882                } 
    38313883            } 
    38323884            error("%s is nested in both %s and %s", 
    38333885                toChars(), isnested->toChars(), dparent->toChars()); 
    38343886            } 
    38353887          L1: 
    38363888            //printf("\tnested inside %s\n", isnested->toChars()); 
    38373889            nested |= 1; 
    38383890        } 
    38393891        else 
    38403892            error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars()); 
    38413893        } 
    38423894    } 
    38433895    else if (va) 
    38443896    { 
    3845         nested |= isNested(&va->objects); 
     3897        nested |= hasNestedArgs(&va->objects); 
    38463898    } 
    38473899    } 
    38483900    return nested; 
    38493901} 
    38503902 
    38513903/**************************************** 
    38523904 * This instance needs an identifier for name mangling purposes. 
    38533905 * Create one by taking the template declaration name and adding 
    38543906 * the type signature for it. 
    38553907 */ 
    38563908 
    38573909Identifier *TemplateInstance::genIdent() 
    38583910{   OutBuffer buf; 
    38593911    char *id; 
    38603912    Objects *args; 
    38613913 
    38623914    //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); 
    38633915    id = tempdecl->ident->toChars(); 
    38643916    buf.printf("__T%zu%s", strlen(id), id); 
    38653917    args = tiargs; 
  • trunk/src/template.h

    r174 r183  
    3434struct Scope; 
    3535struct Expression; 
    3636struct AliasDeclaration; 
    3737struct FuncDeclaration; 
    3838struct HdrGenState; 
    3939enum MATCH; 
    4040 
    4141struct Tuple : Object 
    4242{ 
    4343    Objects objects; 
    4444 
    4545    int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType() 
    4646}; 
    4747 
    4848 
    4949struct TemplateDeclaration : ScopeDsymbol 
    5050{ 
    5151    TemplateParameters *parameters; // array of TemplateParameter's 
    5252 
    5353    TemplateParameters *origParameters; // originals for Ddoc 
    54  
     54#if V2 
    5555    Expression *constraint; 
    56  
     56#endif 
    5757    Array instances;            // array of TemplateInstance's 
    5858 
    5959    TemplateDeclaration *overnext;  // next overloaded TemplateDeclaration 
    6060    TemplateDeclaration *overroot;  // first in overnext list 
    6161 
    6262    Scope *scope; 
    6363    Dsymbol *onemember;     // if !=NULL then one member of this template 
    6464 
    6565    TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, 
    66     Expression *constraint, Array *decldefs); 
     66#if V2 
     67    Expression *constraint, 
     68#endif 
     69    Array *decldefs); 
    6770    Dsymbol *syntaxCopy(Dsymbol *); 
    6871    void semantic(Scope *sc); 
    6972    int overloadInsert(Dsymbol *s); 
    7073    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    7174    const char *kind(); 
    7275    char *toChars(); 
    7376 
    7477    void emitComment(Scope *sc); 
    7578//    void toDocBuffer(OutBuffer *buf); 
    7679 
    7780    MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); 
    7881    MATCH leastAsSpecialized(TemplateDeclaration *td2); 
    7982 
    8083    MATCH deduceFunctionTemplateMatch(Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs); 
    8184    FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0); 
    8285    void declareParameter(Scope *sc, TemplateParameter *tp, Object *o); 
    8386 
    8487    TemplateDeclaration *isTemplateDeclaration() { return this; } 
    8588 
    8689    TemplateTupleParameter *isVariadic(); 
     
    9497     *  template Foo(ident : specType) 
    9598     * For value-parameter: 
    9699     *  template Foo(valType ident) // specValue is set to NULL 
    97100     *  template Foo(valType ident : specValue) 
    98101     * For alias-parameter: 
    99102     *  template Foo(alias ident) 
    100103     * For this-parameter: 
    101104     *  template Foo(this ident) 
    102105     */ 
    103106 
    104107    Loc loc; 
    105108    Identifier *ident; 
    106109 
    107110    Declaration *sparam; 
    108111 
    109112    TemplateParameter(Loc loc, Identifier *ident); 
    110113 
    111114    virtual TemplateTypeParameter  *isTemplateTypeParameter(); 
    112115    virtual TemplateValueParameter *isTemplateValueParameter(); 
    113116    virtual TemplateAliasParameter *isTemplateAliasParameter(); 
     117#if V2 
    114118    virtual TemplateThisParameter *isTemplateThisParameter(); 
     119#endif 
    115120    virtual TemplateTupleParameter *isTemplateTupleParameter(); 
    116121 
    117122    virtual TemplateParameter *syntaxCopy() = 0; 
    118123    virtual void declareParameter(Scope *sc) = 0; 
    119124    virtual void semantic(Scope *) = 0; 
    120125    virtual void print(Object *oarg, Object *oded) = 0; 
    121126    virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0; 
    122127    virtual Object *specialization() = 0; 
    123128    virtual Object *defaultArg(Loc loc, Scope *sc) = 0; 
    124129 
    125130    /* If TemplateParameter's match as far as overloading goes. 
    126131     */ 
    127132    virtual int overloadMatch(TemplateParameter *) = 0; 
    128133 
    129134    /* Match actual argument against parameter. 
    130135     */ 
    131136    virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags = 0) = 0; 
    132137 
    133138    /* Create dummy argument based on parameter. 
    134139     */ 
     
    291296    Dsymbol *syntaxCopy(Dsymbol *); 
    292297    void semantic(Scope *sc); 
    293298    void semantic2(Scope *sc); 
    294299    void semantic3(Scope *sc); 
    295300    void inlineScan(); 
    296301    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    297302    Dsymbol *toAlias();         // resolve real symbol 
    298303    const char *kind(); 
    299304    int oneMember(Dsymbol **ps); 
    300305    char *toChars(); 
    301306    char *mangle(); 
    302307 
    303308    void toObjFile(int multiobj);           // compile to .obj file 
    304309 
    305310    // Internal 
    306311    static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags); 
    307312    void semanticTiargs(Scope *sc); 
    308313    TemplateDeclaration *findTemplateDeclaration(Scope *sc); 
    309314    TemplateDeclaration *findBestMatch(Scope *sc); 
    310315    void declareParameters(Scope *sc); 
    311     int isNested(Objects *tiargs); 
     316    int hasNestedArgs(Objects *tiargs); 
    312317    Identifier *genIdent(); 
    313318 
    314319    TemplateInstance *isTemplateInstance() { return this; } 
    315320    AliasDeclaration *isAliasDeclaration(); 
    316321}; 
    317322 
    318323struct TemplateMixin : TemplateInstance 
    319324{ 
    320325    Array *idents; 
    321326    Type *tqual; 
    322327 
    323328    Scope *scope;       // for forward referencing 
    324329 
    325330    TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs); 
    326331    Dsymbol *syntaxCopy(Dsymbol *s); 
    327332    void semantic(Scope *sc); 
    328333    void semantic2(Scope *sc); 
    329334    void semantic3(Scope *sc); 
    330335    void inlineScan(); 
    331336    const char *kind(); 
  • trunk/src/tocsym.c

    r182 r183  
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stddef.h> 
    1313#include <time.h> 
    1414#include <assert.h> 
    1515 
    1616#include "mars.h" 
    1717#include "module.h" 
    1818#include "mtype.h" 
    1919#include "declaration.h" 
    2020#include "statement.h" 
    2121#include "enum.h" 
    2222#include "aggregate.h" 
    2323#include "init.h" 
    2424#include "attrib.h" 
    2525#include "lexer.h" 
    2626#include "dsymbol.h" 
    2727#include "id.h" 
    2828 
    29 #include <mem.h> 
     29#include "rmem.h" 
    3030 
    3131// Back end 
    3232#include "cc.h" 
    3333#include "global.h" 
    3434#include "oper.h" 
    3535#include "code.h" 
    3636#include "type.h" 
    3737#include "dt.h" 
    3838#include "cgcv.h" 
    3939#include "outbuf.h" 
    4040#include "irstate.h" 
    4141 
    4242void slist_add(Symbol *s); 
    4343void slist_reset(); 
    4444 
    4545Classsym *fake_classsym(Identifier *id); 
    4646 
    4747/********************************* SymbolDeclaration ****************************/ 
    4848 
    4949SymbolDeclaration::SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym) 
  • trunk/src/todt.c

    r182 r183  
    875875 
    876876    if (offset < structsize) 
    877877    dtnzeros(pdt, structsize - offset); 
    878878 
    879879#undef LOG 
    880880} 
    881881 
    882882void StructDeclaration::toDt(dt_t **pdt) 
    883883{ 
    884884    unsigned offset; 
    885885    unsigned i; 
    886886    dt_t *dt; 
    887887 
    888888    //printf("StructDeclaration::toDt(), this='%s'\n", toChars()); 
    889889    offset = 0; 
    890890 
    891891    // Note equivalence of this loop to class's 
    892892    for (i = 0; i < fields.dim; i++) 
    893893    { 
    894894    VarDeclaration *v = (VarDeclaration *)fields.data[i]; 
    895     Initializer *init; 
    896  
    897895    //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset); 
    898896    dt = NULL; 
    899     init = v->init; 
    900     if (init) 
    901     {   //printf("\t\thas initializer %s\n", init->toChars()); 
    902         ExpInitializer *ei = init->isExpInitializer(); 
    903         Type *tb = v->type->toBasetype(); 
    904         if (ei && tb->ty == Tsarray) 
    905         ((TypeSArray *)tb)->toDtElem(&dt, ei->exp); 
    906         else 
    907         dt = init->toDt(); 
    908     } 
    909     else if (v->offset >= offset) 
    910         v->type->toDt(&dt); 
     897    int sz; 
     898 
     899    if (v->storage_class & STCref) 
     900    { 
     901        sz = PTRSIZE; 
     902        if (v->offset >= offset) 
     903        dtnzeros(&dt, sz); 
     904    } 
     905    else 
     906    { 
     907        sz = v->type->size(); 
     908        Initializer *init = v->init; 
     909        if (init) 
     910        {   //printf("\t\thas initializer %s\n", init->toChars()); 
     911        ExpInitializer *ei = init->isExpInitializer(); 
     912        Type *tb = v->type->toBasetype(); 
     913        if (ei && tb->ty == Tsarray) 
     914            ((TypeSArray *)tb)->toDtElem(&dt, ei->exp); 
     915        else 
     916            dt = init->toDt(); 
     917        } 
     918        else if (v->offset >= offset) 
     919        v->type->toDt(&dt); 
     920    } 
    911921    if (dt) 
    912922    { 
    913923        if (v->offset < offset) 
    914924        error("overlapping initialization for struct %s.%s", toChars(), v->toChars()); 
    915925        else 
    916926        { 
    917927        if (offset < v->offset) 
    918928            dtnzeros(pdt, v->offset - offset); 
    919929        dtcat(pdt, dt); 
    920         offset = v->offset + v->type->size()
     930        offset = v->offset + sz
    921931        } 
    922932    } 
    923933    } 
    924934 
    925935    if (offset < structsize) 
    926936    dtnzeros(pdt, structsize - offset); 
    927937 
    928938    dt_optimize(*pdt); 
    929939} 
    930940 
    931941/* ================================================================= */ 
    932942 
    933943dt_t **Type::toDt(dt_t **pdt) 
    934944{ 
    935945    //printf("Type::toDt()\n"); 
    936946    Expression *e = defaultInit(); 
    937947    return e->toDt(pdt); 
    938948} 
    939949 
    940950dt_t **TypeSArray::toDt(dt_t **pdt) 
  • trunk/src/toir.c

    r182 r183  
    1414 
    1515#include    <stdio.h> 
    1616#include    <string.h> 
    1717#include    <time.h> 
    1818#include    <complex.h> 
    1919 
    2020#include    "lexer.h" 
    2121#include    "expression.h" 
    2222#include    "mtype.h" 
    2323#include    "dsymbol.h" 
    2424#include    "declaration.h" 
    2525#include    "enum.h" 
    2626#include    "aggregate.h" 
    2727#include    "attrib.h" 
    2828#include    "module.h" 
    2929#include    "init.h" 
    3030#include    "template.h" 
    3131 
    3232#if _WIN32 
    3333#include    "..\tk\mem.h"   // for mem_malloc 
    34 #elif linux || __APPLE__ 
     34#else 
    3535#include    "../tk/mem.h"   // for mem_malloc 
    3636#endif 
    3737 
    3838#include    "cc.h" 
    3939#include    "el.h" 
    4040#include    "oper.h" 
    4141#include    "global.h" 
    4242#include    "code.h" 
    4343#include    "type.h" 
    4444#include    "dt.h" 
    4545#include    "irstate.h" 
    4646#include    "id.h" 
    4747#include    "type.h" 
    4848#include    "toir.h" 
    4949 
    5050static char __file__[] = __FILE__;  /* for tassert.h        */ 
    5151#include    "tassert.h" 
    5252 
    5353/********************************************* 
    5454 * Produce elem which increments the usage count for a particular line. 
     
    170170             */ 
    171171            if (fdparent == s->toParent2()) 
    172172            break; 
    173173            if (thisfd->isNested()) 
    174174            { 
    175175            FuncDeclaration *p = s->toParent2()->isFuncDeclaration(); 
    176176#if V2 
    177177            if (!p || p->closureVars.dim) 
    178178#else 
    179179            if (!p || p->nestedFrameRef) 
    180180#endif 
    181181                ethis = el_una(OPind, TYnptr, ethis); 
    182182            } 
    183183            else if (thisfd->vthis) 
    184184            { 
    185185            } 
    186186            else 
    187187            assert(0); 
    188188        } 
    189189        else 
    190         {   /* Enclosed by a class. That means the current 
    191              * function must be a member function of that class
     190        {   /* Enclosed by an aggregate. That means the current 
     191             * function must be a member function of that aggregate
    192192             */ 
    193             ClassDeclaration *cd = s->isClassDeclaration(); 
    194             if (!cd) 
     193            ClassDeclaration *cd; 
     194            StructDeclaration *sd; 
     195            AggregateDeclaration *ad = s->isAggregateDeclaration(); 
     196            if (!ad) 
    195197            goto Lnoframe; 
    196             if (//cd->baseClass == fd || 
    197            fd->isClassDeclaration() && 
     198            cd = s->isClassDeclaration(); 
     199            if (cd && fd->isClassDeclaration() && 
    198200            fd->isClassDeclaration()->isBaseOf(cd, NULL)) 
    199201            break; 
    200             if (!cd->isNested() || !cd->vthis) 
     202            sd = s->isStructDeclaration(); 
     203            if (fd == sd) 
     204            break; 
     205            if (!ad->isNested() || !ad->vthis) 
    201206            { 
    202207              Lnoframe: 
    203208            irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toChars()); 
    204209            return el_long(TYnptr, 0);  // error recovery 
    205210            } 
    206             ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, cd->vthis->offset)); 
     211            ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, ad->vthis->offset)); 
    207212            ethis = el_una(OPind, TYnptr, ethis); 
    208213            if (fdparent == s->toParent2()) 
    209214            break; 
    210215            if (fd == s->toParent2()) 
    211216            { 
    212217            /* Remember that frames for functions that have no 
    213218             * nested references are skipped in the linked list 
    214219             * of frames. 
    215220             */ 
    216221#if V2 
    217222            if (s->toParent2()->isFuncDeclaration()->closureVars.dim) 
    218223#else 
    219224            if (s->toParent2()->isFuncDeclaration()->nestedFrameRef) 
    220225#endif 
    221226                ethis = el_una(OPind, TYnptr, ethis); 
    222227            break; 
    223228            } 
    224229            if (s->toParent2()->isFuncDeclaration()) 
    225230            { 
    226231            /* Remember that frames for functions that have no 
     
    232237#else 
    233238            if (s->toParent2()->isFuncDeclaration()->nestedFrameRef) 
    234239#endif 
    235240                ethis = el_una(OPind, TYnptr, ethis); 
    236241            } 
    237242        } 
    238243        s = s->toParent2(); 
    239244        assert(s); 
    240245        } 
    241246    } 
    242247    } 
    243248#if 0 
    244249    printf("ethis:\n"); 
    245250    elem_print(ethis); 
    246251    printf("\n"); 
    247252#endif 
    248253    return ethis; 
    249254} 
    250255 
    251256 
     257/************************* 
     258 * Initialize the hidden aggregate member, vthis, with 
     259 * the context pointer. 
     260 * Returns: 
     261 *  *(ey + ad.vthis.offset) = this; 
     262 */ 
     263elem *setEthis(Loc loc, IRState *irs, elem *ey, AggregateDeclaration *ad) 
     264{ 
     265    elem *ethis; 
     266    FuncDeclaration *thisfd = irs->getFunc(); 
     267    int offset = 0; 
     268    Dsymbol *cdp = ad->toParent2(); // class/func we're nested in 
     269 
     270    //printf("setEthis(ad = %s, cdp = %s, thisfd = %s)\n", ad->toChars(), cdp->toChars(), thisfd->toChars()); 
     271 
     272    if (cdp == thisfd) 
     273    {   /* Class we're new'ing is a local class in this function: 
     274     *  void thisfd() { class ad { } } 
     275     */ 
     276    if (irs->sclosure) 
     277        ethis = el_var(irs->sclosure); 
     278    else if (irs->sthis) 
     279    { 
     280#if V2 
     281        if (thisfd->closureVars.dim) 
     282#else 
     283        if (thisfd->nestedFrameRef) 
     284#endif 
     285        { 
     286        ethis = el_ptr(irs->sthis); 
     287        } 
     288        else 
     289        ethis = el_var(irs->sthis); 
     290    } 
     291    else 
     292    { 
     293        ethis = el_long(TYnptr, 0); 
     294#if V2 
     295        if (thisfd->closureVars.dim) 
     296#else 
     297        if (thisfd->nestedFrameRef) 
     298#endif 
     299        { 
     300        ethis->Eoper = OPframeptr; 
     301        } 
     302    } 
     303    } 
     304    else if (thisfd->vthis && 
     305      (cdp == thisfd->toParent2() || 
     306       (cdp->isClassDeclaration() && 
     307        cdp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset) 
     308       ) 
     309      ) 
     310    ) 
     311    {   /* Class we're new'ing is at the same level as thisfd 
     312     */ 
     313    assert(offset == 0);    // BUG: should handle this case 
     314    ethis = el_var(irs->sthis); 
     315    } 
     316    else 
     317    { 
     318    ethis = getEthis(loc, irs, ad->toParent2()); 
     319    ethis = el_una(OPaddr, TYnptr, ethis); 
     320    } 
     321 
     322    ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, ad->vthis->offset)); 
     323    ey = el_una(OPind, TYnptr, ey); 
     324    ey = el_bin(OPeq, TYnptr, ey, ethis); 
     325    return ey; 
     326} 
     327 
    252328/******************************************* 
    253329 * Convert intrinsic function to operator. 
    254330 * Returns that operator, -1 if not an intrinsic function. 
    255331 */ 
    256332 
    257333int intrinsic_op(char *name) 
    258334{ 
     335    //printf("intrinsic_op(%s)\n", name); 
    259336    static const char *namearray[] = 
    260337    { 
     338#if V1 
    261339    "4math3cosFeZe", 
    262340    "4math3sinFeZe", 
    263341    "4math4fabsFeZe", 
    264342    "4math4rintFeZe", 
    265343    "4math4sqrtFdZd", 
    266344    "4math4sqrtFeZe", 
    267345    "4math4sqrtFfZf", 
    268346    "4math5ldexpFeiZe", 
    269347    "4math6rndtolFeZl", 
    270348 
    271 #if V1 
    272349    "9intrinsic2btFPkkZi", 
    273 #else 
    274     "9intrinsic2btFxPkkZi", 
    275 #endif 
    276350    "9intrinsic3bsfFkZi", 
    277351    "9intrinsic3bsrFkZi", 
    278352    "9intrinsic3btcFPkkZi", 
    279353    "9intrinsic3btrFPkkZi", 
    280354    "9intrinsic3btsFPkkZi", 
    281355    "9intrinsic3inpFkZh", 
    282356    "9intrinsic4inplFkZk", 
    283357    "9intrinsic4inpwFkZt", 
    284358    "9intrinsic4outpFkhZh", 
    285359    "9intrinsic5bswapFkZk", 
    286360    "9intrinsic5outplFkkZk", 
    287361    "9intrinsic5outpwFktZt", 
     362#elif V2 
     363    /* The names are mangled differently because of the pure and 
     364     * nothrow attributes. 
     365     */ 
     366    "4math3cosFNaNbeZe", 
     367    "4math3sinFNaNbeZe", 
     368    "4math4fabsFNaNbeZe", 
     369    "4math4rintFNaNbeZe", 
     370    "4math4sqrtFNaNbdZd", 
     371    "4math4sqrtFNaNbeZe", 
     372    "4math4sqrtFNaNbfZf", 
     373    "4math5ldexpFNaNbeiZe", 
     374    "4math6rndtolFNaNbeZl", 
     375 
     376    "9intrinsic2btFNaNbxPkkZi", 
     377    "9intrinsic3bsfFNaNbkZi", 
     378    "9intrinsic3bsrFNaNbkZi", 
     379    "9intrinsic3btcFNbPkkZi", 
     380    "9intrinsic3btrFNbPkkZi", 
     381    "9intrinsic3btsFNbPkkZi", 
     382    "9intrinsic3inpFNbkZh", 
     383    "9intrinsic4inplFNbkZk", 
     384    "9intrinsic4inpwFNbkZt", 
     385    "9intrinsic4outpFNbkhZh", 
     386    "9intrinsic5bswapFNaNbkZk", 
     387    "9intrinsic5outplFNbkkZk", 
     388    "9intrinsic5outpwFNbktZt", 
     389#endif 
    288390    }; 
    289391    static unsigned char ioptab[] = 
    290392    { 
    291393    OPcos, 
    292394    OPsin, 
    293395    OPabs, 
    294396    OPrint, 
    295397    OPsqrt, 
    296398    OPsqrt, 
    297399    OPsqrt, 
    298400    OPscale, 
    299401    OPrndtol, 
    300402 
    301403    OPbt, 
    302404    OPbsf, 
    303405    OPbsr, 
    304406    OPbtc, 
    305407    OPbtr, 
    306408    OPbts, 
    307409    OPinp, 
     
    312414    OPoutp, 
    313415    OPoutp, 
    314416    }; 
    315417 
    316418    int i; 
    317419    size_t length; 
    318420 
    319421#ifdef DEBUG 
    320422    assert(sizeof(namearray) / sizeof(char *) == sizeof(ioptab)); 
    321423    for (i = 0; i < sizeof(namearray) / sizeof(char *) - 1; i++) 
    322424    { 
    323425    if (strcmp(namearray[i], namearray[i + 1]) >= 0) 
    324426    { 
    325427        printf("namearray[%d] = '%s'\n", i, namearray[i]); 
    326428        assert(0); 
    327429    } 
    328430    } 
    329431#endif 
    330432 
    331433    length = strlen(name); 
    332     if (length < 11 || memcmp(name, "_D3std", 6) != 0) 
     434    if (length < 11 || 
     435    !(name[7] == 'm' || name[7] == 'i') || 
     436    memcmp(name, "_D3std", 6) != 0) 
    333437    return -1; 
    334438 
    335439    i = binary(name + 6, namearray, sizeof(namearray) / sizeof(char *)); 
    336440    return (i == -1) ? i : ioptab[i]; 
    337441} 
    338442 
    339443 
    340444/************************************** 
    341445 * Given an expression e that is an array, 
    342446 * determine and set the 'length' variable. 
    343447 * Input: 
    344448 *  lengthVar   Symbol of 'length' variable 
    345449 *  &e  expression that is the array 
    346450 *  t1  Type of the array 
    347451 * Output: 
    348452 *  e   is rewritten to avoid side effects 
    349453 * Returns: 
    350454 *  expression that initializes 'length' 
    351455 */ 
    352456 
  • trunk/src/toir.h

    r125 r183  
    11 
    2 // Copyright (c) 1999-2006 by Digital Mars 
     2// Copyright (c) 1999-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010/* Code to help convert to the intermediate representation 
    1111 * of the compiler back end. 
    1212 * It's specific to the Digital Mars back end, but can serve 
    1313 * as a guide to hooking up to other back ends. 
    1414 */ 
    1515 
    1616elem *incUsageElem(IRState *irs, Loc loc); 
    1717elem *getEthis(Loc loc, IRState *irs, Dsymbol *fd); 
     18elem *setEthis(Loc loc, IRState *irs, elem *ey, AggregateDeclaration *ad); 
    1819int intrinsic_op(char *name); 
    1920elem *resolveLengthVar(VarDeclaration *lengthVar, elem **pe, Type *t1); 
    2021 
  • trunk/src/toobj.c

    r182 r183  
    88// See the included readme.txt for details. 
    99 
    1010#include <stdio.h> 
    1111#include <stddef.h> 
    1212#include <time.h> 
    1313#include <assert.h> 
    1414 
    1515#include "mars.h" 
    1616#include "module.h" 
    1717#include "mtype.h" 
    1818#include "declaration.h" 
    1919#include "statement.h" 
    2020#include "enum.h" 
    2121#include "aggregate.h" 
    2222#include "init.h" 
    2323#include "attrib.h" 
    2424#include "id.h" 
    2525#include "import.h" 
    2626#include "template.h" 
    2727 
    28 #include <mem.h> 
     28#include "rmem.h" 
    2929#include "cc.h" 
    3030#include "global.h" 
    3131#include "oper.h" 
    3232#include "code.h" 
    3333#include "type.h" 
    3434#include "dt.h" 
    3535#include "cgcv.h" 
    3636#include "outbuf.h" 
    3737#include "irstate.h" 
    3838 
    3939void obj_lzext(Symbol *s1,Symbol *s2); 
    4040 
    4141/* ================================================================== */ 
    4242 
    4343// Put out instance of ModuleInfo for this Module 
    4444 
    4545void Module::genmoduleinfo() 
    4646{ 
    4747    //printf("Module::genmoduleinfo() %s\n", toChars()); 
    4848 
     
    139139#if V2 
    140140    FuncDeclaration *sgetmembers = findGetMembers(); 
    141141    if (sgetmembers) 
    142142    dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr); 
    143143    else 
    144144#endif 
    145145    dtdword(&dt, 0);            // xgetMembers 
    146146 
    147147    if (sictor) 
    148148    dtxoff(&dt, sictor, 0, TYnptr); 
    149149    else 
    150150    dtdword(&dt, 0); 
    151151 
    152152    ////////////////////////////////////////////// 
    153153 
    154154    for (int i = 0; i < aimports.dim; i++) 
    155155    {   Module *m = (Module *)aimports.data[i]; 
    156156 
    157157    if (m->needModuleInfo()) 
    158158    {   Symbol *s = m->toSymbol(); 
     159 
     160        /* Weak references don't pull objects in from the library, 
     161         * they resolve to 0 if not pulled in by something else. 
     162         * Don't pull in a module just because it was imported. 
     163         */ 
     164#if !OMFOBJ // Optlink crashes with weak symbols at EIP 41AFE7, 402000 
    159165        s->Sflags |= SFLweak; 
     166#endif 
    160167        dtxoff(&dt, s, 0, TYnptr); 
    161168    } 
    162169    } 
    163170 
    164171    for (int i = 0; i < aclasses.dim; i++) 
    165172    { 
    166173    ClassDeclaration *cd = (ClassDeclaration *)aclasses.data[i]; 
    167174    dtxoff(&dt, cd->toSymbol(), 0, TYnptr); 
    168175    } 
    169176 
    170177    csym->Sdt = dt; 
    171178#if ELFOBJ || MACHOBJ 
    172179    // Cannot be CONST because the startup code sets flag bits in it 
    173180    csym->Sseg = DATA; 
    174181#endif 
    175182    outdata(csym); 
    176183 
    177184    ////////////////////////////////////////////// 
    178185 
    179186    obj_moduleinfo(msym); 
     
    625632 
    626633    //printf("\tvtbl[%d] = %p\n", i, fd); 
    627634    if (fd && (fd->fbody || !isAbstract())) 
    628635    {   Symbol *s = fd->toSymbol(); 
    629636 
    630637#if V2 
    631638        if (isFuncHidden(fd)) 
    632639        {   /* fd is hidden from the view of this class. 
    633640         * If fd overlaps with any function in the vtbl[], then 
    634641         * issue 'hidden' error. 
    635642         */ 
    636643        for (int j = 1; j < vtbl.dim; j++) 
    637644        {   if (j == i) 
    638645            continue; 
    639646            FuncDeclaration *fd2 = ((Dsymbol *)vtbl.data[j])->isFuncDeclaration(); 
    640647            if (!fd2->ident->equals(fd->ident)) 
    641648            continue; 
    642649            if (fd->leastAsSpecialized(fd2) || fd2->leastAsSpecialized(fd)) 
    643650            { 
    644651            if (global.params.warnings) 
    645             {   fprintf(stdmsg, "warning - "); 
     652            { 
    646653                TypeFunction *tf = (TypeFunction *)fd->type; 
    647654                if (tf->ty == Tfunction) 
    648                 error("%s%s is hidden by %s\n", fd->toPrettyChars(), Argument::argsTypesToChars(tf->parameters, tf->varargs), toChars()); 
     655                warning("%s%s is hidden by %s\n", fd->toPrettyChars(), Argument::argsTypesToChars(tf->parameters, tf->varargs), toChars()); 
    649656                else 
    650                 error("%s is hidden by %s\n", fd->toPrettyChars(), toChars()); 
     657                warning("%s is hidden by %s\n", fd->toPrettyChars(), toChars()); 
    651658            } 
    652659            s = rtlsym[RTLSYM_DHIDDENFUNC]; 
    653660            break; 
    654661            } 
    655662        } 
    656663        } 
    657664#endif 
    658665        dtxoff(&dt, s, 0, TYnptr); 
    659666    } 
    660667    else 
    661668        dtdword(&dt, 0); 
    662669    } 
    663670    vtblsym->Sdt = dt; 
    664671    vtblsym->Sclass = scclass; 
    665672    vtblsym->Sfl = FLdata; 
    666673#if ELFOBJ 
    667674    vtblsym->Sseg = CDATA; 
    668675#endif 
    669676#if MACHOBJ 
    670677    vtblsym->Sseg = DATA; 
     
    909916    {   obj_append(this); 
    910917    return; 
    911918    } 
    912919 
    913920    // Anonymous structs/unions only exist as part of others, 
    914921    // do not output forward referenced structs's 
    915922    if (!isAnonymous() && members) 
    916923    { 
    917924    if (global.params.symdebug) 
    918925        toDebug(); 
    919926 
    920927    type->getTypeInfo(NULL);    // generate TypeInfo 
    921928 
    922929    if (1) 
    923930    { 
    924931        // Generate static initializer 
    925932        toInitializer(); 
    926933#if 0 
    927934        sinit->Sclass = SCcomdat; 
    928935#else 
    929         if (parent && parent->isTemplateInstance()) 
     936        if (inTemplateInstance()) 
     937        { 
    930938        sinit->Sclass = SCcomdat; 
     939        } 
    931940        else 
     941        { 
    932942        sinit->Sclass = SCglobal; 
     943        } 
    933944#endif 
    934945        sinit->Sfl = FLdata; 
    935946        toDt(&sinit->Sdt); 
    936947 
    937948#if OMFOBJ 
    938949        /* For OMF, common blocks aren't pulled in from the library. 
    939950         */ 
    940951        /* ELF comdef's generate multiple 
    941952         * definition errors for them from the gnu linker. 
    942953         * Need to figure out how to generate proper comdef's for ELF. 
    943954         */ 
    944955        // See if we can convert a comdat to a comdef, 
    945956        // which saves on exe file space. 
    946957        if (sinit->Sclass == SCcomdat && 
    947958        sinit->Sdt && 
    948959        sinit->Sdt->dt == DT_azeros && 
    949960        sinit->Sdt->DTnext == NULL && 
    950961        !global.params.multiobj) 
    951962        { 
    952963        sinit->Sclass = SCglobal; 
  • trunk/src/traits.c

    r171 r183  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <ctype.h> 
    1414#include <assert.h> 
     15#if _MSC_VER 
     16#include <complex> 
     17#else 
    1518#include <complex.h> 
     19#endif 
    1620#include <math.h> 
    1721 
    1822#if IN_GCC 
    1923// Issues with using -include total.h (defines integer_t) and then complex.h fails... 
    2024#undef integer_t 
    2125#endif 
    2226 
    2327#ifdef __APPLE__ 
    2428#define integer_t dmd_integer_t 
    2529#endif 
    2630 
    27 #if IN_GCC 
    28 #include "mem.h" 
    29 #elif _WIN32 
    30 #include "..\root\mem.h" 
    31 #elif linux 
    32 #include "../root/mem.h" 
    33 #endif 
     31#include "rmem.h" 
    3432 
    3533//#include "port.h" 
    3634#include "mtype.h" 
    3735#include "init.h" 
    3836#include "expression.h" 
    3937#include "template.h" 
    4038#include "utf.h" 
    4139#include "enum.h" 
    4240#include "scope.h" 
    4341#include "statement.h" 
    4442#include "declaration.h" 
    4543#include "aggregate.h" 
    4644#include "import.h" 
    4745#include "id.h" 
    4846#include "dsymbol.h" 
    4947#include "module.h" 
    5048#include "attrib.h" 
    5149#include "hdrgen.h" 
    5250#include "parse.h" 
    5351 
    5452#define LOGSEMANTIC 0 
    5553 
     54#if V2 
     55 
    5656/************************************************ 
    5757 * Delegate to be passed to overloadApply() that looks 
    5858 * for virtual functions. 
    5959 */ 
    6060 
    6161struct Pvirtuals 
    6262{ 
    6363    Expression *e1; 
    6464    Expressions *exps; 
    6565}; 
    6666 
    6767static int fpvirtuals(void *param, FuncDeclaration *f) 
    6868{   Pvirtuals *p = (Pvirtuals *)param; 
    6969 
    7070    if (f->isVirtual()) 
    7171    {   Expression *e; 
    7272 
    7373    if (p->e1->op == TOKdotvar) 
    7474    {   DotVarExp *dve = (DotVarExp *)p->e1; 
    7575        e = new DotVarExp(0, dve->e1, f); 
     
    421421 
    422422    return NULL; 
    423423 
    424424Lnottype: 
    425425    error("%s is not a type", o->toChars()); 
    426426    goto Lfalse; 
    427427 
    428428Ldimerror: 
    429429    error("wrong number of arguments %d", dim); 
    430430    goto Lfalse; 
    431431 
    432432 
    433433Lfalse: 
    434434    return new IntegerExp(loc, 0, Type::tbool); 
    435435 
    436436Ltrue: 
    437437    return new IntegerExp(loc, 1, Type::tbool); 
    438438} 
    439439 
    440440 
     441#endif 
  • trunk/src/typinf.c

    r182 r183  
    1010 
    1111#include <stdio.h> 
    1212#include <assert.h> 
    1313 
    1414//#include "mem.h" 
    1515 
    1616#include "mars.h" 
    1717#include "module.h" 
    1818#include "mtype.h" 
    1919#include "scope.h" 
    2020#include "init.h" 
    2121#include "expression.h" 
    2222#include "attrib.h" 
    2323#include "declaration.h" 
    2424#include "template.h" 
    2525#include "id.h" 
    2626#include "enum.h" 
    2727#include "import.h" 
    2828#include "aggregate.h" 
    2929 
    30 #include <mem.h> 
     30#include "rmem.h" 
    3131#include "cc.h" 
    3232#include "global.h" 
    3333#include "oper.h" 
    3434#include "code.h" 
    3535#include "type.h" 
    3636#include "dt.h" 
    3737#include "cgcv.h" 
    3838#include "outbuf.h" 
    3939#include "irstate.h" 
    4040 
    4141extern Symbol *static_sym(); 
    4242 
    4343/******************************************* 
    4444 * Get a canonicalized form of the TypeInfo for use with the internal 
    4545 * runtime library routines. Canonicalized in that static arrays are 
    4646 * represented as dynamic arrays, enums are represented by their 
    4747 * underlying type, etc. This reduces the number of TypeInfo's needed, 
    4848 * so we can use the custom internal ones more. 
    4949 */ 
    5050