Browse files

Merge dmd-1.074 into ldc.

  • Loading branch information...
1 parent f1998a6 commit 1c6ff32d507218acf2ac02f2bb4eaeec3a6b2fce @redstar redstar committed Apr 13, 2012
Showing with 5,533 additions and 4,034 deletions.
  1. +21 −8 dmd/aggregate.h
  2. +151 −180 dmd/attrib.c
  3. +6 −3 dmd/attrib.h
  4. +3 −4 dmd/cast.c
  5. +71 −41 dmd/class.c
  6. +19 −3 dmd/cond.c
  7. +4 −1 dmd/cond.h
  8. +118 −8 dmd/declaration.c
  9. +3 −0 dmd/declaration.h
  10. +3 −0 dmd/doc.c
  11. +57 −11 dmd/dsymbol.c
  12. +8 −1 dmd/dsymbol.h
  13. +162 −154 dmd/expression.c
  14. +24 −5 dmd/expression.h
  15. +29 −9 dmd/func.c
  16. +4 −4 dmd/html.c
  17. +21 −5 dmd/import.c
  18. +40 −34 dmd/init.c
  19. +21 −1 dmd/inline.c
  20. +300 −90 dmd/interpret.c
  21. +33 −1 dmd/lexer.c
  22. +2 −0 dmd/lexer.h
  23. +6 −1 dmd/mars.c
  24. +6 −0 dmd/mars.h
  25. +31 −14 dmd/module.c
  26. +3 −2 dmd/module.h
  27. +60 −15 dmd/mtype.c
  28. +6 −2 dmd/mtype.h
  29. +3 −2 dmd/parse.c
  30. +188 −188 dmd/root/aav.c
  31. +11 −11 dmd/root/aav.h
  32. +257 −257 dmd/root/array.c
  33. +325 −325 dmd/root/async.c
  34. +33 −33 dmd/root/async.h
  35. +482 −482 dmd/root/dchar.c
  36. +194 −194 dmd/root/dchar.h
  37. +636 −0 dmd/root/longdouble.c
  38. +254 −0 dmd/root/longdouble.h
  39. +63 −63 dmd/root/lstring.c
  40. +74 −72 dmd/root/lstring.h
  41. +100 −100 dmd/root/man.c
  42. +655 −796 dmd/root/port.c
  43. +83 −81 dmd/root/port.h
  44. +29 −29 dmd/root/root.c
  45. +428 −425 dmd/root/root.h
  46. +139 −139 dmd/root/stringtable.c
  47. +48 −48 dmd/root/stringtable.h
  48. +0 −2 dmd/scope.c
  49. +5 −2 dmd/scope.h
  50. +6 −1 dmd/speller.c
  51. +21 −3 dmd/statement.c
  52. +85 −105 dmd/struct.c
  53. +196 −75 dmd/template.c
  54. +6 −4 dmd/template.h
View
29 dmd/aggregate.h
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -51,6 +51,13 @@ namespace llvm
}
#endif
+enum Sizeok
+{
+ SIZEOKnone, // size of aggregate is not computed yet
+ SIZEOKdone, // size of aggregate is set correctly
+ SIZEOKfwd, // error in computing size of aggregate
+};
+
struct AggregateDeclaration : ScopeDsymbol
{
Type *type;
@@ -62,10 +69,7 @@ struct AggregateDeclaration : ScopeDsymbol
unsigned structalign; // struct member alignment in effect
int hasUnions; // set if aggregate has overlapping fields
VarDeclarations fields; // VarDeclaration fields
- unsigned sizeok; // set when structsize contains valid data
- // 0: no size
- // 1: size is correct
- // 2: cannot determine size; fwd referenced
+ enum Sizeok sizeok; // set when structsize contains valid data
int isdeprecated; // !=0 if deprecated
#if DMDV2
@@ -89,7 +93,8 @@ struct AggregateDeclaration : ScopeDsymbol
FuncDeclaration *dtor; // aggregate destructor
#ifdef IN_GCC
- Array methods; // flat list of all methods for debug information
+ Expressions *attributes; // GCC decl/type attributes
+ FuncDeclarations methods; // flat list of all methods for debug information
#endif
AggregateDeclaration(Loc loc, Identifier *id);
@@ -98,8 +103,10 @@ struct AggregateDeclaration : ScopeDsymbol
void inlineScan();
unsigned size(Loc loc);
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
+ static unsigned placeField(unsigned *nextoffset,
+ unsigned memsize, unsigned memalignsize, unsigned memalign,
+ unsigned *paggsize, unsigned *paggalignsize, bool isunion);
Type *getType();
- void addField(Scope *sc, VarDeclaration *v);
int firstFieldInUnion(int indx); // first field in union that includes indx
int numFieldsInUnion(int firstIndex); // #fields in union starting at index
int isDeprecated(); // is aggregate deprecated?
@@ -163,14 +170,19 @@ struct StructDeclaration : AggregateDeclaration
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
const char *kind();
+ void finalizeSize(Scope *sc);
#if DMDV1
Expression *cloneMembers();
#endif
#if DMDV2
int needOpAssign();
+ int needOpEquals();
FuncDeclaration *buildOpAssign(Scope *sc);
+ FuncDeclaration *buildOpEquals(Scope *sc);
FuncDeclaration *buildPostBlit(Scope *sc);
FuncDeclaration *buildCpCtor(Scope *sc);
+
+ FuncDeclaration *buildXopEquals(Scope *sc);
#endif
void toDocBuffer(OutBuffer *buf);
@@ -222,7 +234,8 @@ struct BaseClass
};
#if DMDV2
-#define CLASSINFO_SIZE (0x3C+16+4) // value of ClassInfo.size
+#define CLASSINFO_SIZE_64 0x98 // value of ClassInfo.size
+#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#else
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#define CLASSINFO_SIZE_64 (0x98) // value of ClassInfo.size
View
331 dmd/attrib.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -54,15 +54,33 @@ Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
return decl;
}
+int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
+{
+ Dsymbols *d = include(NULL, NULL);
+
+ if (d)
+ {
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
+ if (s)
+ {
+ if (s->apply(fp, param))
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
int m = 0;
Dsymbols *d = include(sc, sd);
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
//printf("\taddMember %s to %s\n", s->toChars(), sd->toChars());
m |= s->addMember(sc, sd, m | memnum);
}
@@ -92,8 +110,8 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
newsc->explicitProtection = explicitProtection;
newsc->structalign = structalign;
}
- for (unsigned i = 0; i < decl->dim; i++)
- { Dsymbol *s = decl->tdata()[i];
+ for (size_t i = 0; i < decl->dim; i++)
+ { Dsymbol *s = (*decl)[i];
s->setScope(newsc); // yes, the only difference from semanticNewSc()
}
@@ -127,8 +145,8 @@ void AttribDeclaration::semanticNewSc(Scope *sc,
newsc->explicitProtection = explicitProtection;
newsc->structalign = structalign;
}
- for (unsigned i = 0; i < decl->dim; i++)
- { Dsymbol *s = decl->tdata()[i];
+ for (size_t i = 0; i < decl->dim; i++)
+ { Dsymbol *s = (*decl)[i];
s->semantic(newsc);
}
@@ -149,7 +167,7 @@ void AttribDeclaration::semantic(Scope *sc)
{
for (size_t i = 0; i < d->dim; i++)
{
- Dsymbol *s = d->tdata()[i];
+ Dsymbol *s = (*d)[i];
s->semantic(sc);
}
@@ -163,7 +181,7 @@ void AttribDeclaration::semantic2(Scope *sc)
if (d)
{
for (size_t i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ { Dsymbol *s = (*d)[i];
s->semantic2(sc);
}
}
@@ -176,7 +194,7 @@ void AttribDeclaration::semantic3(Scope *sc)
if (d)
{
for (size_t i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ { Dsymbol *s = (*d)[i];
s->semantic3(sc);
}
}
@@ -188,8 +206,8 @@ void AttribDeclaration::inlineScan()
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::inlineScan %s\n", s->toChars());
s->inlineScan();
}
@@ -205,8 +223,8 @@ void AttribDeclaration::addComment(unsigned char *comment)
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::addComment %s\n", s->toChars());
s->addComment(comment);
}
@@ -230,8 +248,8 @@ void AttribDeclaration::emitComment(Scope *sc)
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::emitComment %s\n", s->toChars());
s->emitComment(sc);
}
@@ -246,32 +264,27 @@ void AttribDeclaration::toObjFile(int multiobj)
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
s->toObjFile(multiobj);
}
}
}
-int AttribDeclaration::cvMember(unsigned char *p)
+#endif
+
+void AttribDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
- int nwritten = 0;
- int n;
Dsymbols *d = include(NULL, NULL);
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
- n = s->cvMember(p);
- if (p)
- p += n;
- nwritten += n;
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
+ s->setFieldOffset(ad, poffset, isunion);
}
}
- return nwritten;
}
-#endif
int AttribDeclaration::hasPointers()
{
@@ -281,7 +294,7 @@ int AttribDeclaration::hasPointers()
{
for (size_t i = 0; i < d->dim; i++)
{
- Dsymbol *s = d->tdata()[i];
+ Dsymbol *s = (*d)[i];
if (s->hasPointers())
return 1;
}
@@ -323,8 +336,8 @@ void AttribDeclaration::checkCtorConstInit()
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
s->checkCtorConstInit();
}
}
@@ -339,8 +352,8 @@ void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
s->addLocalClass(aclasses);
}
}
@@ -354,15 +367,15 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
if (decl->dim == 0)
buf->writestring("{}");
else if (decl->dim == 1)
- (decl->tdata()[0])->toCBuffer(buf, hgs);
+ ((*decl)[0])->toCBuffer(buf, hgs);
else
{
buf->writenl();
buf->writeByte('{');
buf->writenl();
- for (unsigned i = 0; i < decl->dim; i++)
+ for (size_t i = 0; i < decl->dim; i++)
{
- Dsymbol *s = decl->tdata()[i];
+ Dsymbol *s = (*decl)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -467,17 +480,19 @@ void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
{ STCout, TOKout },
{ STCin, TOKin },
#if DMDV2
+ { STCmanifest, TOKenum },
{ STCimmutable, TOKimmutable },
{ STCshared, TOKshared },
{ STCnothrow, TOKnothrow },
{ STCpure, TOKpure },
{ STCref, TOKref },
{ STCtls, TOKtls },
{ STCgshared, TOKgshared },
- { STCproperty, TOKat },
- { STCsafe, TOKat },
- { STCtrusted, TOKat },
- { STCdisable, TOKat },
+ { STCproperty, TOKat, Id::property },
+ { STCsafe, TOKat, Id::safe },
+ { STCtrusted, TOKat, Id::trusted },
+ { STCsystem, TOKat, Id::system },
+ { STCdisable, TOKat, Id::disable },
#endif
};
@@ -488,20 +503,9 @@ void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
enum TOK tok = table[i].tok;
#if DMDV2
if (tok == TOKat)
- { Identifier *id;
-
- if (stc & STCproperty)
- id = Id::property;
- else if (stc & STCsafe)
- id = Id::safe;
- else if (stc & STCtrusted)
- id = Id::trusted;
- else if (stc & STCdisable)
- id = Id::disable;
- else
- assert(0);
+ {
buf->writeByte('@');
- buf->writestring(id->toChars());
+ buf->writestring(table[i].id->toChars());
}
else
#endif
@@ -560,9 +564,9 @@ void LinkDeclaration::semantic3(Scope *sc)
{ enum LINK linkage_save = sc->linkage;
sc->linkage = linkage;
- for (unsigned i = 0; i < decl->dim; i++)
+ for (size_t i = 0; i < decl->dim; i++)
{
- Dsymbol *s = decl->tdata()[i];
+ Dsymbol *s = (*decl)[i];
s->semantic3(sc);
}
@@ -738,6 +742,7 @@ AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Dsymbols *decl)
: AttribDeclaration(decl)
{
this->loc = loc;
+ this->alignment = 0;
this->isunion = isunion;
this->sem = 0;
}
@@ -755,21 +760,6 @@ void AnonDeclaration::semantic(Scope *sc)
{
//printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
- if (sem == 1)
- { //printf("already completed\n");
- scope = NULL;
- return; // semantic() already completed
- }
-
- Scope *scx = NULL;
- if (scope)
- { sc = scope;
- scx = scope;
- scope = NULL;
- }
-
- unsigned dprogress_save = Module::dprogress;
-
assert(sc->parent);
Dsymbol *parent = sc->parent->pastMixin();
@@ -781,106 +771,85 @@ void AnonDeclaration::semantic(Scope *sc)
return;
}
+ alignment = sc->structalign;
if (decl)
{
- AnonymousAggregateDeclaration aad;
- int adisunion;
-
- if (sc->anonAgg)
- { ad = sc->anonAgg;
- adisunion = sc->inunion;
- }
- else
- adisunion = ad->isUnionDeclaration() != NULL;
-
-// printf("\tsc->anonAgg = %p\n", sc->anonAgg);
-// printf("\tad = %p\n", ad);
-// printf("\taad = %p\n", &aad);
-
sc = sc->push();
- sc->anonAgg = &aad;
sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared);
sc->inunion = isunion;
sc->offset = 0;
sc->flags = 0;
- aad.structalign = sc->structalign;
- aad.parent = ad;
- for (unsigned i = 0; i < decl->dim; i++)
+ for (size_t i = 0; i < decl->dim; i++)
{
- Dsymbol *s = decl->tdata()[i];
-
+ Dsymbol *s = (*decl)[i];
s->semantic(sc);
- if (isunion)
- sc->offset = 0;
- if (aad.sizeok == 2)
- {
- break;
- }
}
sc = sc->pop();
+ }
+}
- // If failed due to forward references, unwind and try again later
- if (aad.sizeok == 2)
- {
- ad->sizeok = 2;
- //printf("\tsetting ad->sizeok %p to 2\n", ad);
- if (!sc->anonAgg)
- {
- scope = scx ? scx : new Scope(*sc);
- scope->setNoFree();
- scope->module->addDeferredSemantic(this);
- }
- Module::dprogress = dprogress_save;
- //printf("\tforward reference %p\n", this);
- return;
- }
- if (sem == 0)
- { Module::dprogress++;
- sem = 1;
- //printf("\tcompleted %p\n", this);
- }
- else
- ;//printf("\talready completed %p\n", this);
- // 0 sized structs are set to 1 byte
- if (aad.structsize == 0)
- {
- aad.structsize = 1;
- aad.alignsize = 1;
- }
+void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
+{
+ //printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);
+
+ if (decl)
+ {
+ /* This works by treating an AnonDeclaration as an aggregate 'member',
+ * so in order to place that member we need to compute the member's
+ * size and alignment.
+ */
- // Align size of anonymous aggregate
-//printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset);
- ad->alignmember(aad.structalign, aad.alignsize, &sc->offset);
- //ad->structsize = sc->offset;
-//printf("sc->offset = %d\n", sc->offset);
+ size_t fieldstart = ad->fields.dim;
- // Add members of aad to ad
- //printf("\tadding members of aad (%p) to '%s'\n", &aad, ad->toChars());
- for (unsigned i = 0; i < aad.fields.dim; i++)
+ /* Hackishly hijack ad's structsize and alignsize fields
+ * for use in our fake anon aggregate member.
+ */
+ unsigned savestructsize = ad->structsize;
+ unsigned savealignsize = ad->alignsize;
+ ad->structsize = 0;
+ ad->alignsize = 0;
+
+ unsigned offset = 0;
+ for (size_t i = 0; i < decl->dim; i++)
{
- VarDeclaration *v = (VarDeclaration *)aad.fields.data[i];
+ Dsymbol *s = (*decl)[i];
- v->offset += sc->offset;
- ad->fields.push(v);
+ s->setFieldOffset(ad, &offset, this->isunion);
+ if (this->isunion)
+ offset = 0;
}
- // Add size of aad to ad
- if (adisunion)
+ unsigned anonstructsize = ad->structsize;
+ unsigned anonalignsize = ad->alignsize;
+ ad->structsize = savestructsize;
+ ad->alignsize = savealignsize;
+
+ // 0 sized structs are set to 1 byte
+ if (anonstructsize == 0)
{
- if (aad.structsize > ad->structsize)
- ad->structsize = aad.structsize;
- sc->offset = 0;
+ anonstructsize = 1;
+ anonalignsize = 1;
}
- else
+
+ /* Given the anon 'member's size and alignment,
+ * go ahead and place it.
+ */
+ unsigned anonoffset = AggregateDeclaration::placeField(
+ poffset,
+ anonstructsize, anonalignsize, alignment,
+ &ad->structsize, &ad->alignsize,
+ isunion);
+
+ // Add to the anon fields the base offset of this anonymous aggregate
+ //printf("anon fields, anonoffset = %d\n", anonoffset);
+ for (size_t i = fieldstart; i < ad->fields.dim; i++)
{
- ad->structsize = sc->offset + aad.structsize;
- sc->offset = ad->structsize;
+ VarDeclaration *v = ad->fields[i];
+ //printf("\t[%d] %s %d\n", i, v->toChars(), v->offset);
+ v->offset += anonoffset;
}
-
- if (ad->alignsize < aad.alignsize)
- ad->alignsize = aad.alignsize;
}
}
@@ -891,9 +860,9 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("\n{\n");
if (decl)
{
- for (unsigned i = 0; i < decl->dim; i++)
+ for (size_t i = 0; i < decl->dim; i++)
{
- Dsymbol *s = decl->tdata()[i];
+ Dsymbol *s = (*decl)[i];
//buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -953,10 +922,10 @@ void PragmaDeclaration::setScope(Scope *sc)
}
else
{
- Expression *e = args->tdata()[0];
+ Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
- args->tdata()[0] = e;
+ (*args)[0] = e;
StringExp* se = e->toString();
if (!se)
{
@@ -991,7 +960,7 @@ void PragmaDeclaration::semantic(Scope *sc)
{
for (size_t i = 0; i < args->dim; i++)
{
- Expression *e = args->tdata()[i];
+ Expression *e = (*args)[i];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
@@ -1013,11 +982,11 @@ void PragmaDeclaration::semantic(Scope *sc)
error("string expected for library name");
else
{
- Expression *e = args->tdata()[0];
+ Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
- args->tdata()[0] = e;
+ (*args)[0] = e;
if (e->op == TOKerror)
goto Lnodecl;
StringExp *se = e->toString();
@@ -1045,7 +1014,7 @@ void PragmaDeclaration::semantic(Scope *sc)
Declaration *d = NULL;
StringExp *s = NULL;
- e = (Expression *)args->data[0];
+ e = (*args)[0];
e = e->semantic(sc);
if (e->op == TOKvar)
{
@@ -1056,14 +1025,14 @@ void PragmaDeclaration::semantic(Scope *sc)
if (!d)
error("first argument of GNU_asm must be a function or variable declaration");
- e = args->tdata()[1];
+ e = (*args)[1];
e = e->semantic(sc);
e = e->optimize(WANTvalue);
e = e->toString();
if (e && ((StringExp *)e)->sz == 1)
s = ((StringExp *)e);
else
- error("second argument of GNU_asm must be a char string");
+ error("second argument of GNU_asm must be a character string");
if (d && s)
d->c_ident = Lexer::idPool((char*) s->string);
@@ -1078,10 +1047,10 @@ void PragmaDeclaration::semantic(Scope *sc)
error("function name expected for start address");
else
{
- Expression *e = (Expression *)args->data[0];
+ Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
- args->data[0] = (void *)e;
+ (*args)[0] = e;
Dsymbol *sa = getDsymbol(e);
if (!sa || !sa->isFuncDeclaration())
error("function name expected for start address, not '%s'", e->toChars());
@@ -1111,11 +1080,13 @@ void PragmaDeclaration::semantic(Scope *sc)
{
for (size_t i = 0; i < args->dim; i++)
{
+#if IN_LLVM
// ignore errors in ignored pragmas.
global.gag++;
unsigned errors_save = global.errors;
+#endif
- Expression *e = (Expression *)args->data[i];
+ Expression *e = (*args)[i];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
if (i == 0)
@@ -1124,9 +1095,11 @@ void PragmaDeclaration::semantic(Scope *sc)
printf(",");
printf("%s", e->toChars());
+#if IN_LLVM
// restore error state.
global.gag--;
global.errors = errors_save;
+#endif
}
if (args->dim)
printf(")");
@@ -1141,9 +1114,9 @@ void PragmaDeclaration::semantic(Scope *sc)
Ldecl:
if (decl)
{
- for (unsigned i = 0; i < decl->dim; i++)
+ for (size_t i = 0; i < decl->dim; i++)
{
- Dsymbol *s = decl->tdata()[i];
+ Dsymbol *s = (*decl)[i];
s->semantic(sc);
@@ -1180,7 +1153,7 @@ void PragmaDeclaration::toObjFile(int multiobj)
{
assert(args && args->dim == 1);
- Expression *e = (Expression *)args->data[0];
+ Expression *e = (*args)[0];
assert(e->op == TOKstring);
@@ -1208,7 +1181,7 @@ void PragmaDeclaration::toObjFile(int multiobj)
else if (ident == Id::startaddress)
{
assert(args && args->dim == 1);
- Expression *e = (Expression *)args->data[0];
+ Expression *e = (*args)[0];
Dsymbol *sa = getDsymbol(e);
FuncDeclaration *f = sa->isFuncDeclaration();
assert(f);
@@ -1285,8 +1258,8 @@ void ConditionalDeclaration::emitComment(Scope *sc)
* a template, then include(NULL, NULL) will fail.
*/
Dsymbols *d = decl ? decl : elsedecl;
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
s->emitComment(sc);
}
}
@@ -1308,9 +1281,9 @@ void ConditionalDeclaration::setScope(Scope *sc)
//printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
+ for (size_t i = 0; i < d->dim; i++)
{
- Dsymbol *s = d->tdata()[i];
+ Dsymbol *s = (*d)[i];
s->setScope(sc);
}
@@ -1324,9 +1297,9 @@ void ConditionalDeclaration::importAll(Scope *sc)
//printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d);
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
+ for (size_t i = 0; i < d->dim; i++)
{
- Dsymbol *s = d->tdata()[i];
+ Dsymbol *s = (*d)[i];
s->importAll(sc);
}
@@ -1349,10 +1322,8 @@ void ConditionalDeclaration::addComment(unsigned char *comment)
{
if (d)
{
- for (unsigned i = 0; i < d->dim; i++)
- { Dsymbol *s;
-
- s = d->tdata()[i];
+ for (size_t i = 0; i < d->dim; i++)
+ { Dsymbol *s = (*d)[i];
//printf("ConditionalDeclaration::addComment %s\n", s->toChars());
s->addComment(comment);
}
@@ -1372,9 +1343,9 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
if (decl)
{
- for (unsigned i = 0; i < decl->dim; i++)
+ for (size_t i = 0; i < decl->dim; i++)
{
- Dsymbol *s = decl->tdata()[i];
+ Dsymbol *s = (*decl)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -1388,9 +1359,9 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
buf->writeByte('{');
buf->writenl();
- for (unsigned i = 0; i < elsedecl->dim; i++)
+ for (size_t i = 0; i < elsedecl->dim; i++)
{
- Dsymbol *s = elsedecl->tdata()[i];
+ Dsymbol *s = (*elsedecl)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -1474,9 +1445,9 @@ void StaticIfDeclaration::semantic(Scope *sc)
addisdone = 1;
}
- for (unsigned i = 0; i < d->dim; i++)
+ for (size_t i = 0; i < d->dim; i++)
{
- Dsymbol *s = d->tdata()[i];
+ Dsymbol *s = (*d)[i];
s->semantic(sc);
}
View
9 dmd/attrib.h
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -33,6 +33,7 @@ struct AttribDeclaration : Dsymbol
AttribDeclaration(Dsymbols *decl);
virtual Dsymbols *include(Scope *sc, ScopeDsymbol *s);
+ int apply(Dsymbol_apply_ft_t fp, void *param);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void setScopeNewSc(Scope *sc,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
@@ -48,6 +49,7 @@ struct AttribDeclaration : Dsymbol
void emitComment(Scope *sc);
const char *kind();
int oneMember(Dsymbol **ps);
+ void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
int hasPointers();
bool hasStaticCtorOrDtor();
void checkCtorConstInit();
@@ -58,7 +60,6 @@ struct AttribDeclaration : Dsymbol
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
- int cvMember(unsigned char *p);
#endif
#if IN_LLVM
@@ -119,12 +120,14 @@ struct AlignDeclaration : AttribDeclaration
struct AnonDeclaration : AttribDeclaration
{
- int isunion;
+ bool isunion;
+ unsigned alignment;
int sem; // 1 if successful semantic()
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
+ void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
};
View
7 dmd/cast.c
@@ -1166,17 +1166,16 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
Expression *DelegateExp::castTo(Scope *sc, Type *t)
{
- Type *tb;
#if 0
printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n",
toChars(), type->toChars(), t->toChars());
#endif
- Expression *e = this;
static char msg[] = "cannot form delegate due to covariant return type";
- tb = t->toBasetype();
+ Expression *e = this;
+ Type *tb = t->toBasetype();
type = type->toBasetype();
- if (tb != type)
+ if (tb != type || hasOverloads)
{
// Look for delegates to functions where the functions are overloaded.
FuncDeclaration *f;
View
112 dmd/class.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -228,9 +228,9 @@ Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
cd->baseclasses->setDim(this->baseclasses->dim);
for (size_t i = 0; i < cd->baseclasses->dim; i++)
{
- BaseClass *b = (BaseClass *)this->baseclasses->data[i];
+ BaseClass *b = this->baseclasses->tdata()[i];
BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection);
- cd->baseclasses->data[i] = b2;
+ cd->baseclasses->tdata()[i] = b2;
}
ScopeDsymbol::syntaxCopy(cd);
@@ -264,7 +264,7 @@ void ClassDeclaration::semantic(Scope *sc)
return;
}
if (symtab)
- { if (sizeok == 1 || !scope)
+ { if (sizeok == SIZEOKdone || !scope)
{ //printf("\tsemantic for '%s' is already completed\n", toChars());
return; // semantic() already completed
}
@@ -290,7 +290,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
- { BaseClass *b = (BaseClass *)baseclasses->data[i];
+ { BaseClass *b = baseclasses->tdata()[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
@@ -315,11 +315,12 @@ void ClassDeclaration::semantic(Scope *sc)
BaseClass *b;
Type *tb;
- b = (BaseClass *)baseclasses->data[0];
+ b = baseclasses->tdata()[0];
//b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty != Tclass)
- { error("base type must be class or interface, not %s", b->type->toChars());
+ { if (b->type != Type::terror)
+ error("base type must be class or interface, not %s", b->type->toChars());
baseclasses->remove(0);
}
else
@@ -331,7 +332,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (!isDeprecated())
{
// Deriving from deprecated class makes this one deprecated too
- isdeprecated = 1;
+ isdeprecated = true;
tc->checkDeprecated(loc, sc);
}
@@ -350,12 +351,12 @@ void ClassDeclaration::semantic(Scope *sc)
goto L7;
}
}
- if (!tc->sym->symtab || tc->sym->sizeok == 0)
+ if (!tc->sym->symtab || tc->sym->sizeok == SIZEOKnone)
{ // Try to resolve forward reference
if (/*sc->mustsemantic &&*/ tc->sym->scope)
tc->sym->semantic(NULL);
}
- if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
+ if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == SIZEOKnone)
{
//printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars());
//error("forward reference of base class %s", baseClass->toChars());
@@ -384,15 +385,15 @@ void ClassDeclaration::semantic(Scope *sc)
BaseClass *b;
Type *tb;
- b = (BaseClass *)baseclasses->data[i];
+ b = baseclasses->tdata()[i];
b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty == Tclass)
tc = (TypeClass *)tb;
else
tc = NULL;
if (!tc || !tc->sym->isInterfaceDeclaration())
- {
+ { if (b->type != Type::terror)
error("base type must be interface, not %s", b->type->toChars());
baseclasses->remove(i);
continue;
@@ -404,7 +405,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (!isDeprecated())
{
// Deriving from deprecated class makes this one deprecated too
- isdeprecated = 1;
+ isdeprecated = true;
tc->checkDeprecated(loc, sc);
}
@@ -413,7 +414,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Check for duplicate interfaces
for (size_t j = (baseClass ? 1 : 0); j < i; j++)
{
- BaseClass *b2 = (BaseClass *)baseclasses->data[j];
+ BaseClass *b2 = baseclasses->tdata()[j];
if (b2->base == tc->sym)
error("inherits from duplicate interface %s", b2->base->toChars());
}
@@ -467,7 +468,7 @@ void ClassDeclaration::semantic(Scope *sc)
}
interfaces_dim = baseclasses->dim;
- interfaces = (BaseClass **)baseclasses->data;
+ interfaces = baseclasses->tdata();
if (baseClass)
@@ -480,7 +481,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Copy vtbl[] from base class
vtbl.setDim(baseClass->vtbl.dim);
- memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim);
+ memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim);
// Inherit properties from base class
com = baseClass->isCOMclass();
@@ -503,7 +504,7 @@ void ClassDeclaration::semantic(Scope *sc)
for (size_t i = 0; i < members->dim; i++)
{
- Dsymbol *s = (Dsymbol *)members->data[i];
+ Dsymbol *s = (*members)[i];
s->addMember(sc, this, 1);
}
@@ -606,31 +607,56 @@ void ClassDeclaration::semantic(Scope *sc)
structsize = sc->offset;
Scope scsave = *sc;
size_t members_dim = members->dim;
- sizeok = 0;
+ sizeok = SIZEOKnone;
/* Set scope so if there are forward references, we still might be able to
* resolve individual members like enums.
*/
for (size_t i = 0; i < members_dim; i++)
- { Dsymbol *s = (Dsymbol *)members->data[i];
+ { Dsymbol *s = (*members)[i];
/* There are problems doing this in the general case because
* Scope keeps track of things like 'offset'
*/
- if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
+ if (s->isEnumDeclaration() ||
+ (s->isAggregateDeclaration() && s->ident) ||
+ s->isTemplateMixin() ||
+ s->isAliasDeclaration())
{
//printf("setScope %s %s\n", s->kind(), s->toChars());
s->setScope(sc);
}
}
for (size_t i = 0; i < members_dim; i++)
- { Dsymbol *s = (Dsymbol *)members->data[i];
+ { Dsymbol *s = (*members)[i];
s->semantic(sc);
}
- if (sizeok == 2)
- { // semantic() failed because of forward references.
+ // Set the offsets of the fields and determine the size of the class
+
+ unsigned offset = structsize;
+ bool isunion = isUnionDeclaration() != NULL;
+ for (size_t i = 0; i < members->dim; i++)
+ { Dsymbol *s = (*members)[i];
+ s->setFieldOffset(this, &offset, false);
+ }
+ sc->offset = structsize;
+
+ if (global.gag && global.gaggedErrors != errors)
+ { // The type is no good, yet the error messages were gagged.
+ type = Type::terror;
+ }
+
+ if (sizeok == 2) // failed due to forward references
+ { // semantic() failed due to forward references
// Unwind what we did, and defer it for later
+
+ for (size_t i = 0; i < fields.dim; i++)
+ { Dsymbol *s = fields[i];
+ VarDeclaration *vd = s->isVarDeclaration();
+ if (vd)
+ vd->offset = 0;
+ }
fields.setDim(0);
structsize = 0;
alignsize = 0;
@@ -650,7 +676,6 @@ void ClassDeclaration::semantic(Scope *sc)
//printf("\tsemantic('%s') successful\n", toChars());
- structsize = sc->offset;
//members->print();
/* Look for special member functions.
@@ -683,7 +708,6 @@ void ClassDeclaration::semantic(Scope *sc)
members->push(ctor);
ctor->addMember(sc, this, 1);
*sc = scsave; // why? What about sc->nofree?
- sc->offset = structsize;
ctor->semantic(sc);
this->ctor = ctor;
defaultCtor = ctor;
@@ -699,9 +723,10 @@ void ClassDeclaration::semantic(Scope *sc)
#endif
// Allocate instance of each new interface
+ sc->offset = structsize;
for (size_t i = 0; i < vtblInterfaces->dim; i++)
{
- BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
+ BaseClass *b = (*vtblInterfaces)[i];
unsigned thissize = PTRSIZE;
alignmember(structalign, thissize, &sc->offset);
@@ -720,7 +745,7 @@ void ClassDeclaration::semantic(Scope *sc)
alignsize = thissize;
}
structsize = sc->offset;
- sizeok = 1;
+ sizeok = SIZEOKdone;
Module::dprogress++;
dtor = buildDtor(sc);
@@ -731,7 +756,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Fill in base class vtbl[]s
for (i = 0; i < vtblInterfaces->dim; i++)
{
- BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
+ BaseClass *b = vtblInterfaces->tdata()[i];
//b->fillVtbl(this, &b->vtbl, 1);
}
@@ -750,7 +775,7 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
for (size_t i = 0; i < baseclasses->dim; i++)
{
- BaseClass *b = (BaseClass *)baseclasses->data[i];
+ BaseClass *b = baseclasses->tdata()[i];
if (i)
buf->writeByte(',');
@@ -764,7 +789,7 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
for (size_t i = 0; i < members->dim; i++)
{
- Dsymbol *s = (Dsymbol *)members->data[i];
+ Dsymbol *s = members->tdata()[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -799,7 +824,7 @@ int ClassDeclaration::isBaseOf2(ClassDeclaration *cd)
return 0;
//printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
for (size_t i = 0; i < cd->baseclasses->dim; i++)
- { BaseClass *b = (BaseClass *)cd->baseclasses->data[i];
+ { BaseClass *b = cd->baseclasses->tdata()[i];
if (b->base == this || isBaseOf2(b->base))
return 1;
@@ -845,7 +870,7 @@ int ClassDeclaration::isBaseInfoComplete()
if (!baseClass)
return ident == Id::Object;
for (size_t i = 0; i < baseclasses->dim; i++)
- { BaseClass *b = (BaseClass *)baseclasses->data[i];
+ { BaseClass *b = baseclasses->tdata()[i];
if (!b->base || !b->base->isBaseInfoComplete())
return 0;
}
@@ -860,7 +885,12 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
if (scope && !symtab)
{ Scope *sc = scope;
sc->mustsemantic++;
+ // If speculatively gagged, ungag now.
+ unsigned oldgag = global.gag;
+ if (global.isSpeculativeGagging())
+ global.gag = 0;
semantic(sc);
+ global.gag = oldgag;
sc->mustsemantic--;
}
@@ -878,7 +908,7 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
for (size_t i = 0; i < baseclasses->dim; i++)
{
- BaseClass *b = (BaseClass *)baseclasses->data[i];
+ BaseClass *b = baseclasses->tdata()[i];
if (b->base)
{
@@ -1178,12 +1208,12 @@ void InterfaceDeclaration::semantic(Scope *sc)
if (sc->stc & STCdeprecated)
{
- isdeprecated = 1;
+ isdeprecated = true;
}
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
- { BaseClass *b = (BaseClass *)baseclasses->data[0];
+ { BaseClass *b = (*baseclasses)[0];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
@@ -1208,15 +1238,15 @@ void InterfaceDeclaration::semantic(Scope *sc)
BaseClass *b;
Type *tb;
- b = (BaseClass *)baseclasses->data[i];
+ b = baseclasses->tdata()[i];
b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty == Tclass)
tc = (TypeClass *)tb;
else
tc = NULL;
if (!tc || !tc->sym->isInterfaceDeclaration())
- {
+ { if (b->type != Type::terror)
error("base type must be interface, not %s", b->type->toChars());
baseclasses->remove(i);
continue;
@@ -1226,7 +1256,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Check for duplicate interfaces
for (size_t j = 0; j < i; j++)
{
- BaseClass *b2 = (BaseClass *)baseclasses->data[j];
+ BaseClass *b2 = baseclasses->tdata()[j];
if (b2->base == tc->sym)
error("inherits from duplicate interface %s", b2->base->toChars());
}
@@ -1311,10 +1341,10 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc->explicitProtection = 0;
structalign = sc->structalign;
sc->offset = PTRSIZE * 2;
+ structsize = sc->offset;
inuse++;
for (size_t i = 0; i < members->dim; i++)
- {
- Dsymbol *s = (*members)[i];
+ { Dsymbol *s = (*members)[i];
s->semantic(sc);
}
inuse--;
@@ -1408,7 +1438,7 @@ int InterfaceDeclaration::isBaseInfoComplete()
{
assert(!baseClass);
for (size_t i = 0; i < baseclasses->dim; i++)
- { BaseClass *b = (BaseClass *)baseclasses->data[i];
+ { BaseClass *b = baseclasses->tdata()[i];
if (!b->base || !b->base->isBaseInfoComplete ())
return 0;
}
View
22 dmd/cond.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -225,6 +225,7 @@ StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
: Condition(loc)
{
this->exp = exp;
+ this->nest = 0;
}
Condition *StaticIfCondition::syntaxCopy()
@@ -235,28 +236,43 @@ Condition *StaticIfCondition::syntaxCopy()
int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
{
#if 0
- printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s);
+ printf("StaticIfCondition::include(sc = %p, s = %p) this=%p inc = %d\n", sc, s, this, inc);
if (s)
{
printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind());
}
#endif
if (inc == 0)
{
+ if (exp->op == TOKerror || nest > 100)
+ {
+ error(loc, (nest > 1000) ? "unresolvable circular static if expression"
+ : "error evaluating static if expression");
+ if (!global.gag)
+ inc = 2; // so we don't see the error message again
+ return 0;
+ }
+
if (!sc)
{
error(loc, "static if conditional cannot be at global scope");
inc = 2;
return 0;
}
+ ++nest;
sc = sc->push(sc->scopesym);
sc->sd = s; // s gets any addMember()
sc->flags |= SCOPEstaticif;
Expression *e = exp->semantic(sc);
sc->pop();
e = e->optimize(WANTvalue | WANTinterpret);
- if (e->isBool(TRUE))
+ --nest;
+ if (e->op == TOKerror)
+ { exp = e;
+ inc = 0;
+ }
+ else if (e->isBool(TRUE))
inc = 1;
else if (e->isBool(FALSE))
inc = 2;
View
5 dmd/cond.h
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -36,6 +36,7 @@ struct Condition
virtual Condition *syntaxCopy() = 0;
virtual int include(Scope *sc, ScopeDsymbol *s) = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
+ virtual DebugCondition *isDebugCondition() { return NULL; }
};
struct DVCondition : Condition
@@ -59,6 +60,7 @@ struct DebugCondition : DVCondition
int include(Scope *sc, ScopeDsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+ DebugCondition *isDebugCondition() { return this; }
};
struct VersionCondition : DVCondition
@@ -77,6 +79,7 @@ struct VersionCondition : DVCondition
struct StaticIfCondition : Condition
{
Expression *exp;
+ int nest; // limit circular dependencies
StaticIfCondition(Loc loc, Expression *exp);
Condition *syntaxCopy();
View
126 dmd/declaration.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -530,7 +530,8 @@ void AliasDeclaration::semantic(Scope *sc)
goto L2;
}
else
- { error("cannot alias an expression %s", e->toChars());
+ { if (e->op != TOKerror)
+ error("cannot alias an expression %s", e->toChars());
t = e->type;
}
}
@@ -543,7 +544,7 @@ void AliasDeclaration::semantic(Scope *sc)
ScopeDsymbol::multiplyDefined(0, this, overnext);
this->inSemantic = 0;
- if (errors != global.errors)
+ if (global.gag && errors != global.errors)
type = savedtype;
return;
@@ -580,7 +581,7 @@ void AliasDeclaration::semantic(Scope *sc)
assert(global.errors);
s = NULL;
}
- if (errors != global.errors)
+ if (global.gag && errors != global.errors)
{
type = savedtype;
overnext = savedovernext;
@@ -728,6 +729,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
#if DMDV1
nestedref = 0;
#endif
+ alignment = 0;
ctorinit = 0;
aliassym = NULL;
onstack = 0;
@@ -767,6 +769,7 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
sv->storage_class = storage_class;
}
+
// Syntax copy for header file
if (!htype) // Don't overwrite original
{ if (type) // Make copy for both old and new instances
@@ -955,9 +958,7 @@ void VarDeclaration::semantic(Scope *sc)
}
else
{
- AggregateDeclaration *aad = sc->anonAgg;
- if (!aad)
- aad = parent->isAggregateDeclaration();
+ AggregateDeclaration *aad = parent->isAggregateDeclaration();
if (aad)
{
#if DMDV2
@@ -970,7 +971,15 @@ void VarDeclaration::semantic(Scope *sc)
}
else
#endif
- aad->addField(sc, this);
+ {
+ storage_class |= STCfield;
+ alignment = sc->structalign;
+#if DMDV2
+ if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
+ tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
+ aad->noDefaultCtor = TRUE;
+#endif
+ }
}
InterfaceDeclaration *id = parent->isInterfaceDeclaration();
@@ -1305,6 +1314,31 @@ ExpInitializer *VarDeclaration::getExpInitializer()
void VarDeclaration::semantic2(Scope *sc)
{
//printf("VarDeclaration::semantic2('%s')\n", toChars());
+ // Inside unions, default to void initializers
+ if (!init && sc->inunion && !toParent()->isFuncDeclaration())
+ {
+ AggregateDeclaration *aad = parent->isAggregateDeclaration();
+ if (aad)
+ {
+ if (aad->fields[0] == this)
+ {
+ int hasinit = 0;
+ for (size_t i = 1; i < aad->fields.dim; i++)
+ {
+ if (aad->fields[i]->init &&
+ !aad->fields[i]->init->isVoidInitializer())
+ {
+ hasinit = 1;
+ break;
+ }
+ }
+ if (!hasinit)
+ init = new ExpInitializer(loc, type->defaultInitLiteral(loc));
+ }
+ else
+ init = new VoidInitializer(loc);
+ }
+ }
if (init && !toParent()->isFuncDeclaration())
{ inuse++;
#if 0
@@ -1330,6 +1364,82 @@ void VarDeclaration::semantic3(Scope *sc)
Declaration::semantic3(sc);
}
+void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
+{
+ //printf("VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars());
+
+ if (aliassym)
+ { // If this variable was really a tuple, set the offsets for the tuple fields
+ TupleDeclaration *v2 = aliassym->isTupleDeclaration();
+ assert(v2);
+ for (size_t i = 0; i < v2->objects->dim; i++)
+ { Object *o = (*v2->objects)[i];
+ assert(o->dyncast() == DYNCAST_EXPRESSION);
+ Expression *e = (Expression *)o;
+ assert(e->op == TOKdsymbol);
+ DsymbolExp *se = (DsymbolExp *)e;
+ se->s->setFieldOffset(ad, poffset, isunion);
+ }
+ return;
+ }
+
+ if (!(storage_class & STCfield))
+ return;
+ assert(!(storage_class & (STCstatic | STCextern | STCparameter | STCtls)));
+
+ /* Fields that are tuples appear both as part of TupleDeclarations and
+ * as members. That means ignore them if they are already a field.
+ */
+ if (offset)
+ return; // already a field
+ for (size_t i = 0; i < ad->fields.dim; i++)
+ {
+ if (ad->fields[i] == this)
+ return; // already a field
+ }
+
+ // Check for forward referenced types which will fail the size() call
+ Type *t = type->toBasetype();
+ if (storage_class & STCref)
+ { // References are the size of a pointer
+ t = Type::tvoidptr;
+ }
+ if (t->ty == Tstruct)
+ { TypeStruct *ts = (TypeStruct *)t;
+#if DMDV2
+ if (ts->sym == ad)
+ {
+ ad->error("cannot have field %s with same struct type", toChars());
+ }
+#endif
+
+ if (ts->sym->sizeok != SIZEOKdone && ts->sym->scope)
+ ts->sym->semantic(NULL);
+ if (ts->sym->sizeok != SIZEOKdone)
+ {
+ ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced
+ return;
+ }
+ }
+ if (t->ty == Tident)
+ {
+ ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced
+ return;
+ }
+
+ unsigned memsize = t->size(loc); // size of member
+ unsigned memalignsize = t->alignsize(); // size of member for alignment purposes
+ unsigned memalign = t->memalign(alignment); // alignment boundaries
+
+ offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, memalign,
+ &ad->structsize, &ad->alignsize, isunion);
+
+ //printf("\t%s: alignsize = %d\n", toChars(), alignsize);
+
+ //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad->toChars(), offset, memsize);
+ ad->fields.push(this);
+}
+
const char *VarDeclaration::kind()
{
return "variable";
View
3 dmd/declaration.h
@@ -279,6 +279,7 @@ struct VarDeclaration : Declaration
#else
int nestedref; // referenced by a lexically nested function
#endif
+ unsigned short alignment;
int ctorinit; // it has been initialized in a ctor
int onstack; // 1: it has been allocated on the stack
// 2: on stack, run destructor anyway
@@ -305,6 +306,7 @@ struct VarDeclaration : Declaration
VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
+ void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
void semantic2(Scope *sc);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -795,6 +797,7 @@ struct FuncDeclaration : Declaration
int isAbstract();
int isCodeseg();
int isOverloadable();
+ int hasOverloads();
int isPure();
int isSafe();
int isTrusted();
View
3 dmd/doc.c
@@ -261,6 +261,9 @@ void Module::gendocfile()
Macro::define(&macrotable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4);
}
+ char *srcfilename = srcfile->toChars();
+ Macro::define(&macrotable, (unsigned char *)"SRCFILENAME", 11, (unsigned char *)srcfilename, strlen(srcfilename));
+
char *docfilename = docfile->toChars();
Macro::define(&macrotable, (unsigned char *)"DOCFILENAME", 11, (unsigned char *)docfilename, strlen(docfilename));
View
68 dmd/dsymbol.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -50,6 +50,7 @@ Dsymbol::Dsymbol()
this->loc = 0;
this->comment = NULL;
this->scope = NULL;
+ this->errors = false;
#if IN_LLVM
this->llvmInternal = LLVMnone;
this->irsym = NULL;
@@ -69,6 +70,7 @@ Dsymbol::Dsymbol(Identifier *ident)
this->loc = 0;
this->comment = NULL;
this->scope = NULL;
+ this->errors = false;
#if IN_LLVM
this->llvmInternal = LLVMnone;
this->irsym = NULL;
@@ -169,6 +171,10 @@ bool Dsymbol::hasStaticCtorOrDtor()
return FALSE;
}
+void Dsymbol::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
+{
+}
+
char *Dsymbol::toChars()
{
return ident ? ident->toChars() : (char *)"__anonymous";
@@ -283,6 +289,23 @@ TemplateInstance *Dsymbol::inTemplateInstance()
return NULL;
}
+// Check if this function is a member of a template which has only been
+// instantiated speculatively, eg from inside is(typeof()).
+// Return the speculative template instance it is part of,
+// or NULL if not speculative.
+TemplateInstance *Dsymbol::isSpeculative()
+{
+ Dsymbol * par = parent;
+ while (par)
+ {
+ TemplateInstance *ti = par->isTemplateInstance();
+ if (ti && ti->speculative)
+ return ti;
+ par = par->toParent();
+ }
+ return NULL;
+}
+
int Dsymbol::isAnonymous()
{
return ident ? 0 : 1;
@@ -367,11 +390,21 @@ Dsymbol *Dsymbol::search(Loc loc, Identifier *ident, int flags)
void *symbol_search_fp(void *arg, const char *seed)
{
+ /* If not in the lexer's string table, it certainly isn't in the symbol table.
+ * Doing this first is a lot faster.
+ */
+ size_t len = strlen(seed);
+ if (!len)
+ return NULL;
+ StringValue *sv = Lexer::stringtable.lookup(seed, len);
+ if (!sv)
+ return NULL;
+ Identifier *id = (Identifier *)sv->ptrvalue;
+ assert(id);
+
Dsymbol *s = (Dsymbol *)arg;
- Identifier id(seed, 0);
Module::clearCache();
- s = s->search(0, &id, 4|2);
- return s;
+ return s->search(0, id, 4|2);
}
Dsymbol *Dsymbol::search_correct(Identifier *ident)
@@ -409,7 +442,13 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, Identifier *id)
id = ti->name;
sm = s->search(loc, id, 0);
if (!sm)
- { error("template identifier %s is not a member of %s %s",
+ {
+ sm = s->search_correct(id);
+ if (sm)
+ error("template identifier '%s' is not a member of '%s %s', did you mean '%s %s'?",
+ id->toChars(), s->kind(), s->toChars(), sm->kind(), sm->toChars());
+ else
+ error("template identifier '%s' is not a member of '%s %s'",
id->toChars(), s->kind(), s->toChars());
return NULL;
}
@@ -495,6 +534,11 @@ int Dsymbol::isOverloadable()
}
#endif
+int Dsymbol::hasOverloads()
+{
+ return 0;
+}
+
LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()?
{
return NULL;
@@ -518,6 +562,11 @@ int Dsymbol::needThis()
return FALSE;
}
+int Dsymbol::apply(Dsymbol_apply_ft_t fp, void *param)
+{
+ return (*fp)(this, param);
+}
+
int Dsymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
//printf("Dsymbol::addMember('%s')\n", toChars());
@@ -634,19 +683,16 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
Module *Dsymbol::getModule()
{
- Module *m;
- Dsymbol *s;
-
//printf("Dsymbol::getModule()\n");
TemplateDeclaration *td = getFuncTemplateDecl(this);
if (td)
return td->getModule();
- s = this;
+ Dsymbol *s = this;
while (s)
{
- //printf("\ts = '%s'\n", s->toChars());
- m = s->isModule();
+ //printf("\ts = %s '%s'\n", s->kind(), s->toPrettyChars());
+ Module *m = s->isModule();
if (m)
return m;
s = s->parent;
View
9 dmd/dsymbol.h
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -128,6 +128,8 @@ enum PASS
PASSobj, // toObjFile() run
};
+typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);
+
struct Dsymbol : Object
{
Identifier *ident;
@@ -140,6 +142,7 @@ struct Dsymbol : Object
unsigned char *comment; // documentation comment for this Dsymbol
Loc loc; // where defined
Scope *scope; // !=NULL means context to use for semantic()
+ bool errors; // this symbol failed to pass semantic()
Dsymbol();
Dsymbol(Identifier *);
@@ -157,6 +160,7 @@ struct Dsymbol : Object
Dsymbol *toParent();
Dsymbol *toParent2();
TemplateInstance *inTemplateInstance();
+ TemplateInstance *isSpeculative();
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
@@ -165,6 +169,7 @@ struct Dsymbol : Object
virtual const char *toPrettyChars();
virtual const char *kind();
virtual Dsymbol *toAlias(); // resolve real symbol
+ virtual int apply(Dsymbol_apply_ft_t fp, void *param);
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
virtual void setScope(Scope *sc);
virtual void importAll(Scope *sc);
@@ -193,6 +198,7 @@ struct Dsymbol : Object
#if DMDV2
virtual int isOverloadable();
#endif
+ virtual int hasOverloads();
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
virtual Type *getType(); // is this a type?
@@ -202,6 +208,7 @@ struct Dsymbol : Object
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
virtual int oneMember(Dsymbol **ps);
static int oneMembers(Dsymbols *members, Dsymbol **ps);
+ virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
virtual int hasPointers();
virtual bool hasStaticCtorOrDtor();
virtual void addLocalClass(ClassDeclarations *) { }
View
316 dmd/expression.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -345,10 +345,10 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
*/
Type *t0 = NULL;
for (size_t i = 0; i < exps->dim; i++)
- { Expression *e = (Expression *)exps->data[i];
+ { Expression *e = (*exps)[i];
if (!e->type)
- { error("%s has no value", e->toChars());
+ { error(e->loc, "%s has no value", e->toChars());
e = new ErrorExp();
}
e = resolveProperties(sc, e);
@@ -357,7 +357,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
t0 = e->type;
else
e = e->implicitCastTo(sc, t0);
- exps->data[i] = (void *)e;
+ (*exps)[i] = e;
}
if (!t0)
@@ -384,11 +384,11 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
Expression *e0;
int j0;
for (size_t i = 0; i < exps->dim; i++)
- { Expression *e = (Expression *)exps->data[i];
+ { Expression *e = (*exps)[i];
e = resolveProperties(sc, e);
if (!e->type)
- { error("%s has no value", e->toChars());
+ { e->error("%s has no value", e->toChars());
e = new ErrorExp();
}
@@ -401,8 +401,9 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
condexp.type = NULL;
condexp.e1 = e0;
condexp.e2 = e;
+ condexp.loc = e->loc;
condexp.semantic(sc);
- exps->data[j0] = (void *)condexp.e1;
+ (*exps)[j0] = condexp.e1;
e = condexp.e2;
j0 = i;
e0 = e;
@@ -414,15 +415,15 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt
e0 = e;
t0 = e->type;
}
- exps->data[i] = (void *)e;
+ (*exps)[i] = e;
}
if (t0)
{
for (size_t i = 0; i < exps->dim; i++)
- { Expression *e = (Expression *)exps->data[i];
+ { Expression *e = (*exps)[i];
e = e->implicitCastTo(sc, t0);
- exps->data[i] = (void *)e;
+ (*exps)[i] = e;
}
}
else
@@ -525,23 +526,6 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
}
#endif
-// Check if this function is a member of a template which has only been
-// instantiated speculatively, eg from inside is(typeof()).
-// Return the speculative template instance it is part of,
-// or NULL if not speculative.
-TemplateInstance *isSpeculativeFunction(FuncDeclaration *fd)
-{
- Dsymbol * par = fd->parent;
- while (par)
- {
- TemplateInstance *ti = par->isTemplateInstance();
- if (ti && ti->speculative)
- return ti;
- par = par->toParent();
- }
- return NULL;
-}
-
/****************************************
* Now that we know the exact type of the function we're calling,
* the arguments[] need to be adjusted:
@@ -565,7 +549,7 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
// If inferring return type, and semantic3() needs to be run if not already run
if (!tf->next && fd->inferRetType)
{
- TemplateInstance *spec = isSpeculativeFunction(fd);
+ TemplateInstance *spec = fd->isSpeculative();
int olderrs = global.errors;
fd->semantic3(fd->scope);
// Update the template instantiation with the number
@@ -583,10 +567,9 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
Expression *arg;
if (i < nargs)
- arg = (Expression *)arguments->data[i];
+ arg = (*arguments)[i];
else
arg = NULL;
- Type *tb;
if (i < nparams)
{
@@ -613,12 +596,13 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
if (tf->varargs == 2 && i + 1 == nparams)
{
//printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
- if (arg->implicitConvTo(p->type))
+ MATCH m;
+ if ((m = arg->implicitConvTo(p->type)) != MATCHnomatch)
{
- if (p->type->nextOf() && arg->implicitConvTo(p->type->nextOf()))
+ if (p->type->nextOf() && arg->implicitConvTo(p->type->nextOf()) >= m)
goto L2;
else if (nargs != nparams)
- { error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
+ { error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs);
return;
}
goto L1;
@@ -661,9 +645,6 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
Expression *e = new VarExp(loc, v);
e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams));
AssignExp *ae = new AssignExp(loc, e, a);
-#if DMDV2
- ae->op = TOKconstruct;
-#endif
if (c)
c = new CommaExp(loc, c, ae);
else
@@ -723,7 +704,7 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
// LDC we don't want this!
#if !IN_LLVM
// Convert static arrays to pointers
- tb = arg->type->toBasetype();
+ Type *tb = arg->type->toBasetype();
if (tb->ty == Tsarray)
{
arg = arg->checkToPointer();
@@ -732,7 +713,19 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
#if DMDV2
if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout)))
{
- arg = callCpCtor(loc, sc, arg);
+ if (arg->op == TOKcall)
+ {
+ /* The struct value returned from the function is transferred
+ * to the function, so the callee should not call the destructor
+ * on it.
+ */
+ valueNoDtor(arg);
+ }
+ else
+ { /* Not transferring it, so call the copy constructor
+ */
+ arg = callCpCtor(loc, sc, arg, 1);
+ }
}
#endif
@@ -801,7 +794,8 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
}
// Convert static arrays to dynamic arrays
- tb = arg->type->toBasetype();
+ // BUG: I don't think this is right for D2
+ Type *tb = arg->type->toBasetype();
if (tb->ty == Tsarray)