88 changes: 44 additions & 44 deletions src/backend/gflow.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1985-1998 by Symantec
// Copyright (C) 2000-2014 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down Expand Up @@ -54,7 +54,7 @@ STATIC void accumlv(vec_t GEN , vec_t KILL , elem *n);
STATIC void accumvbe(vec_t GEN , vec_t KILL , elem *n);
STATIC void accumrd(vec_t GEN , vec_t KILL , elem *n);
STATIC void flowaecp(void);


/***************** REACHING DEFINITIONS *********************/

/************************************
Expand All @@ -69,9 +69,9 @@ STATIC void flowaecp(void);
*/

void flowrd()
{ register vec_t tmp;
register unsigned i;
register bool anychng;
{ vec_t tmp;
unsigned i;
bool anychng;

rdgenkill(); /* Compute Bgen and Bkill for RDs */
if (deftop == 0) /* if no definition elems */
Expand All @@ -89,8 +89,8 @@ void flowrd()
do
{ anychng = FALSE;
for (i = 0; i < dfotop; i++) /* for each block */
{ register block *b;
register list_t bp;
{ block *b;
list_t bp;

b = dfo[i];

Expand Down Expand Up @@ -118,7 +118,7 @@ void flowrd()
#if 0
dbg_printf("Reaching definitions\n");
for (i = 0; i < dfotop; i++)
{ register block *b = dfo[i];
{ block *b = dfo[i];

assert(vec_numbits(b->Binrd) == deftop);
dbg_printf("B%d Bin ",i); vec_println(b->Binrd);
Expand All @@ -128,13 +128,13 @@ void flowrd()
}
#endif
}


/***************************
* Compute Bgen and Bkill for RDs.
*/

STATIC void rdgenkill()
{ register unsigned i,deftopsave;
{ unsigned i,deftopsave;

util_free(defnod); /* free existing junk */

Expand Down Expand Up @@ -163,7 +163,7 @@ STATIC void rdgenkill()
assert(deftop == deftopsave);

for (i = 0; i < dfotop; i++) /* for each block */
{ register block *b = dfo[i];
{ block *b = dfo[i];

/* dump any existing vectors */
vec_free(b->Bgen);
Expand All @@ -181,12 +181,12 @@ STATIC void rdgenkill()
b->Boutrd = vec_calloc(deftop);
}
}


/**********************
* Compute # of definition elems (deftop).
*/

STATIC void numdefelems(register elem *n)
STATIC void numdefelems(elem *n)
{
while (1)
{ assert(n);
Expand All @@ -212,8 +212,8 @@ STATIC void numdefelems(register elem *n)
* necessary.
*/

STATIC void asgdefelems(block *b,register elem *n)
{ register unsigned op;
STATIC void asgdefelems(block *b,elem *n)
{ unsigned op;

assert(b && n);
op = n->Eoper;
Expand All @@ -234,7 +234,7 @@ STATIC void asgdefelems(block *b,register elem *n)
deftop++;
}
}


/*************************************
* Allocate and compute rd GEN and KILL.
*/
Expand Down Expand Up @@ -307,7 +307,7 @@ STATIC void accumrd(vec_t GEN,vec_t KILL,elem *n)
if (OTdef(op)) /* if definition elem */
updaterd(n,GEN,KILL);
}


/******************** AVAILABLE EXPRESSIONS ***********************/

/************************************
Expand Down Expand Up @@ -349,7 +349,7 @@ void flowcp()

STATIC void flowaecp()
{ vec_t tmp;
register unsigned i;
unsigned i;
bool anychng;

aecpgenkill(); /* Compute Bgen and Bkill for AEs or CPs */
Expand All @@ -368,7 +368,7 @@ STATIC void flowaecp()

/* For all blocks except startblock */
for (i = 1; i < dfotop; i++)
{ register block *b = dfo[i];
{ block *b = dfo[i];

vec_set(b->Bin); /* Bin = all expressions */

Expand Down Expand Up @@ -455,7 +455,7 @@ STATIC void flowaecp()
} while (anychng);
vec_free(tmp);
}


/******************************
* A variable to avoid parameter overhead to asgexpelems().
*/
Expand All @@ -467,7 +467,7 @@ static block *this_block;
*/

STATIC void aecpgenkill()
{ register unsigned i;
{ unsigned i;
unsigned exptopsave;

util_free(expnod); /* dump any existing one */
Expand Down Expand Up @@ -518,7 +518,7 @@ STATIC void aecpgenkill()
#endif

for (i = 0; i < dfotop; i++) /* for each block */
{ register block *b = dfo[i];
{ block *b = dfo[i];
elem *e;

/* dump any existing vectors */
Expand Down Expand Up @@ -613,16 +613,16 @@ STATIC void aecpgenkill()
b->Bout = vec_calloc(exptop);
}
}


/*****************************
* Accumulate number of expressions in exptop.
* Set NFLaecp as a flag indicating an AE elem.
* Returns:
* TRUE if this elem is a possible AE elem.
*/

STATIC int numaeelems(register elem *n)
{ register unsigned op;
STATIC int numaeelems(elem *n)
{ unsigned op;
unsigned ae;

assert(n);
Expand Down Expand Up @@ -681,7 +681,7 @@ STATIC void numcpelems(elem *n)
}
n->Nflags &= ~NFLaecp;
}


/********************************
* Assign ae (or cp) elems to expnod[] (in order of evaluation).
*/
Expand Down Expand Up @@ -710,7 +710,7 @@ STATIC void asgexpelems(elem *n)
else
n->Eexp = 0;
}


/********************************
* Compute defkill, starkill and vptrkill vectors.
* starkill: set of expressions killed when a variable is
Expand All @@ -723,8 +723,8 @@ STATIC void asgexpelems(elem *n)
*/

STATIC void defstarkill()
{ register unsigned i,op;
register elem *n;
{ unsigned i,op;
elem *n;

vec_free(vptrkill);
vec_free(defkill);
Expand Down Expand Up @@ -850,12 +850,12 @@ void main()
*/

void genkillae()
{ register unsigned i;
{ unsigned i;

flowxx = AE;
assert(exptop > 1);
for (i = 0; i < dfotop; i++)
{ register block *b = dfo[i];
{ block *b = dfo[i];

assert(b);
vec_clear(b->Bgen);
Expand All @@ -868,7 +868,7 @@ void genkillae()
}
}
}


/************************************
* Allocate and compute KILL and GEN vectors for a elem.
*/
Expand Down Expand Up @@ -1039,7 +1039,7 @@ STATIC void accumaecpx(elem *n)
assert(t->Eoper == OPvar);
s = t->EV.sp.Vsym; // ptr to var being def'd
for (i = 1; i < exptop; i++) /* for each ae elem */
{ register elem *e = expnod[i];
{ elem *e = expnod[i];

/* If it could be changed by the definition, */
/* set bit in KILL. */
Expand Down Expand Up @@ -1120,7 +1120,7 @@ STATIC void accumaecpx(elem *n)
}
}
}


/************************* LIVE VARIABLES **********************/

/*********************************
Expand All @@ -1137,7 +1137,7 @@ STATIC void accumaecpx(elem *n)

void flowlv()
{ vec_t tmp,livexit;
register unsigned i;
unsigned i;
bool anychng;
unsigned cnt;

Expand Down Expand Up @@ -1170,8 +1170,8 @@ void flowlv()

/* For each block B in reverse DFO order */
for (i = dfotop; i--;)
{ register block *b = dfo[i];
register list_t bl = b->Bsucc;
{ block *b = dfo[i];
list_t bl = b->Bsucc;

/* Bout = union of Bins of all successors to B. */
if (bl)
Expand Down Expand Up @@ -1211,7 +1211,7 @@ void flowlv()
}
#endif
}


/***********************************
* Compute Bgen and Bkill for LVs.
* Allocate Binlv and Boutlv vectors.
Expand Down Expand Up @@ -1249,7 +1249,7 @@ STATIC void lvgenkill()
vec_free(ambigsym); /* dump any existing one */
ambigsym = NULL;
}


/*****************************
* Allocate and compute KILL and GEN for live variables.
*/
Expand All @@ -1268,7 +1268,7 @@ STATIC void lvelem(vec_t *pgen,vec_t *pkill,elem *n)

STATIC void accumlv(vec_t GEN,vec_t KILL,elem *n)
{ vec_t Gl,Kl,Gr,Kr;
register unsigned op;
unsigned op;
elem *t;

assert(GEN && KILL && n);
Expand Down Expand Up @@ -1425,7 +1425,7 @@ STATIC void accumlv(vec_t GEN,vec_t KILL,elem *n)
break;
}
}


/********************* VERY BUSY EXPRESSIONS ********************/

/**********************************************
Expand Down Expand Up @@ -1512,14 +1512,14 @@ void flowvbe()
} while (anychng); /* while any changes occurred to any Bin */
vec_free(tmp);
}


/*************************************
* Accumulate GEN and KILL sets for VBEs for this elem.
*/

STATIC void accumvbe(vec_t GEN,vec_t KILL,elem *n)
{ register unsigned op,i;
register elem *t;
{ unsigned op,i;
elem *t;

assert(GEN && KILL && n);
op = n->Eoper;
Expand Down
2 changes: 1 addition & 1 deletion src/backend/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ void cgcs_term();
/* errmsgs.c */
extern char *dlcmsgs(int);
extern void errmsgs_term();


/* from evalu8.c */
int boolres(elem *);
int iftrue(elem *);
Expand Down
12 changes: 5 additions & 7 deletions src/backend/glocal.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1993-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand All @@ -9,16 +9,12 @@
* For any other uses, please contact Digital Mars.
*/

#if !DEMO && !SPP
#if !SPP

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#if __sun || _MSC_VER
#include <alloca.h>
#endif

#include "cc.h"
#include "global.h"
#include "el.h"
Expand Down Expand Up @@ -82,7 +78,7 @@ void localize()

// Table should not get any larger than the symbol table
locmax = globsym.symmax;
loctab = (loc_t *) alloca(locmax * sizeof(*loctab));
loctab = (loc_t *) malloc(locmax * sizeof(*loctab));

for (b = startblock; b; b = b->Bnext) /* for each block */
{
Expand All @@ -100,6 +96,8 @@ void localize()
local_exp(b->Belem,0);
}
}
free(loctab);
locmax = 0;
}

//////////////////////////////////////
Expand Down
326 changes: 93 additions & 233 deletions src/backend/gloop.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/backend/go.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1986-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down
2 changes: 1 addition & 1 deletion src/backend/go.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef unsigned mftype; /* a type big enough for all the flags */
#define MFtree 0x1000 // optelem (tree optimization)
#define MFlocal 0x2000 // localize expressions
#define MFall (~0) // do everything


/**********************************
* Definition elem vector, used for reaching definitions.
*/
Expand Down
113 changes: 48 additions & 65 deletions src/backend/gother.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1986-1998 by Symantec
// Copyright (C) 2000-2011 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down Expand Up @@ -123,7 +123,7 @@ void constprop()
static block *thisblock;

STATIC void rd_compute()
{ register unsigned i;
{ unsigned i;

cmes("constprop()\n");
assert(dfo);
Expand All @@ -149,7 +149,7 @@ STATIC void rd_compute()
}

for (i = 0; i < dfotop; i++) /* for each block */
{ register block *b;
{ block *b;

b = dfo[i];
thisblock = b;
Expand Down Expand Up @@ -180,7 +180,7 @@ STATIC void rd_compute()
}
}
}


/***************************
* Support routine for constprop().
* Visit each elem in order
Expand All @@ -196,7 +196,7 @@ STATIC void rd_compute()
*/

STATIC void conpropwalk(elem *n,vec_t IN)
{ register unsigned op;
{ unsigned op;
Elemdata *pdata;
vec_t L,R;
elem *t;
Expand Down Expand Up @@ -347,7 +347,7 @@ STATIC void conpropwalk(elem *n,vec_t IN)
}
}
}


/******************************
* Give error if there are no reaching defs for variable v.
*/
Expand Down Expand Up @@ -419,7 +419,7 @@ STATIC void chkrd(elem *n,list_t rdlist)
warerr(WM_used_b4_set, p2); // variable used before set
}
#endif
#if 1 && MARS
#if MARS
/* Watch out for:
void test()
{
Expand All @@ -439,7 +439,7 @@ STATIC void chkrd(elem *n,list_t rdlist)
//elem_print(n);
#endif
}


/**********************************
* Look through the vector of reaching defs (IN) to see
* if all defs of n are of the same constant. If so, replace
Expand Down Expand Up @@ -485,12 +485,11 @@ STATIC elem * chkprop(elem *n,list_t rdlist)
//printf("\trd: "); WReqn(d); printf("\n");
if (d->Eoper == OPasm) /* OPasm elems ruin everything */
goto noprop;
#if 0

// Runs afoul of Buzilla 4506
if (OTassign(d->Eoper) && EBIN(d)) // if assignment elem
#else
/*if (OTassign(d->Eoper) && EBIN(d))*/ // if assignment elem

if (OTassign(d->Eoper)) // if assignment elem
#endif
{ elem *t = Elvalue(d);

if (t->Eoper == OPvar)
Expand Down Expand Up @@ -558,7 +557,7 @@ STATIC elem * chkprop(elem *n,list_t rdlist)
noprop:
return NULL;
}


/***********************************
* Find all the reaching defs of OPvar e.
* Put into a linked list, or just set the RD bits in a vector.
Expand Down Expand Up @@ -780,8 +779,7 @@ STATIC void intranges()
increment = -increment;
relatop = rel->pelem->Eoper;
final = el_tolong(rel->pelem->E2);
// dbg_printf("initial = %d, increment = %d, final = %d\n",
// initial,increment,final);
//printf("initial = %d, increment = %d, final = %d\n",initial,increment,final);

/* Determine if we can make the relational an unsigned */
if (initial >= 0)
Expand All @@ -805,7 +803,7 @@ STATIC void intranges()
#ifdef DEBUG
if (debugc)
{ WReqn(rel->pelem);
dbg_printf(" made unsigned, initial = %ld, increment = %ld,\
printf(" made unsigned, initial = %ld, increment = %ld,\
final = %ld\n",(long int)initial,(long int)increment,(long int)final);
}
#endif
Expand Down Expand Up @@ -853,9 +851,6 @@ STATIC int loopcheck(block *start,block *inc,block *rel)
{ list_t list;
block *b;

#if __ZTC__
_chkstack(); /* always check stack on recursive routines */
#endif
if (!(start->Bflags & BFLvisited))
{ start->Bflags |= BFLvisited; /* guarantee eventual termination */
for (list = start->Bsucc; list; list = list_next(list))
Expand All @@ -866,7 +861,7 @@ STATIC int loopcheck(block *start,block *inc,block *rel)
}
return FALSE;
}


/****************************
* Do copy propagation.
* Copy propagation elems are of the form OPvar=OPvar, and they are
Expand All @@ -876,7 +871,7 @@ STATIC int loopcheck(block *start,block *inc,block *rel)
static int recalc;

void copyprop()
{ register unsigned i;
{ unsigned i;

out_regcand(&globsym);
cmes("copyprop()\n");
Expand All @@ -894,7 +889,7 @@ void copyprop()
#endif
recalc = 0;
for (i = 0; i < dfotop; i++) /* for each block */
{ register block *b;
{ block *b;

b = dfo[i];
if (b->Belem)
Expand Down Expand Up @@ -931,9 +926,9 @@ void copyprop()
* Keep IN up to date.
*/

STATIC void cpwalk(register elem *n,vec_t IN)
{ register unsigned op,i;
register elem *t;
STATIC void cpwalk(elem *n,vec_t IN)
{ unsigned op,i;
elem *t;
vec_t L;

static int nocp;
Expand Down Expand Up @@ -1132,7 +1127,7 @@ STATIC void cpwalk(register elem *n,vec_t IN)
;
}
}


/********************************
* Remove dead assignments. Those are assignments to a variable v
* for which there are no subsequent uses of v.
Expand All @@ -1147,13 +1142,13 @@ static vec_t ambigref; /* vector of assignment elems that */
/* reference is done (as in *p or call) */

void rmdeadass()
{ register unsigned i,j;
{ unsigned i,j;
vec_t DEAD,POSS;

cmes("rmdeadass()\n");
flowlv(); /* compute live variables */
for (i = 0; i < dfotop; i++) /* for each block b */
{ register block *b = dfo[i];
{ block *b = dfo[i];

if (!b->Belem) /* if no elems at all */
continue;
Expand All @@ -1178,18 +1173,18 @@ void rmdeadass()
vec_orass(POSS,DEAD); /* POSS |= DEAD */
foreach (j,asstop,POSS) /* for each possible dead asg. */
{ symbol *v; /* v = target of assignment */
register elem *n,*nv;
elem *n,*nv;

n = assnod[j];
nv = Elvalue(n);
v = nv->EV.sp.Vsym;
if (!symbol_isintab(v)) // not considered
continue;
//printf("assnod[%d]: ",j); WReqn(n); printf("\n");
//printf("\tPOSS\n");
//printf("assnod[%d]: ",j); WReqn(n); printf("\n");
//printf("\tPOSS\n");
/* If not positively dead but v is live on a */
/* successor to b, then v is live. */
//printf("\tDEAD=%d, live=%d\n",vec_testbit(j,DEAD),vec_testbit(v->Ssymnum,b->Boutlv));
//printf("\tDEAD=%d, live=%d\n",vec_testbit(j,DEAD),vec_testbit(v->Ssymnum,b->Boutlv));
if (!vec_testbit(j,DEAD) && vec_testbit(v->Ssymnum,b->Boutlv))
continue;
/* volatile variables are not dead */
Expand Down Expand Up @@ -1291,7 +1286,7 @@ STATIC unsigned numasg(elem *e)
return OTunary(e->Eoper) ? numasg(e->E1) :
OTbinary(e->Eoper) ? numasg(e->E1) + numasg(e->E2) : 0;
}


/******************************
* Tree walk routine for rmdeadass().
* DEAD = assignments which are dead
Expand All @@ -1307,7 +1302,7 @@ STATIC unsigned numasg(elem *e)

STATIC void accumda(elem *n,vec_t DEAD, vec_t POSS)
{ vec_t Pl,Pr,Dl,Dr;
register unsigned i,op,vecdim;
unsigned i,op,vecdim;

/*chkvecdim(asstop,0);*/
assert(n && DEAD && POSS);
Expand All @@ -1327,22 +1322,10 @@ STATIC void accumda(elem *n,vec_t DEAD, vec_t POSS)
/* = Pl & Pr | ~P & (Pl | Pr) */
vecdim = vec_dim(DEAD);
for (i = 0; i < vecdim; i++)
#if MPW
{
unsigned tmp1,tmp2;
tmp1 = POSS[i] & Dl[i] & Dr[i] ;
tmp2 = ~POSS[i] & (Dl[i] | Dr[i]);
DEAD[i] |= tmp1 | tmp2;
tmp1 = Pl[i] & Pr[i];
tmp2 = ~POSS[i] & (Pl[i] | Pr[i]);
POSS[i] = tmp1 | tmp2;
}
#else
{ DEAD[i] |= (POSS[i] & Dl[i] & Dr[i]) |
(~POSS[i] & (Dl[i] | Dr[i]));
POSS[i] = (Pl[i] & Pr[i]) | (~POSS[i] & (Pl[i] | Pr[i]));
}
#endif
vec_free(Pl); vec_free(Pr); vec_free(Dl); vec_free(Dr);
break;

Expand Down Expand Up @@ -1370,7 +1353,7 @@ STATIC void accumda(elem *n,vec_t DEAD, vec_t POSS)
// could be referenced.

for (i = 0; i < assnum; i++)
{ register elem *ti;
{ elem *ti;

ti = Elvalue(assnod[i]);
if (v == ti->EV.sp.Vsym &&
Expand Down Expand Up @@ -1516,7 +1499,7 @@ STATIC void accumda(elem *n,vec_t DEAD, vec_t POSS)
break;
}
}


/***************************
* Mark all dead variables. Only worry about register candidates.
* Compute live ranges for register candidates.
Expand Down Expand Up @@ -1555,7 +1538,7 @@ void deadvar()
/* if variable is in the IN set for that block. */
flowlv(); /* compute live variables */
for (i = 0; i < globsym.top; i++)
{ register unsigned j;
{ unsigned j;

if (globsym.tab[i]->Srange /*&& globsym.tab[i]->Sclass != CLMOS*/)
for (j = 0; j < dfotop; j++)
Expand All @@ -1565,7 +1548,7 @@ void deadvar()

/* Print results */
for (i = 0; i < globsym.top; i++)
{ register char *p;
{ char *p;
symbol *s = globsym.tab[i];

if (s->Sflags & SFLdead && s->Sclass != SCparameter && s->Sclass != SCregpar)
Expand All @@ -1589,12 +1572,12 @@ void deadvar()
* i = block index
*/

STATIC void dvwalk(register elem *n,register unsigned i)
STATIC void dvwalk(elem *n,unsigned i)
{
for (; TRUE; n = n->E1)
{ assert(n);
if (n->Eoper == OPvar || n->Eoper == OPrelconst)
{ register symbol *s = n->EV.sp.Vsym;
{ symbol *s = n->EV.sp.Vsym;

s->Sflags &= ~SFLdead;
if (s->Srange)
Expand All @@ -1608,7 +1591,7 @@ STATIC void dvwalk(register elem *n,register unsigned i)
break;
}
}


/*********************************
* Optimize very busy expressions (VBEs).
*/
Expand All @@ -1617,8 +1600,8 @@ static vec_t blockseen; /* which blocks we have visited */

void verybusyexp()
{ elem **pn;
register int i;
register unsigned j,k,l;
int i;
unsigned j,k,l;

cmes("verybusyexp()\n");
flowvbe(); /* compute VBEs */
Expand All @@ -1636,8 +1619,8 @@ void verybusyexp()
/* Go backwards through dfo so that VBEs are evaluated as */
/* close as possible to where they are used. */
for (i = dfotop; --i >= 0;) /* for each block */
{ register block *b = dfo[i];
register int done;
{ block *b = dfo[i];
int done;

/* Do not hoist things to blocks that do not */
/* divide the flow of control. */
Expand Down Expand Up @@ -1696,7 +1679,7 @@ void verybusyexp()
#endif

foreach (j,exptop,b->Bout)
{ register list_t bl;
{ list_t bl;

vec_clear(blockseen);
for (bl = expblk[j]->Bpred; bl; bl = list_next(bl))
Expand All @@ -1717,7 +1700,7 @@ void verybusyexp()
#endif

foreach (j,exptop,b->Bout)
{ register list_t bl;
{ list_t bl;

vec_clear(blockseen);
for (bl = expblk[j]->Bpred; bl; bl = list_next(bl))
Expand Down Expand Up @@ -1778,14 +1761,14 @@ void verybusyexp()
} /* for */
vec_free(blockseen);
}


/****************************
* Return TRUE if elem j is killed somewhere
* between b and bp.
*/

STATIC int killed(register unsigned j,register block *bp,block *b)
{ register list_t bl;
STATIC int killed(unsigned j,block *bp,block *b)
{ list_t bl;

if (bp == b || vec_testbit(bp->Bdfoidx,blockseen))
return FALSE;
Expand All @@ -1807,9 +1790,9 @@ STATIC int killed(register unsigned j,register block *bp,block *b)
* j = VBE expression elem candidate (index into expnod[])
*/

STATIC int ispath(register unsigned j,register block *bp,block *b)
{ register list_t bl;
register unsigned i;
STATIC int ispath(unsigned j,block *bp,block *b)
{ list_t bl;
unsigned i;

/*chkvecdim(exptop,0);*/
if (bp == b) return TRUE; /* the trivial case */
Expand Down
68 changes: 53 additions & 15 deletions src/backend/mscoff.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,23 @@

struct filehdr
{
unsigned short f_magic; // identifies type of target machine
unsigned short f_sig1; // IMAGE_FILE_MACHINE_UNKNOWN
unsigned short f_sig2; // 0xFFFF
unsigned short f_minver; // 2
unsigned short f_magic; // identifies type of target machine
unsigned long f_timdat; // creation date, number of seconds since 1970
unsigned char f_uuid[16]; // { '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
// '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8' };
unsigned long f_unused[4]; // { 0, 0, 0, 0 }
unsigned long f_nscns; // number of sections
unsigned long f_symptr; // file offset of symbol table
unsigned long f_nsyms; // number of entries in the symbol table


#define IMAGE_FILE_MACHINE_UNKNOWN 0 // applies to any machine type
#define IMAGE_FILE_MACHINE_I386 0x14C // x86
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // x86_64
unsigned short f_nscns; // number of sections (96 is max)
long f_timdat; // creation date, number of seconds since 1970
long f_symptr; // file offset of symbol table
long f_nsyms; // number of entried in the symbol table
unsigned short f_opthdr; // optional header size (0)
unsigned short f_flags;

#define IMAGE_FILE_RELOCS_STRIPPED 1
#define IMAGE_FILE_EXECUTABLE_IMAGE 2
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
Expand All @@ -39,6 +46,17 @@ struct filehdr
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
};

struct filehdr_old
{
unsigned short f_magic; // identifies type of target machine
unsigned short f_nscns; // number of sections (96 is max)
long f_timdat; // creation date, number of seconds since 1970
long f_symptr; // file offset of symbol table
long f_nsyms; // number of entried in the symbol table
unsigned short f_opthdr; // optional header size (0)
unsigned short f_flags;
};

/***********************************************/

// size should be 40 bytes
Expand Down Expand Up @@ -111,7 +129,7 @@ struct syment
#define n_nptr _n._n_nptr[1]

unsigned n_value;
short n_scnum;
long n_scnum;
#define IMAGE_SYM_DEBUG -2
#define IMAGE_SYM_ABSOLUTE -1
#define IMAGE_SYM_UNDEFINED 0
Expand All @@ -130,6 +148,23 @@ struct syment
};


struct syment_old
{
union
{
char _n_name[SYMNMLEN];
struct
{ long _n_zeroes;
long _n_offset;
} _n_n;
} _n;
unsigned n_value;
short n_scnum;
unsigned short n_type; // 0x20 function; 0x00 not a function
unsigned char n_sclass;
unsigned char n_numaux;
};

/***********************************************/

struct reloc
Expand Down Expand Up @@ -198,6 +233,7 @@ union auxent
unsigned TotalSize;
unsigned PointerToLinenumber;
unsigned PointerToNextFunction;
unsigned short Zeros;
} x_fd;

// .bf symbols
Expand All @@ -208,37 +244,39 @@ union auxent
unsigned short Linenumber;
char filler[6];
unsigned PointerToNextFunction;
unsigned short Zeros;
#pragma pack()
} x_bf;

// .ef symbols
struct
{ unsigned Unused;
unsigned short Linenumber;
unsigned short Zeros;
} x_ef;

// Weak externals
struct
{ unsigned TagIndex;
unsigned Characteristics;
unsigned short Zeros;
#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY
#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS
} x_weak;

// Files
struct
{ char FileName[18];
} x_filename;

// Section definitions
struct
{ unsigned length;
{
unsigned length;
unsigned short NumberOfRelocations;
unsigned short NumberOfLinenumbers;
unsigned CheckSum;
unsigned short Number;
unsigned short NumberLowPart;
unsigned char Selection;
unsigned char Unused;
unsigned short NumberHighPart;
unsigned short Zeros;
#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
#define IMAGE_COMDAT_SELECT_ANY 2
#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
Expand Down
187 changes: 103 additions & 84 deletions src/backend/mscoffobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ static Outbuffer *symbuf;

static Outbuffer *syment_buf; // array of struct syment

struct Comdef { symbol *sym; targ_size_t size; int count; };
static Outbuffer *comdef_symbuf; // Comdef's are stored here

static segidx_t segidx_drectve; // contents of ".drectve" section
static segidx_t segidx_debugS = UNKNOWN;
static segidx_t segidx_xdata = UNKNOWN;
Expand Down Expand Up @@ -393,12 +390,7 @@ MsCoffObj *MsCoffObj::init(Outbuffer *objbuf, const char *filename, const char *
syment_buf = new Outbuffer(sizeof(struct syment) * SYM_TAB_INIT);
syment_buf->setsize(0);

if (!comdef_symbuf)
comdef_symbuf = new Outbuffer(sizeof(symbol *) * SYM_TAB_INIT);
comdef_symbuf->setsize(0);

extdef = 0;

pointersSeg = 0;

// Initialize segments for CODE, DATA, UDATA and CDATA
Expand Down Expand Up @@ -575,12 +567,30 @@ static void syment_set_name(syment *sym, const char *name)
}
}

void build_syment_table()
void write_sym(struct syment* sym, bool bigobj)
{
assert(sizeof(*sym) == 20);
if (bigobj)
{
syment_buf->write(sym, sizeof(*sym));
}
else
{
// the only difference between syment and syment_old
// is that field n_scnum is long instead of short
unsigned scoff = (char*)&sym->n_scnum - (char*)sym;
syment_buf->write(sym, scoff + 2);
syment_buf->write((char*)sym + scoff + 4, sizeof(*sym) - scoff - 4);
}
}

void build_syment_table(bool bigobj)
{
/* The @comp.id symbol appears to be the version of VC that generated the .obj file.
* Anything we put in there would have no relevance, so we'll not put out this symbol.
*/

unsigned symsize = bigobj ? sizeof(syment) : sizeof(syment_old);
/* Now goes one symbol per section.
*/
for (segidx_t seg = 1; seg <= seg_count; seg++)
Expand All @@ -596,8 +606,7 @@ void build_syment_table()
sym.n_sclass = IMAGE_SYM_CLASS_STATIC;
sym.n_numaux = 1;

assert(sizeof(sym) == 18);
syment_buf->write(&sym, sizeof(sym));
write_sym(&sym, bigobj);

union auxent aux;
memset(&aux, 0, sizeof(aux));
Expand All @@ -614,17 +623,19 @@ void build_syment_table()

if (psechdr->s_flags & IMAGE_SCN_LNK_COMDAT)
{
aux.x_section.Selection = IMAGE_COMDAT_SELECT_ANY;
aux.x_section.Selection = (unsigned char)IMAGE_COMDAT_SELECT_ANY;
if (pseg->SDassocseg)
{ aux.x_section.Selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;
aux.x_section.Number = pseg->SDassocseg;
{ aux.x_section.Selection = (unsigned char)IMAGE_COMDAT_SELECT_ASSOCIATIVE;
aux.x_section.NumberHighPart = (unsigned short)(pseg->SDassocseg >> 16);
aux.x_section.NumberLowPart = (unsigned short)(pseg->SDassocseg & 0x0000FFFF);
}
}

syment_buf->write(&aux, sizeof(aux));
//printf("%d %d %d %d %d %d\n", sizeof(aux.x_fd), sizeof(aux.x_bf), sizeof(aux.x_ef),
// sizeof(aux.x_weak), sizeof(aux.x_filename), sizeof(aux.x_section));
assert(sizeof(aux) == 18);
memset(&aux.x_section.Zeros, 0, 2);

syment_buf->write(&aux, symsize);

assert(sizeof(aux) == 20);
}

/* Add symbols from symbuf[]
Expand All @@ -634,7 +645,7 @@ void build_syment_table()
size_t dim = symbuf->size() / sizeof(symbol *);
for (size_t i = 0; i < dim; i++)
{ symbol *s = ((symbol **)symbuf->buf)[i];
s->Sxtrnnum = syment_buf->size() / sizeof(syment);
s->Sxtrnnum = syment_buf->size() / symsize;
n++;

struct syment sym;
Expand All @@ -653,10 +664,6 @@ void build_syment_table()
default:
sym.n_scnum = SegData[s->Sseg]->SDshtidx;
break;

case SCcomdef:
assert(0); // comdef's should be in comdef_symbuf[]
break;
}
sym.n_type = tyfunc(s->Stype->Tty) ? 0x20 : 0;
switch (s->Sclass)
Expand All @@ -675,32 +682,7 @@ void build_syment_table()
}
sym.n_numaux = 0;

syment_buf->write(&sym, sizeof(sym));
}

/* Add comdef symbols from comdef_symbuf[]
*/

dim = comdef_symbuf->size() / sizeof(Comdef);
for (size_t i = 0; i < dim; i++)
{ Comdef *c = ((Comdef *)comdef_symbuf->buf) + i;
symbol *s = c->sym;
s->Sxtrnnum = syment_buf->size() / sizeof(syment);
n++;

struct syment sym;

char dest[DEST_LEN+1];
char *destr = obj_mangle2(s, dest);
syment_set_name(&sym, destr);

sym.n_scnum = IMAGE_SYM_UNDEFINED;
sym.n_type = 0;
sym.n_sclass = IMAGE_SYM_CLASS_EXTERNAL;
sym.n_value = c->size * c->count;
sym.n_numaux = 0;

syment_buf->write(&sym, sizeof(sym));
write_sym(&sym, bigobj);
}
}

Expand Down Expand Up @@ -742,8 +724,12 @@ void MsCoffObj::term(const char *objfilename)
if (errcnt)
return;
#endif

build_syment_table();
// To allow tooling support for most output files
// switch to new object file format (similar to C++ with /bigobj)
// only when exceeding the limit for 16-bit section count according to
// https://msdn.microsoft.com/en-us/library/8578y171%28v=vs.71%29.aspx
bool bigobj = scnhdr_cnt > 65279;
build_syment_table(bigobj);

/* Write out the object file in the following order:
* Header
Expand All @@ -758,24 +744,45 @@ void MsCoffObj::term(const char *objfilename)
// Write out the bytes for the header

struct filehdr header;
struct filehdr_old header_old;

header.f_magic = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
header.f_nscns = scnhdr_cnt;
time_t f_timedat = 0;
time(&f_timedat);
header.f_timdat = (long)f_timedat;
header.f_symptr = 0; // offset to symbol table
header.f_nsyms = 0;
header.f_opthdr = 0;
header.f_flags = 0;

foffset = sizeof(header); // start after header
unsigned symtable_offset;

foffset += ScnhdrBuf->size(); // section headers

header.f_symptr = foffset;
header.f_nsyms = syment_buf->size() / sizeof(struct syment);
foffset += header.f_nsyms * sizeof(struct syment); // symbol table
if (bigobj)
{
header.f_sig1 = IMAGE_FILE_MACHINE_UNKNOWN;
header.f_sig2 = 0xFFFF;
header.f_minver = 2;
header.f_magic = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
header.f_nscns = scnhdr_cnt;
header.f_timdat = (unsigned long)f_timedat;
unsigned char uuid[16] = { '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
'\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8' };
memcpy(header.f_uuid, uuid, 16);
memset(header.f_unused, 0, sizeof(header.f_unused));
foffset = sizeof(header); // start after header
foffset += ScnhdrBuf->size(); // section headers
header.f_symptr = foffset; // offset to symbol table
symtable_offset = foffset;
header.f_nsyms = syment_buf->size() / sizeof(struct syment);
foffset += header.f_nsyms * sizeof(struct syment); // symbol table
}
else
{
header_old.f_magic = I64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
header_old.f_nscns = scnhdr_cnt;
header_old.f_timdat = (unsigned long)f_timedat;
header_old.f_opthdr = 0;
header_old.f_flags = 0;
foffset = sizeof(header_old); // start after header
foffset += ScnhdrBuf->size(); // section headers
header_old.f_symptr = foffset; // offset to symbol table
symtable_offset = foffset;
header_old.f_nsyms = syment_buf->size() / sizeof(struct syment_old);
foffset += header_old.f_nsyms * sizeof(struct syment_old); // symbol table
}

unsigned string_table_offset = foffset;
foffset += string_table->size(); // string table
Expand Down Expand Up @@ -825,15 +832,23 @@ void MsCoffObj::term(const char *objfilename)
assert(fobjbuf->size() == 0);

// Write the header
fobjbuf->write(&header, sizeof(header));
foffset = sizeof(header);
if (bigobj)
{
fobjbuf->write(&header, sizeof(header));
foffset = sizeof(header);
}
else
{
fobjbuf->write(&header_old, sizeof(header_old));
foffset = sizeof(header_old);
}

// Write the section headers
fobjbuf->write(ScnhdrBuf);
foffset += ScnhdrBuf->size();

// Write the symbol table
assert(foffset == header.f_symptr);
assert(foffset == symtable_offset);
fobjbuf->write(syment_buf);
foffset += syment_buf->size();

Expand Down Expand Up @@ -1582,6 +1597,9 @@ segidx_t MsCoffObj::getsegment2(IDXSEC shtidx)
return seg;
}

extern void error(const char *filename, unsigned linnum, unsigned charnum, const char *format, ...);
extern void fatal();

/********************************************
* Add new scnhdr.
* Returns:
Expand Down Expand Up @@ -2046,24 +2064,25 @@ int MsCoffObj::common_block(Symbol *s,targ_size_t size,targ_size_t count)
// can't have code or thread local comdef's
assert(!(s->ty() & mTYthread));

/* A common block looks like this in the symbol table:
* n_name = s->Sident
* n_value = size * count
* n_scnum = IMAGE_SYM_UNDEFINED
* n_type = x0000
* n_sclass = IMAGE_SYM_CLASS_EXTERNAL
* n_numaux = 0
*/
s->Sfl = FLudata;
unsigned align = 16;
s->Sseg = MsCoffObj::getsegment(".bss$B", IMAGE_SCN_CNT_UNINITIALIZED_DATA |
IMAGE_SCN_LNK_COMDAT |
IMAGE_SCN_ALIGN_16BYTES |
IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_WRITE);
if (s->Salignment > align)
{
SegData[s->Sseg]->SDalignment = s->Salignment;
assert(s->Salignment >= -1);
}
s->Soffset = SegData[s->Sseg]->SDoffset;
SegData[s->Sseg]->SDsym = s;
SegData[s->Sseg]->SDoffset += count * size;

struct Comdef comdef;
comdef.sym = s;
comdef.size = size;
comdef.count = count;
comdef_symbuf->write(&comdef, sizeof(comdef));
MsCoffObj::pubdef(s->Sseg, s, s->Soffset);
searchfixlist(s); // backpatch any refs to this symbol

s->Sxtrnnum = 1;
if (!s->Sseg)
s->Sseg = UDATA;
return 1; // should return void
}

Expand Down
10 changes: 5 additions & 5 deletions src/backend/newman.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ char *cpp_operator2(token_t *to, int *pcastoverload)
}

#endif


/***********************************
* Generate and return a pointer to a string constructed from
* the type, appended to the prefix.
Expand Down Expand Up @@ -522,7 +522,7 @@ char *cpp_mangle(symbol *s)
return mangle.buf;
}
}


///////////////////////////////////////////////////////

/*********************************
Expand Down Expand Up @@ -584,7 +584,7 @@ STATIC int cpp_protection(symbol *s)
}
return i;
}


/***********************************
* Create mangled name for template instantiation.
*/
Expand Down Expand Up @@ -749,7 +749,7 @@ char *template_mangle(symbol *s,param_t *arglist)
}

#endif


//////////////////////////////////////////////////////
// Functions corresponding to the name mangling grammar in the
// "Microsoft Object Mapping Specification"
Expand Down Expand Up @@ -1662,7 +1662,7 @@ STATIC void cpp_decorated_name(symbol *s)
CHAR('@');
cpp_type_encoding(s);
}


/*********************************
* Mangle a vtbl or vbtbl name.
* Returns:
Expand Down
56 changes: 6 additions & 50 deletions src/backend/os.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1994-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand All @@ -20,11 +20,6 @@
#include <stdlib.h>
#include <string.h>

#if DOS386
#include <dos.h>
#include <sys\stat.h>
#endif

#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
#include <sys/types.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -166,7 +161,7 @@ void *globalrealloc(void *oldp,size_t newsize)
dbg_printf("globalrealloc(oldp = %p, size = x%x) = %p\n",oldp,newsize,p);
return p;
}


/*****************************************
* Functions to manage allocating a single virtual address space.
*/
Expand Down Expand Up @@ -610,32 +605,6 @@ unsigned long os_unique()
return x;
}

#elif DOS386

//////////////////////////////////////////
// Return a value that will hopefully be unique every time
// we call it.

unsigned long os_unique()
{
if (cputype() >= 5) // if cpuid instruction supported
{
__asm
{
mov EAX,1
cpuid
test EDX,0x20 // is rdtsc supported?
jz L1 // no
rdtsc
}
}
else
{
L1: time(NULL);
}
return _EAX;
}

#endif

/*******************************************
Expand All @@ -651,21 +620,14 @@ int os_file_exists(const char *name)
DWORD dw;
int result;

dw = GetFileAttributes(name);
dw = GetFileAttributesA(name);
if (dw == -1L)
result = 0;
else if (dw & FILE_ATTRIBUTE_DIRECTORY)
result = 2;
else
result = 1;
return result;
#elif DOS386
struct FIND *find;

find = findfirst(name,FA_DIREC | FA_SYSTEM | FA_HIDDEN);
if (!find)
return 0;
return (find->attribute & FA_DIREC) ? 2 : 1;
#elif __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
struct stat buf;

Expand Down Expand Up @@ -710,7 +672,7 @@ char *file_8dot3name(const char *filename)
char *buf;
int i;

h = FindFirstFile(filename,&fileinfo);
h = FindFirstFileA(filename,&fileinfo);
if (h == INVALID_HANDLE_VALUE)
return NULL;
if (fileinfo.cAlternateFileName[0])
Expand Down Expand Up @@ -770,15 +732,15 @@ int file_write(char *name, void *buffer, unsigned len)
HANDLE h;
DWORD numwritten;

h = CreateFileA((LPTSTR)name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
h = CreateFileA((LPCSTR)name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (h == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_PATH_NOT_FOUND)
{
if (!file_createdirs(name))
{
h = CreateFileA((LPTSTR)name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
h = CreateFileA((LPCSTR)name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (h != INVALID_HANDLE_VALUE)
goto Lok;
Expand All @@ -803,9 +765,6 @@ int file_write(char *name, void *buffer, unsigned len)
err:
return 1;
#endif
#if _MSDOS
return 1;
#endif
}

/********************************
Expand Down Expand Up @@ -853,9 +812,6 @@ int file_createdirs(char *name)
Lfail:
return 1;
#endif
#if _MSDOS
return 1;
#endif
}

/***********************************
Expand Down
2 changes: 0 additions & 2 deletions src/backend/outbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,13 @@ void Outbuffer::write32(int v)
* Writes a 64 bit long.
*/

#if __INTSIZE == 4
void Outbuffer::write64(long long v)
{
if (pend - p < 8)
reserve(8);
*(long long *)p = v;
p += 8;
}
#endif

/**
* Writes a 32 bit float.
Expand Down
2 changes: 0 additions & 2 deletions src/backend/outbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,7 @@ struct Outbuffer
/**
* Writes a 64 bit long.
*/
#if __INTSIZE == 4
void write64(long long v);
#endif

/**
* Writes a 32 bit float.
Expand Down
26 changes: 26 additions & 0 deletions src/backend/rtlsym.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,32 @@ SYMBOL_Z(TRACE_EPI_N, FLfunc,ALLREGS|mBP|mES,"_trace_epi_n",0,tstrace) \
SYMBOL_Z(TRACE_EPI_F, FLfunc,ALLREGS|mBP|mES,"_trace_epi_f",0,tstrace) \
SYMBOL_MARS(TRACE_CPRO, FLfunc,FREGSAVED,"_c_trace_pro",0,t) \
SYMBOL_MARS(TRACE_CEPI, FLfunc,FREGSAVED,"_c_trace_epi",0,t) \
\
SYMBOL_MARS(TRACENEWCLASS, FLfunc,FREGSAVED,"_d_newclassTrace", 0, t) \
SYMBOL_MARS(TRACENEWARRAYT, FLfunc,FREGSAVED,"_d_newarrayTTrace", 0, t) \
SYMBOL_MARS(TRACENEWARRAYIT, FLfunc,FREGSAVED,"_d_newarrayiTTrace", 0, t) \
SYMBOL_MARS(TRACENEWARRAYMTX, FLfunc,FREGSAVED,"_d_newarraymTXTrace", 0, t) \
SYMBOL_MARS(TRACENEWARRAYMITX, FLfunc,FREGSAVED,"_d_newarraymiTXTrace", 0, t) \
SYMBOL_MARS(TRACENEWITEMT, FLfunc,FREGSAVED,"_d_newitemTTrace", 0, t) \
SYMBOL_MARS(TRACENEWITEMIT, FLfunc,FREGSAVED,"_d_newitemiTTrace", 0, t) \
SYMBOL_MARS(TRACECALLFINALIZER, FLfunc,FREGSAVED,"_d_callfinalizerTrace", 0, t) \
SYMBOL_MARS(TRACECALLINTERFACEFINALIZER, FLfunc,FREGSAVED,"_d_callinterfacefinalizerTrace", 0, t) \
SYMBOL_MARS(TRACEDELCLASS, FLfunc,FREGSAVED,"_d_delclassTrace", 0, t) \
SYMBOL_MARS(TRACEDELINTERFACE, FLfunc,FREGSAVED,"_d_delinterfaceTrace", 0, t) \
SYMBOL_MARS(TRACEDELSTRUCT, FLfunc,FREGSAVED,"_d_delstructTrace", 0, t) \
SYMBOL_MARS(TRACEDELARRAYT, FLfunc,FREGSAVED,"_d_delarray_tTrace", 0, t) \
SYMBOL_MARS(TRACEDELMEMORY, FLfunc,FREGSAVED,"_d_delmemoryTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYLITERALTX, FLfunc,FREGSAVED,"_d_arrayliteralTXTrace", 0, t) \
SYMBOL_MARS(TRACEASSOCARRAYLITERALTX, FLfunc,FREGSAVED,"_d_assocarrayliteralTXTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYCATT, FLfunc,FREGSAVED,"_d_arraycatTTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYCATNTX, FLfunc,FREGSAVED,"_d_arraycatnTXTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYAPPENDT, FLfunc,FREGSAVED,"_d_arrayappendTTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYAPPENDCTX, FLfunc,FREGSAVED,"_d_arrayappendcTXTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYAPPENDCD, FLfunc,FREGSAVED,"_d_arrayappendcdTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYAPPENDWD, FLfunc,FREGSAVED,"_d_arrayappendwdTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYSETLENGTHT, FLfunc,FREGSAVED,"_d_arraysetlengthTTrace", 0, t) \
SYMBOL_MARS(TRACEARRAYSETLENGTHIT,FLfunc,FREGSAVED,"_d_arraysetlengthiTTrace", 0, t) \
SYMBOL_MARS(TRACEALLOCMEMORY, FLfunc,FREGSAVED,"_d_allocmemoryTrace", 0, t) \



14 changes: 12 additions & 2 deletions src/backend/strtold.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,18 @@ longdouble strtold_dm(const char *p,char **endp)
}

// Stuff mantissa directly into long double
*(long long *)&ldval = msdec;
((unsigned short *)&ldval)[4] = e2;
union U
{
longdouble ld;
struct S
{
long long mantissa;
unsigned short exp;
} s;
} u;
u.s.mantissa = msdec;
u.s.exp = e2;
ldval = u.ld;
#endif

#if 0
Expand Down
36 changes: 15 additions & 21 deletions src/backend/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ void symbol_addtotree(symbol **parent,symbol *s)
}

#endif


/*************************************
* Search for symbol in multiple symbol tables,
* starting with most recently nested one.
Expand Down Expand Up @@ -601,7 +601,7 @@ symbol * lookupsym(const char *p)

symbol * findsy(const char *p,symbol *rover)
{
#if __INTSIZE == 4 && TX86 && __DMC__
#if TX86 && __DMC__
volatile int len;
__asm
{
Expand Down Expand Up @@ -692,7 +692,7 @@ L6: mov EAX,EBX
}

#endif


/***********************************
* Create a new symbol table.
*/
Expand Down Expand Up @@ -749,7 +749,7 @@ void deletesymtab()
}

#endif


/*********************************
* Delete symbol from symbol table, taking care to delete
* all children of a symbol.
Expand Down Expand Up @@ -1145,7 +1145,7 @@ symbol *symbol_search(const char *id)
}

#endif


/*******************************************
* Hydrate a symbol tree.
*/
Expand All @@ -1166,7 +1166,7 @@ void symbol_tree_hydrate(symbol **ps)

}
#endif


/*******************************************
* Dehydrate a symbol tree.
*/
Expand All @@ -1189,7 +1189,7 @@ void symbol_tree_dehydrate(symbol **ps)
}
}
#endif


/*******************************************
* Hydrate a symbol.
*/
Expand Down Expand Up @@ -1392,7 +1392,7 @@ symbol *symbol_hydrate(symbol **ps)
return s;
}
#endif


/*******************************************
* Dehydrate a symbol.
*/
Expand Down Expand Up @@ -1617,7 +1617,7 @@ void symbol_dehydrate(symbol **ps)
}
}
#endif


/***************************
* Dehydrate threaded list of symbols.
*/
Expand Down Expand Up @@ -1773,7 +1773,7 @@ void symbol_symdefs_hydrate(symbol **ps,symbol **parent,int flag)
}

#endif


#if 0

/*************************************
Expand Down Expand Up @@ -1859,7 +1859,7 @@ void symboltable_hydrate(symbol *s,symbol **parent)
}

#endif



/************************************
* Hydrate/dehydrate an mptr_t.
Expand Down Expand Up @@ -2000,7 +2000,7 @@ int baseclass_nitems(baseclass_t *b)

#endif



/*****************************
* Go through symbol table preparing it to be written to a precompiled
* header. That means removing references to things in the .OBJ file.
Expand Down Expand Up @@ -2072,7 +2072,7 @@ void symboltable_clean(symbol *s)
}

#endif


#if SCPP

/*
Expand Down Expand Up @@ -2171,12 +2171,6 @@ void symboltable_balance(symbol **ps)
count_symbols(*ps);
//dbg_printf("Number of global symbols = %d\n",balance.nsyms);

#if __INTSIZE == 2
// Don't balance tree if we get 16 bit overflow
if (balance.nsyms >= (unsigned)(0x10000 / sizeof(symbol *)))
goto Lret;
#endif

// Use malloc instead of mem because of pagesize limits
balance.array = (symbol **) malloc(balance.nsyms * sizeof(symbol *));
if (!balance.array)
Expand All @@ -2198,7 +2192,7 @@ void symboltable_balance(symbol **ps)
}

#endif


/*****************************************
* Symbol table search routine for members of structs, given that
* we don't know which struct it is in.
Expand Down Expand Up @@ -2262,7 +2256,7 @@ symbol *symbol_membersearch(const char *id)
}
return pb.sm;
}


/*******************************************
* Generate debug info for global struct tag symbols.
*/
Expand Down
4 changes: 0 additions & 4 deletions src/backend/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,7 @@ struct token_t
int pragma; // TKpragma: PRxxxx, pragma number
// -1 if unrecognized pragma
targ_long Vlong; /* integer when TKnum */
#if LONGLONG
targ_llong Vllong;
#else
#define Vllong Vlong
#endif
targ_float Vfloat;
targ_double Vdouble;
targ_ldouble Vldouble;
Expand Down
9 changes: 2 additions & 7 deletions src/backend/ty.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,7 @@ extern int TYptrdiff, TYsize, TYsize_t;

/* Modifiers to basic types */

#ifdef JHANDLE
#define mTYarrayhandle 0x200
#else
#define mTYarrayhandle 0x0
#endif
#define mTYconst 0x100
#define mTYvolatile 0x200
#define mTYrestrict 0 // BUG: add for C99
Expand Down Expand Up @@ -222,7 +218,7 @@ extern unsigned tytab[];

#define tyaggregate(ty) (tytab[(ty) & 0xFF] & TYFLaggregate)

#define tyscalar(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr))
#define tyscalar(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr | TYFLref))

#define tyfloating(ty) (tytab[(ty) & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex))

Expand All @@ -233,7 +229,7 @@ extern unsigned tytab[];
#define tyreal(ty) (tytab[(ty) & 0xFF] & TYFLreal)

// Fits into 64 bit register
#define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr) && tysize(ty) <= NPTRSIZE)
#define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr | TYFLref) && tysize(ty) <= NPTRSIZE)

// Can go in XMM floating point register
#if TX86
Expand Down Expand Up @@ -370,4 +366,3 @@ extern unsigned short dttab4[];
#endif

#endif /* TY_H */

2 changes: 1 addition & 1 deletion src/backend/util2.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ void util_progress(int linnum)
* else -1
*/

#if TX86 && __INTSIZE == 4 && __DMC__ && !_DEBUG_TRACE
#if TX86 && __DMC__ && !_DEBUG_TRACE

int binary(const char *p, const char **table,int high)
{
Expand Down
8 changes: 2 additions & 6 deletions src/backend/var.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1985-1998 by Symantec
// Copyright (C) 2000-2010 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down Expand Up @@ -29,11 +29,7 @@
#include "tytab.c"

#if __SC__ && _MSDOS
#if __INTSIZE == 4
unsigned __cdecl _stack = 100000; // set default stack size
#else
unsigned __cdecl _stack = 60000; // set default stack size
#endif
#endif

/* Global flags:
Expand Down Expand Up @@ -153,7 +149,7 @@ int xc = ' '; // character last read
*/

int colnumber = 0; /* current column number */


/* Other variables: */

int level = 0; /* declaration level */
Expand Down
166 changes: 126 additions & 40 deletions src/cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,10 @@ MATCH implicitConvTo(Expression *e, Type *t)
result = MATCHconst;
}
}

// Enhancement 10724
if (tb->ty == Tpointer && e->e1->op == TOKstring)
e->e1->accept(this);
}
};

Expand Down Expand Up @@ -1439,15 +1443,26 @@ Expression *castTo(Expression *e, Scope *sc, Type *t)
return;
}

// Do (type *) cast of (type [dim])
if (tob->ty == Tpointer &&
t1b->ty == Tsarray)
{
//printf("Converting [dim] to *\n");
result = new AddrExp(e->loc, e);
result->type = t;
return;
}
/* Make semantic error against invalid cast between concrete types.
* Assume that 'e' is never be any placeholder expressions.
* The result of these checks should be consistent with CastExp::toElem().
*/

// Fat Value types
const bool tob_isFV = (tob->ty == Tstruct || tob->ty == Tsarray);
const bool t1b_isFV = (t1b->ty == Tstruct || t1b->ty == Tsarray);

// Fat Reference types
const bool tob_isFR = (tob->ty == Tarray || tob->ty == Tdelegate);
const bool t1b_isFR = (t1b->ty == Tarray || t1b->ty == Tdelegate);

// Reference types
const bool tob_isR = (tob_isFR || tob->ty == Tpointer || tob->ty == Taarray || tob->ty == Tclass);
const bool t1b_isR = (t1b_isFR || t1b->ty == Tpointer || t1b->ty == Taarray || t1b->ty == Tclass);

// Arithmetic types (== valueable basic types)
const bool tob_isA = (tob->isintegral() || tob->isfloating());
const bool t1b_isA = (t1b->isintegral() || t1b->isfloating());

if (AggregateDeclaration *t1ad = isAggregate(t1b))
{
Expand All @@ -1460,16 +1475,14 @@ Expression *castTo(Expression *e, Scope *sc, Type *t)
ClassDeclaration *tocd = tob->isClassHandle();
int offset;
if (tocd->isBaseOf(t1cd, &offset))
goto L1;
goto Lok;
}

/* Forward the cast to our alias this member, rewrite to:
* cast(to)e1.aliasthis
*/
result = resolveAliasThis(sc, e);
result = result->castTo(sc, t);
//result = new CastExp(e->loc, ex, t);
//result = result->semantic(sc);
return;
}
}
Expand All @@ -1482,49 +1495,121 @@ Expression *castTo(Expression *e, Scope *sc, Type *t)
result = result->semantic(sc);
return;
}
else if (tob->ty != Tvector && t1b->ty == Tvector)
{
// T[n] <-- __vector(U[m])
if (tob->ty == Tsarray)
{
if (t1b->size(e->loc) == tob->size(e->loc))
goto Lok;
}
goto Lfail;
}
else if (t1b->implicitConvTo(tob) == MATCHconst && t->equals(e->type->constOf()))
{
result = e->copy();
result->type = t;
return;
}

// Bugzlla 3133: Struct casts are possible only when the sizes match
// Same with static array -> static array
if ((t1b->ty == Tsarray || t1b->ty == Tstruct) &&
(tob->ty == Tsarray || tob->ty == Tstruct))
// arithmetic values vs. other arithmetic values
// arithmetic values vs. T*
if (tob_isA && (t1b_isA || t1b->ty == Tpointer) ||
t1b_isA && (tob_isA || tob->ty == Tpointer))
{
if (t1b->size(e->loc) != tob->size(e->loc))
goto Lfail;
goto Lok;
}
// Bugzilla 9178: Tsarray <--> typeof(null)
// Bugzilla 9904: Tstruct <--> typeof(null)
if (t1b->ty == Tnull && (tob->ty == Tsarray || tob->ty == Tstruct) ||
tob->ty == Tnull && (t1b->ty == Tsarray || t1b->ty == Tstruct))

// arithmetic values vs. references or fat values
if (tob_isA && (t1b_isR || t1b_isFV) ||
t1b_isA && (tob_isR || tob_isFV))
{
goto Lfail;
}
// Bugzilla 13959: Tstruct <--> Tpointer
if ((tob->ty == Tstruct && t1b->ty == Tpointer) ||
(t1b->ty == Tstruct && tob->ty == Tpointer))

// Bugzlla 3133: A cast between fat values is possible only when the sizes match.
if (tob_isFV && t1b_isFV)
{
goto Lfail;
if (t1b->size(e->loc) == tob->size(e->loc))
goto Lok;
e->error("cannot cast expression %s of type %s to %s because of different sizes",
e->toChars(), e->type->toChars(), t->toChars());
result = new ErrorExp();
return;
}
// Bugzilla 10646: Tclass <--> (T[] or T[n])
if (tob->ty == Tclass && (t1b->ty == Tarray || t1b->ty == Tsarray) ||
t1b->ty == Tclass && (tob->ty == Tarray || tob->ty == Tsarray))

// Fat values vs. null or references
if (tob_isFV && (t1b->ty == Tnull || t1b_isR) ||
t1b_isFV && (tob->ty == Tnull || tob_isR))
{
if (tob->ty == Tpointer && t1b->ty == Tsarray)
{
// T[n] sa;
// cast(U*)sa; // ==> cast(U*)sa.ptr;
result = new AddrExp(e->loc, e);
result->type = t;
return;
}
if (tob->ty == Tarray && t1b->ty == Tsarray)
{
// T[n] sa;
// cast(U[])sa; // ==> cast(U[])sa[];
d_uns64 fsize = t1b->nextOf()->size();
d_uns64 tsize = tob->nextOf()->size();
if ((((TypeSArray *)t1b)->dim->toInteger() * fsize) % tsize != 0)
{
// copied from sarray_toDarray() in e2ir.c
e->error("cannot cast expression %s of type %s to %s since sizes don't line up",
e->toChars(), e->type->toChars(), t->toChars());
result = new ErrorExp();
return;
}
goto Lok;
}
goto Lfail;
}
// Bugzilla 11484: (T[] or T[n]) <--> TypeBasic
// Bugzilla 11485, 7472: Tclass <--> TypeBasic
// Bugzilla 14154L Tstruct <--> TypeBasic
if (t1b->isTypeBasic() && (tob->ty == Tarray || tob->ty == Tsarray || tob->ty == Tclass || tob->ty == Tstruct) ||
tob->isTypeBasic() && (t1b->ty == Tarray || t1b->ty == Tsarray || t1b->ty == Tclass || t1b->ty == Tstruct))
{

/* For references, any reinterpret casts are allowed to same 'ty' type.
* T* to U*
* R1 function(P1) to R2 function(P2)
* R1 delegate(P1) to R2 delegate(P2)
* T[] to U[]
* V1[K1] to V2[K2]
* class/interface A to B (will be a dynamic cast if possible)
*/
if (tob->ty == t1b->ty && tob_isR && t1b_isR)
goto Lok;

// typeof(null) <-- non-null references or values
if (tob->ty == Tnull && t1b->ty != Tnull)
goto Lfail; // Bugzilla 14629
// typeof(null) --> non-null references or arithmetic values
if (t1b->ty == Tnull && tob->ty != Tnull)
goto Lok;

// Check size mismatch of references.
// Tarray and Tdelegate are (void*).sizeof*2, but others have (void*).sizeof.
if (tob_isFR && t1b_isR ||
t1b_isFR && tob_isR)
{
if (tob->ty == Tpointer && t1b->ty == Tarray)
{
// T[] da;
// cast(U*)da; // ==> cast(U*)da.ptr;
goto Lok;
}
if (tob->ty == Tpointer && t1b->ty == Tdelegate)
{
// void delegate() dg;
// cast(U*)dg; // ==> cast(U*)dg.ptr;
// Note that it happens even when U is a Tfunction!
e->deprecation("casting from %s to %s is deprecated", e->type->toChars(), t->toChars());
goto Lok;
}
goto Lfail;
}
if (t1b->ty == Tvoid && tob->ty != Tvoid && e->op != TOKfunction)

if (t1b->ty == Tvoid && tob->ty != Tvoid)
{
Lfail:
e->error("cannot cast expression %s of type %s to %s",
Expand All @@ -1533,7 +1618,7 @@ Expression *castTo(Expression *e, Scope *sc, Type *t)
return;
}

L1:
Lok:
result = new CastExp(e->loc, e, tob);
result->type = t; // Don't call semantic()
//printf("Returning: %s\n", result->toChars());
Expand Down Expand Up @@ -1962,7 +2047,7 @@ Expression *castTo(Expression *e, Scope *sc, Type *t)
* TypeTuple!(int, int) values;
* auto values2 = cast(long)values;
* // typeof(values2) == TypeTuple!(int, int) !!
*
*
* Only when the casted tuple is immediately expanded, it would work.
* auto arr = [cast(long)values];
* // typeof(arr) == long[]
Expand Down Expand Up @@ -3049,8 +3134,9 @@ bool typeMerge(Scope *sc, TOK op, Type **pt, Expression **pe1, Expression **pe2)
{
e1 = integralPromotions(e1, sc);
e2 = integralPromotions(e2, sc);
t1 = e1->type; t1b = t1->toBasetype();
t2 = e2->type; t2b = t2->toBasetype();
t1 = e1->type;
t2 = e2->type;
goto Lagain;
}
assert(t1->ty == t2->ty);
if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
Expand Down
34 changes: 34 additions & 0 deletions src/checkwhitespace.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import std.stdio;
import std.file;
import std.string;
import std.range;
import std.regex;
import std.algorithm;
import std.path;

int main(string[] args)
{
bool error;
auto r = regex(r" +\n");
foreach(a; args[1..$])
{
auto str = a.readText();
if (str.canFind("\r\n"))
{
writefln("Error - file '%s' contains windows line endings", a);
error = true;
}
if (a.extension() != ".mak" && str.canFind('\t'))
{
writefln("Error - file '%s' contains tabs", a);
error = true;
}
if (!str.matchFirst(r).empty)
{
writefln("Error - file '%s' contains trailing whitespace", a);
error = true;
}
}
return error ? 1 : 0;
}
340 changes: 202 additions & 138 deletions src/class.c

Large diffs are not rendered by default.

267 changes: 142 additions & 125 deletions src/clone.c

Large diffs are not rendered by default.

110 changes: 110 additions & 0 deletions src/complex.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

module ddmd.complex;

struct complex_t
{
real re = 0;
real im = 0;
this(real re)
{
this.re = re;
this.im = 0;
}

this(real re, real im)
{
this.re = re;
this.im = im;
}

complex_t opAdd(complex_t y)
{
complex_t r;
r.re = re + y.re;
r.im = im + y.im;
return r;
}

complex_t opSub(complex_t y)
{
complex_t r;
r.re = re - y.re;
r.im = im - y.im;
return r;
}

complex_t opNeg()
{
complex_t r;
r.re = -re;
r.im = -im;
return r;
}

complex_t opMul(complex_t y)
{
return complex_t(re * y.re - im * y.im, im * y.re + re * y.im);
}

complex_t opMul_r(real x)
{
return complex_t(x) * this;
}

complex_t opMul(real y)
{
return this * complex_t(y);
}

complex_t opDiv(real y)
{
return this / complex_t(y);
}

complex_t opDiv(complex_t y)
{
real abs_y_re = y.re < 0 ? -y.re : y.re;
real abs_y_im = y.im < 0 ? -y.im : y.im;
real r, den;

if (abs_y_re < abs_y_im)
{
r = y.re / y.im;
den = y.im + r * y.re;
return complex_t((re * r + im) / den, (im * r - re) / den);
}
else
{
r = y.im / y.re;
den = y.re + r * y.im;
return complex_t((re + r * im) / den, (im - r * re) / den);
}
}

bool opCast(T : bool)()
{
return re || im;
}

int opEquals(complex_t y)
{
return re == y.re && im == y.im;
}
}

real creall(complex_t x)
{
return x.re;
}

real cimagl(complex_t x)
{
return x.im;
}
7 changes: 6 additions & 1 deletion src/cond.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,12 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *sds)
sc->pop();
--nest;

if (!e->type->checkBoolean())
// Prevent repeated condition evaluation.
// See: fail_compilation/fail7815.d
if (inc != 0)
return (inc == 1);

if (!e->type->isBoolean())
{
if (e->type->toBasetype() != Type::terror)
exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars());
Expand Down
37 changes: 20 additions & 17 deletions src/constfold.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ UnionExp Div(Type *type, Expression *e1, Expression *e2)
n2 = 1;
}
if (e1->type->isunsigned() || e2->type->isunsigned())
n = ((d_uns64) n1) / ((d_uns64) n2);
n = ((dinteger_t) n1) / ((dinteger_t) n2);
else
n = n1 / n2;
new(&ue) IntegerExp(loc, n, type);
Expand Down Expand Up @@ -483,7 +483,7 @@ UnionExp Mod(Type *type, Expression *e1, Expression *e2)
}
}
if (e1->type->isunsigned() || e2->type->isunsigned())
n = ((d_uns64) n1) % ((d_uns64) n2);
n = ((dinteger_t) n1) % ((dinteger_t) n2);
else
n = n1 % n2;
new(&ue) IntegerExp(loc, n, type);
Expand Down Expand Up @@ -1108,19 +1108,19 @@ UnionExp Cmp(TOK op, Type *type, Expression *e1, Expression *e2)
{
switch (op)
{
case TOKlt: n = ((d_uns64) n1) < ((d_uns64) n2); break;
case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2); break;
case TOKgt: n = ((d_uns64) n1) > ((d_uns64) n2); break;
case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2); break;

case TOKleg: n = 1; break;
case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2); break;
case TOKunord: n = 0; break;
case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2); break;
case TOKug: n = ((d_uns64) n1) > ((d_uns64) n2); break;
case TOKuge: n = ((d_uns64) n1) >= ((d_uns64) n2); break;
case TOKul: n = ((d_uns64) n1) < ((d_uns64) n2); break;
case TOKule: n = ((d_uns64) n1) <= ((d_uns64) n2); break;
case TOKlt: n = ((dinteger_t) n1) < ((dinteger_t) n2); break;
case TOKle: n = ((dinteger_t) n1) <= ((dinteger_t) n2); break;
case TOKgt: n = ((dinteger_t) n1) > ((dinteger_t) n2); break;
case TOKge: n = ((dinteger_t) n1) >= ((dinteger_t) n2); break;

case TOKleg: n = 1; break;
case TOKlg: n = ((dinteger_t) n1) != ((dinteger_t) n2); break;
case TOKunord: n = 0; break;
case TOKue: n = ((dinteger_t) n1) == ((dinteger_t) n2); break;
case TOKug: n = ((dinteger_t) n1) > ((dinteger_t) n2); break;
case TOKuge: n = ((dinteger_t) n1) >= ((dinteger_t) n2); break;
case TOKul: n = ((dinteger_t) n1) < ((dinteger_t) n2); break;
case TOKule: n = ((dinteger_t) n1) <= ((dinteger_t) n2); break;

default:
assert(0);
Expand Down Expand Up @@ -1161,7 +1161,6 @@ UnionExp Cmp(TOK op, Type *type, Expression *e1, Expression *e2)
UnionExp Cast(Type *type, Type *to, Expression *e1)
{
UnionExp ue;
Expression *e = CTFEExp::cantexp;
Loc loc = e1->loc;

Type *tb = to->toBasetype();
Expand Down Expand Up @@ -1303,7 +1302,11 @@ UnionExp Cast(Type *type, Type *to, Expression *e1)
else
{
if (type != Type::terror)
{
// have to change to Internal Compiler Error
// all invalid casts should be handled already in Expression::castTo().
error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars());
}
new(&ue) ErrorExp();
}
return ue;
Expand Down Expand Up @@ -1441,7 +1444,7 @@ UnionExp Index(Type *type, Expression *e1, Expression *e2)
new(&ue) CTFEExp(TOKcantexp);
else
new(&ue) UnionExp(e);
return ue;;
return ue;
}
}
new(&ue) CTFEExp(TOKcantexp);
Expand Down
133 changes: 83 additions & 50 deletions src/cppmangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,8 @@ class CppMangleVisitor : public Visitor
case Tfloat32: c = 'f'; break;
case Tint64: c = (Target::c_longsize == 8 ? 'l' : 'x'); break;
case Tuns64: c = (Target::c_longsize == 8 ? 'm' : 'y'); break;
case Tint128: c = 'n'; break;
case Tuns128: c = 'o'; break;
case Tfloat64: c = 'd'; break;
case Tfloat80: c = (Target::realsize - Target::realpad == 16) ? 'g' : 'e'; break;
case Tbool: c = 'b'; break;
Expand Down Expand Up @@ -662,7 +664,8 @@ class CppMangleVisitor : public Visitor
void visit(TypeVector *t)
{
is_top_level = false;
if (substitute(t)) return;
if (substitute(t))
return;
store(t);
if (t->isImmutable() || t->isShared())
{
Expand Down Expand Up @@ -705,7 +708,8 @@ class CppMangleVisitor : public Visitor
void visit(TypePointer *t)
{
is_top_level = false;
if (substitute(t)) return;
if (substitute(t))
return;
if (t->isImmutable() || t->isShared())
{
visit((Type *)t);
Expand All @@ -720,7 +724,8 @@ class CppMangleVisitor : public Visitor
void visit(TypeReference *t)
{
is_top_level = false;
if (substitute(t)) return;
if (substitute(t))
return;
buf.writeByte('R');
t->next->accept(this);
store(t);
Expand Down Expand Up @@ -751,7 +756,8 @@ class CppMangleVisitor : public Visitor
TypeFunctions for non-static member functions, and non-static
member functions of different classes.
*/
if (substitute(t)) return;
if (substitute(t))
return;
buf.writeByte('F');
if (t->linkage == LINKc)
buf.writeByte('Y');
Expand Down Expand Up @@ -807,7 +813,8 @@ class CppMangleVisitor : public Visitor

is_top_level = false;

if (substitute(t)) return;
if (substitute(t))
return;
if (t->isImmutable() || t->isShared())
{
visit((Type *)t);
Expand All @@ -832,7 +839,8 @@ class CppMangleVisitor : public Visitor
void visit(TypeEnum *t)
{
is_top_level = false;
if (substitute(t)) return;
if (substitute(t))
return;

if (t->isConst())
buf.writeByte('K');
Expand All @@ -853,7 +861,8 @@ class CppMangleVisitor : public Visitor

void visit(TypeClass *t)
{
if (substitute(t)) return;
if (substitute(t))
return;
if (t->isImmutable() || t->isShared())
{
visit((Type *)t);
Expand Down Expand Up @@ -958,7 +967,8 @@ class VisualCPPMangler : public Visitor

if (type->isConst() && ((flags & IS_NOT_TOP_TYPE) || (flags & IS_DMC)))
{
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
}

if ((type->ty == Tbool) && checkTypeSaved(type))// try to replace long name with number
Expand Down Expand Up @@ -1006,7 +1016,8 @@ class VisualCPPMangler : public Visitor
void visit(TypeVector *type)
{
//printf("visit(TypeVector); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
buf.writestring("T__m128@@"); // may be better as __m128i or __m128d?
flags &= ~IS_NOT_TOP_TYPE;
flags &= ~IGNORE_CONST;
Expand All @@ -1016,7 +1027,8 @@ class VisualCPPMangler : public Visitor
{
// This method can be called only for static variable type mangling.
//printf("visit(TypeSArray); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
// first dimension always mangled as const pointer
if (flags & IS_DMC)
buf.writeByte('Q');
Expand Down Expand Up @@ -1112,7 +1124,8 @@ class VisualCPPMangler : public Visitor
void visit(TypeReference *type)
{
//printf("visit(TypeReference); type = %s\n", type->toChars());
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;

if (type->isImmutable() || type->isShared())
{
Expand All @@ -1138,8 +1151,19 @@ class VisualCPPMangler : public Visitor

void visit(TypeFunction *type)
{
// We can mangle pointer to a function, not function.
visit((Type*)type);
const char *arg = mangleFunctionType(type);

if ((flags & IS_DMC))
{
if (checkTypeSaved(type))
return;
}
else
{
buf.writestring("$$A6");
}
buf.writestring(arg);
flags &= ~(IS_NOT_TOP_TYPE | IGNORE_CONST);
}

void visit(TypeStruct *type)
Expand All @@ -1165,15 +1189,17 @@ class VisualCPPMangler : public Visitor

if (type->isConst() && ((flags & IS_NOT_TOP_TYPE) || (flags & IS_DMC)))
{
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
}

mangleModifier(type);
buf.writeByte(c);
}
else
{
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
//printf("visit(TypeStruct); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
mangleModifier(type);
if (type->sym->isUnionDeclaration())
Expand All @@ -1189,7 +1215,8 @@ class VisualCPPMangler : public Visitor
void visit(TypeEnum *type)
{
//printf("visit(TypeEnum); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
mangleModifier(type);
buf.writeByte('W');

Expand Down Expand Up @@ -1235,7 +1262,8 @@ class VisualCPPMangler : public Visitor
void visit(TypeClass *type)
{
//printf("visit(TypeClass); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
if (checkTypeSaved(type)) return;
if (checkTypeSaved(type))
return;
if (flags & IS_NOT_TOP_TYPE)
mangleModifier(type);

Expand Down Expand Up @@ -1588,7 +1616,8 @@ class VisualCPPMangler : public Visitor
}
else
{
if (checkAndSaveIdent(name)) return;
if (checkAndSaveIdent(name))
return;
}
}
buf.writestring(name);
Expand Down Expand Up @@ -1699,8 +1728,10 @@ class VisualCPPMangler : public Visitor

bool checkTypeSaved(Type *type)
{
if (flags & IS_NOT_TOP_TYPE) return false;
if (flags & MANGLE_RETURN_TYPE) return false;
if (flags & IS_NOT_TOP_TYPE)
return false;
if (flags & MANGLE_RETURN_TYPE)
return false;
for (size_t i = 0; i < VC_SAVED_TYPE_CNT; i++)
{
if (!saved_types[i]) // no saved same type
Expand All @@ -1721,7 +1752,8 @@ class VisualCPPMangler : public Visitor

void mangleModifier(Type *type)
{
if (flags & IGNORE_CONST) return;
if (flags & IGNORE_CONST)
return;
if (type->isImmutable() || type->isShared())
{
visit((Type*)type);
Expand Down Expand Up @@ -1761,6 +1793,35 @@ class VisualCPPMangler : public Visitor
cur->accept(this);
}

static int mangleParameterDg(void *ctx, size_t n, Parameter *p)
{
VisualCPPMangler *mangler = (VisualCPPMangler *)ctx;

Type *t = p->type;
if (p->storageClass & (STCout | STCref))
{
t = t->referenceTo();
}
else if (p->storageClass & STClazy)
{
// Mangle as delegate
Type *td = new TypeFunction(NULL, t, 0, LINKd);
td = new TypeDelegate(td);
t = t->merge();
}
if (t->ty == Tsarray)
{
t->error(Loc(), "Internal Compiler Error: unable to pass static array to extern(C++) function.");
t->error(Loc(), "Use pointer instead.");
assert(0);
}
mangler->flags &= ~IS_NOT_TOP_TYPE;
mangler->flags &= ~IGNORE_CONST;
t->accept(mangler);

return 0;
}

const char *mangleFunctionType(TypeFunction *type, bool needthis = false, bool noreturn = false)
{
VisualCPPMangler tmp(this);
Expand Down Expand Up @@ -1829,10 +1890,7 @@ class VisualCPPMangler : public Visitor
}
else
{
for (size_t i = 0; i < type->parameters->dim; ++i)
{
tmp.mangleParameter((*type->parameters)[i]);
}
Parameter::foreach(type->parameters, &mangleParameterDg, (void*)&tmp);
if (type->varargs == 1)
{
tmp.buf.writeByte('Z');
Expand All @@ -1849,31 +1907,6 @@ class VisualCPPMangler : public Visitor
memcpy(&saved_types, &tmp.saved_types, sizeof(Type*) * VC_SAVED_TYPE_CNT);
return ret;
}

void mangleParameter(Parameter *p)
{
Type *t = p->type;
if (p->storageClass & (STCout | STCref))
{
t = t->referenceTo();
}
else if (p->storageClass & STClazy)
{
// Mangle as delegate
Type *td = new TypeFunction(NULL, t, 0, LINKd);
td = new TypeDelegate(td);
t = t->merge();
}
if (t->ty == Tsarray)
{
t->error(Loc(), "Internal Compiler Error: unable to pass static array to extern(C++) function.");
t->error(Loc(), "Use pointer instead.");
assert(0);
}
flags &= ~IS_NOT_TOP_TYPE;
flags &= ~IGNORE_CONST;
t->accept(this);
}
};

char *toCppMangle(Dsymbol *s)
Expand Down
1 change: 1 addition & 0 deletions src/ctfe.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class CTFEExp : public Expression
static CTFEExp *gotoexp;

static bool isCantExp(Expression *e) { return e && e->op == TOKcantexp; }
static bool isGotoExp(Expression *e) { return e && e->op == TOKgoto; }
};

/****************************************************************/
Expand Down
101 changes: 63 additions & 38 deletions src/ctfeexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,11 @@ bool needToCopyLiteral(Expression *expr)
switch (expr->op)
{
case TOKarrayliteral:
return ((ArrayLiteralExp *)expr)->ownedByCtfe == 0;
return ((ArrayLiteralExp *)expr)->ownedByCtfe == OWNEDcode;
case TOKassocarrayliteral:
return ((AssocArrayLiteralExp *)expr)->ownedByCtfe == 0;
return ((AssocArrayLiteralExp *)expr)->ownedByCtfe == OWNEDcode;
case TOKstructliteral:
return ((StructLiteralExp *)expr)->ownedByCtfe == 0;
return ((StructLiteralExp *)expr)->ownedByCtfe == OWNEDcode;
case TOKstring:
case TOKthis:
case TOKvar:
Expand Down Expand Up @@ -268,7 +268,7 @@ UnionExp copyLiteral(Expression *e)
se2->postfix = se->postfix;
se2->type = se->type;
se2->sz = se->sz;
se2->ownedByCtfe = 1;
se2->ownedByCtfe = OWNEDctfe;
return ue;
}
if (e->op == TOKarrayliteral)
Expand All @@ -277,7 +277,7 @@ UnionExp copyLiteral(Expression *e)
new(&ue) ArrayLiteralExp(e->loc, copyLiteralArray(ae->elements));
ArrayLiteralExp *r = (ArrayLiteralExp *)ue.exp();
r->type = e->type;
r->ownedByCtfe = 1;
r->ownedByCtfe = OWNEDctfe;
return ue;
}
if (e->op == TOKassocarrayliteral)
Expand All @@ -286,7 +286,7 @@ UnionExp copyLiteral(Expression *e)
new(&ue) AssocArrayLiteralExp(e->loc, copyLiteralArray(aae->keys), copyLiteralArray(aae->values));
AssocArrayLiteralExp *r = (AssocArrayLiteralExp *)ue.exp();
r->type = e->type;
r->ownedByCtfe = 1;
r->ownedByCtfe = OWNEDctfe;
return ue;
}
if (e->op == TOKstructliteral)
Expand Down Expand Up @@ -322,7 +322,7 @@ UnionExp copyLiteral(Expression *e)
new(&ue) StructLiteralExp(e->loc, se->sd, newelems, se->stype);
StructLiteralExp *r = (StructLiteralExp *)ue.exp();
r->type = e->type;
r->ownedByCtfe = 1;
r->ownedByCtfe = OWNEDctfe;
r->origin = ((StructLiteralExp *)e)->origin;
return ue;
}
Expand All @@ -331,7 +331,8 @@ UnionExp copyLiteral(Expression *e)
e->op == TOKvar || e->op == TOKdotvar ||
e->op == TOKint64 || e->op == TOKfloat64 ||
e->op == TOKchar || e->op == TOKcomplex80 ||
e->op == TOKvoid || e->op == TOKvector)
e->op == TOKvoid || e->op == TOKvector ||
e->op == TOKtypeid)
{
// Simple value types
// Keep e1 for DelegateExp and DotVarExp
Expand Down Expand Up @@ -373,7 +374,7 @@ UnionExp copyLiteral(Expression *e)
assert(ue.exp()->op == TOKarrayliteral);
ArrayLiteralExp *r = (ArrayLiteralExp *)ue.exp();
r->elements = copyLiteralArray(r->elements);
r->ownedByCtfe = 1;
r->ownedByCtfe = OWNEDctfe;
return ue;
}
else
Expand Down Expand Up @@ -457,7 +458,7 @@ UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit)
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)lit;
// TODO: we should be creating a reference to this AAExp, not
// just a ref to the keys and values.
int wasOwned = aae->ownedByCtfe;
OwnedBy wasOwned = aae->ownedByCtfe;
new(&ue) AssocArrayLiteralExp(lit->loc, aae->keys, aae->values);
aae = (AssocArrayLiteralExp *)ue.exp();
aae->ownedByCtfe = wasOwned;
Expand Down Expand Up @@ -544,7 +545,7 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
}
ArrayLiteralExp *ale = new ArrayLiteralExp(loc, elements);
ale->type = type;
ale->ownedByCtfe = 1;
ale->ownedByCtfe = OWNEDctfe;
return ale;
}

Expand All @@ -570,7 +571,7 @@ StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
se->type = type;
se->sz = sz;
se->committed = true;
se->ownedByCtfe = 1;
se->ownedByCtfe = OWNEDctfe;
return se;
}

Expand Down Expand Up @@ -651,8 +652,15 @@ bool isSafePointerCast(Type *srcPointee, Type *destPointee)
// It's OK if they are the same size (static array of) integers, eg:
// int* --> uint*
// int[5][] --> uint[5][]
return srcPointee->baseElemOf()->isintegral() &&
destPointee->baseElemOf()->isintegral() &&
if (srcPointee->ty == Tsarray && destPointee->ty == Tsarray)
{
if (srcPointee->size() != destPointee->size())
return false;
srcPointee = srcPointee->baseElemOf();
destPointee = destPointee->baseElemOf();
}
return srcPointee->isintegral() &&
destPointee->isintegral() &&
srcPointee->size() == destPointee->size();
}

Expand Down Expand Up @@ -1020,7 +1028,7 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp
result = 1;
}
else if (e1->type->isunsigned() || e2->type->isunsigned())
result = ((d_uns64) n1) / ((d_uns64) n2);
result = ((dinteger_t) n1) / ((dinteger_t) n2);
else
result = n1 / n2;
break;
Expand Down Expand Up @@ -1050,7 +1058,7 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp
}
}
if (e1->type->isunsigned() || e2->type->isunsigned())
result = ((d_uns64) n1) % ((d_uns64) n2);
result = ((dinteger_t) n1) % ((dinteger_t) n2);
else
result = n1 % n2;
break;
Expand Down Expand Up @@ -1200,7 +1208,7 @@ bool isCtfeComparable(Expression *e)
return true;
}
// Bugzilla 14123: TypeInfo object is comparable in CTFE
if (e->op == TOKsymoff && ((SymOffExp *)e)->var->isTypeInfoDeclaration())
if (e->op == TOKtypeid)
return true;

return false;
Expand All @@ -1209,7 +1217,7 @@ bool isCtfeComparable(Expression *e)
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
int intUnsignedCmp(TOK op, d_uns64 n1, d_uns64 n2)
int intUnsignedCmp(TOK op, dinteger_t n1, dinteger_t n2)
{
int n;
switch (op)
Expand Down Expand Up @@ -1357,7 +1365,7 @@ int ctfeCmpArrays(Loc loc, Expression *e1, Expression *e2, uinteger_t len)
// If they aren't strings, we just need an equality check rather than
// a full cmp.
bool needCmp = ae1->type->nextOf()->isintegral();
for (size_t i = 0; i < len; i++)
for (size_t i = 0; i < (size_t)len; i++)
{
Expression *ee1 = (*ae1->elements)[(size_t)(lo1 + i)];
Expression *ee2 = (*ae2->elements)[(size_t)(lo2 + i)];
Expand Down Expand Up @@ -1411,6 +1419,16 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
return 0;
return 1;
}
if (e1->op == TOKtypeid && e2->op == TOKtypeid)
{
// printf("e1: %s\n", e1->toChars());
// printf("e2: %s\n", e2->toChars());
Type *t1 = isType(((TypeidExp *)e1)->obj);
Type *t2 = isType(((TypeidExp *)e2)->obj);
assert(t1);
assert(t2);
return t1 != t2;
}

// null == null, regardless of type

Expand Down Expand Up @@ -1557,22 +1575,23 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
{
Expression *k1 = (*es1->keys)[i];
Expression *v1 = (*es1->values)[i];

Expression *v2 = NULL;
for (size_t j = 0; j < dim; ++j)
{
if (used[j])
continue;
Expression *k2 = (*es2->keys)[j];
Expression *v2 = (*es2->values)[j];

if (ctfeRawCmp(loc, k1, k2))
continue;
used[j] = true;
if (ctfeRawCmp(loc, v1, v2))
{
mem.xfree(used);
return 1;
}
v2 = (*es2->values)[j];
break;
}
if (!v2 || ctfeRawCmp(loc, v1, v2))
{
mem.xfree(used);
return 1;
}
}
mem.xfree(used);
Expand Down Expand Up @@ -1684,7 +1703,6 @@ UnionExp ctfeCat(Type *type, Expression *e1, Expression *e2)
Loc loc = e1->loc;
Type *t1 = e1->type->toBasetype();
Type *t2 = e2->type->toBasetype();
Expression *e;
UnionExp ue;
if (e2->op == TOKstring && e1->op == TOKarrayliteral &&
t1->nextOf()->isintegral())
Expand Down Expand Up @@ -1878,9 +1896,9 @@ Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e)
if (CTFEExp::isCantExp(r))
error(loc, "cannot cast %s to %s at compile time", e->toChars(), to->toChars());
if (e->op == TOKarrayliteral)
((ArrayLiteralExp *)e)->ownedByCtfe = 1;
((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDctfe;
if (e->op == TOKstring)
((StringExp *)e)->ownedByCtfe = 1;
((StringExp *)e)->ownedByCtfe = OWNEDctfe;
return r;
}

Expand Down Expand Up @@ -2006,11 +2024,11 @@ Expression *modifyStructField(Type *type, StructLiteralExp *se, size_t offset, E
Expressions *expsx = changeOneElement(se->elements, fieldi, newval);
StructLiteralExp * ee = new StructLiteralExp(se->loc, se->sd, expsx);
ee->type = se->type;
ee->ownedByCtfe = 1;
ee->ownedByCtfe = OWNEDctfe;
return ee;
}

// Given an AA literal aae, set arr[index] = newval and return the new array.
// Given an AA literal aae, set aae[index] = newval and return newval.
Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae,
Expression *index, Expression *newval)
{
Expand Down Expand Up @@ -2081,15 +2099,17 @@ UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
se->type = arrayType;
se->sz = oldse->sz;
se->committed = oldse->committed;
se->ownedByCtfe = 1;
se->ownedByCtfe = OWNEDctfe;
}
else
{
if (oldlen != 0)
{
assert(oldval->op == TOKarrayliteral);
ArrayLiteralExp *ae = (ArrayLiteralExp *)oldval;
for (size_t i = 0; i < copylen; i++)
(*elements)[i] = (*ae->elements)[indxlo + i];
ArrayLiteralExp *ae = (ArrayLiteralExp *)oldval;
for (size_t i = 0; i < copylen; i++)
(*elements)[i] = (*ae->elements)[indxlo + i];
}
if (elemType->ty == Tstruct || elemType->ty == Tsarray)
{
/* If it is an aggregate literal representing a value type,
Expand All @@ -2106,7 +2126,7 @@ UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
new(&ue) ArrayLiteralExp(loc, elements);
ArrayLiteralExp *aae = (ArrayLiteralExp *)ue.exp();
aae->type = arrayType;
aae->ownedByCtfe = 1;
aae->ownedByCtfe = OWNEDctfe;
}
return ue;
}
Expand Down Expand Up @@ -2164,6 +2184,11 @@ bool isCtfeValueValid(Expression *newval)
Declaration *d = ((SymOffExp *)newval)->var;
return d->isFuncDeclaration() || d->isDataseg();
}
if (newval->op == TOKtypeid)
{
// always valid
return true;
}
if (newval->op == TOKaddress)
{
// e1 should be a CTFE reference
Expand Down Expand Up @@ -2362,7 +2387,7 @@ UnionExp voidInitLiteral(Type *t, VarDeclaration *var)
new(&ue) ArrayLiteralExp(var->loc, elements);
ArrayLiteralExp *ae = (ArrayLiteralExp *)ue.exp();
ae->type = tsa;
ae->ownedByCtfe = 1;
ae->ownedByCtfe = OWNEDctfe;
}
else if (t->ty == Tstruct)
{
Expand All @@ -2376,7 +2401,7 @@ UnionExp voidInitLiteral(Type *t, VarDeclaration *var)
new(&ue) StructLiteralExp(var->loc, ts->sym, exps);
StructLiteralExp *se = (StructLiteralExp *)ue.exp();
se->type = ts;
se->ownedByCtfe = 1;
se->ownedByCtfe = OWNEDctfe;
}
else
new(&ue) VoidInitExp(var, t);
Expand Down
Loading