mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Squashed 'dmd2/' changes from fc63fd3..82e6a91
82e6a91 Resolve rvalue reference on template function arguments 3708457 Implement rvalue reference for struct literal & construction 530a59f Revert "struct literals are lvalues again" f199933 struct literals are lvalues again 5f181da better error message for Issue 7815 - Mixin template forward reference (?) regression e5452d5 fix Issue 7888 - derivedMembers forward reference error with nested imports b77ae4f merge with D1 5fed58d fix Issue 7886 - derivedMembers infinite recursion 0cf5ecd Merge pull request #872 from 9rnsr/fix7873 744f102 fix Issue 7695 - Regression(2.058): ICE(mtype.c) on associative array with keys of struct type with const members 80fc228 fix Issue 7873 - IFTI with inout does not properly match template parameter if called from inout function for pointers 4a5d365 fix CTFE bugs reported in beta df22942 add kind() d36a3b4 Merge pull request #871 from 9rnsr/fix7871 66d1302 fix Issue 7871 - RangeViolation with findSplitBefore 020ab91 fix Issue 7811 - "not a property" error instead of real error on UFCS array template property c349458 fix Issue 7862 - Accepts-invalid template forward reference bug related to derivedMembers 00d8ec8 fix Issue 7861 - Segfault during __error propagation with self-referencing module 4c9652d fix fwd ref bug 477c357 fix Issue 7859 - Crash on invalid alias template parameter type c35f67a fix Issue 7858 - __traits(getOverloads) returns incorrect symbol bc840e8 fix Issue 7815 - Mixin template forward reference (?) regression 18a1485 fix auto test break ceef368 fix Issue 7826 - [D2 Beta] Cannot use getHash in toHash without a warning d747fd6 fix Issue 7820 - regression(DMD 2.059head) Wrong error on forward reference to 'front' with -property switch 1094601 fix Issue 7823 - Can't use a struct initializer to initialize a nested enum used as a default function argument initializer git-subtree-dir: dmd2 git-subtree-split: 82e6a91f234843be7f660b242f8b8819c1eae20c
This commit is contained in:
18
attrib.c
18
attrib.c
@@ -49,7 +49,7 @@ Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
|
||||
int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(scope, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
@@ -1237,9 +1237,9 @@ void ConditionalDeclaration::emitComment(Scope *sc)
|
||||
|
||||
Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
{
|
||||
//printf("ConditionalDeclaration::include()\n");
|
||||
//printf("ConditionalDeclaration::include(sc = %p) scope = %p\n", sc, scope);
|
||||
assert(condition);
|
||||
return condition->include(sc, sd) ? decl : elsedecl;
|
||||
return condition->include(scope ? scope : sc, sd) ? decl : elsedecl;
|
||||
}
|
||||
|
||||
void ConditionalDeclaration::setScope(Scope *sc)
|
||||
@@ -1399,6 +1399,9 @@ void StaticIfDeclaration::importAll(Scope *sc)
|
||||
void StaticIfDeclaration::setScope(Scope *sc)
|
||||
{
|
||||
// do not evaluate condition before semantic pass
|
||||
|
||||
// But do set the scope, in case we need it for forward referencing
|
||||
Dsymbol::setScope(sc);
|
||||
}
|
||||
|
||||
void StaticIfDeclaration::semantic(Scope *sc)
|
||||
@@ -1430,6 +1433,8 @@ const char *StaticIfDeclaration::kind()
|
||||
|
||||
/***************************** CompileDeclaration *****************************/
|
||||
|
||||
// These are mixin declarations, like mixin("int x");
|
||||
|
||||
CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
|
||||
: AttribDeclaration(NULL)
|
||||
{
|
||||
@@ -1503,3 +1508,10 @@ void CompileDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
buf->writestring(");");
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
const char *CompileDeclaration::kind()
|
||||
{
|
||||
return "mixin";
|
||||
}
|
||||
|
||||
|
||||
|
||||
1
attrib.h
1
attrib.h
@@ -187,6 +187,7 @@ struct CompileDeclaration : AttribDeclaration
|
||||
void compileIt(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
};
|
||||
|
||||
#endif /* DMD_ATTRIB_H */
|
||||
|
||||
29
cond.c
29
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
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "lexer.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "arraytypes.h"
|
||||
|
||||
int findCondition(Strings *ids, Identifier *ident)
|
||||
{
|
||||
@@ -29,7 +30,7 @@ int findCondition(Strings *ids, Identifier *ident)
|
||||
{
|
||||
for (size_t i = 0; i < ids->dim; i++)
|
||||
{
|
||||
const char *id = ids->tdata()[i];
|
||||
const char *id = (*ids)[i];
|
||||
|
||||
if (strcmp(id, ident->toChars()) == 0)
|
||||
return TRUE;
|
||||
@@ -218,6 +219,7 @@ StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
|
||||
: Condition(loc)
|
||||
{
|
||||
this->exp = exp;
|
||||
this->nest = 0;
|
||||
}
|
||||
|
||||
Condition *StaticIfCondition::syntaxCopy()
|
||||
@@ -228,7 +230,7 @@ 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());
|
||||
@@ -236,6 +238,15 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
#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");
|
||||
@@ -243,13 +254,19 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
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;
|
||||
@@ -321,7 +338,7 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
|
||||
|
||||
TemplateParameters parameters;
|
||||
parameters.setDim(1);
|
||||
parameters.tdata()[0] = &tp;
|
||||
parameters[0] = &tp;
|
||||
|
||||
Objects dedtypes;
|
||||
dedtypes.setDim(1);
|
||||
@@ -333,7 +350,7 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
|
||||
else
|
||||
{
|
||||
inc = 1;
|
||||
Type *tded = (Type *)dedtypes.tdata()[0];
|
||||
Type *tded = (Type *)dedtypes[0];
|
||||
if (!tded)
|
||||
tded = targ;
|
||||
Dsymbol *s = new AliasDeclaration(loc, id, tded);
|
||||
|
||||
3
cond.h
3
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
|
||||
@@ -79,6 +79,7 @@ struct VersionCondition : DVCondition
|
||||
struct StaticIfCondition : Condition
|
||||
{
|
||||
Expression *exp;
|
||||
int nest; // limit circular dependencies
|
||||
|
||||
StaticIfCondition(Loc loc, Expression *exp);
|
||||
Condition *syntaxCopy();
|
||||
|
||||
@@ -760,6 +760,7 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
if (!type)
|
||||
{ inuse++;
|
||||
|
||||
//printf("inferring type for %s with init %s\n", toChars(), init->toChars());
|
||||
ArrayInitializer *ai = init->isArrayInitializer();
|
||||
if (ai)
|
||||
{ Expression *e;
|
||||
@@ -780,7 +781,6 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
else
|
||||
type = init->inferType(sc);
|
||||
|
||||
//printf("test2: %s, %s, %s\n", toChars(), type->toChars(), type->deco);
|
||||
// type = type->semantic(loc, sc);
|
||||
|
||||
inuse--;
|
||||
@@ -847,7 +847,14 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
|
||||
Type *tb = type->toBasetype();
|
||||
if (tb->ty == Tvoid && !(storage_class & STClazy))
|
||||
{ error("voids have no value");
|
||||
{
|
||||
if (inferred)
|
||||
{
|
||||
error("type %s is inferred from initializer %s, and variables cannot be of type void",
|
||||
type->toChars(), init->toChars());
|
||||
}
|
||||
else
|
||||
error("variables cannot be of type void");
|
||||
type = Type::terror;
|
||||
tb = type;
|
||||
}
|
||||
|
||||
143
expression.c
143
expression.c
@@ -314,7 +314,15 @@ void checkPropertyCall(Expression *e, Expression *emsg)
|
||||
{ CallExp *ce = (CallExp *)e;
|
||||
TypeFunction *tf;
|
||||
if (ce->f)
|
||||
{
|
||||
tf = (TypeFunction *)ce->f->type;
|
||||
/* If a forward reference to ce->f, try to resolve it
|
||||
*/
|
||||
if (!tf->deco && ce->f->scope)
|
||||
{ ce->f->semantic(ce->f->scope);
|
||||
tf = (TypeFunction *)ce->f->type;
|
||||
}
|
||||
}
|
||||
else if (ce->e1->type->ty == Tfunction)
|
||||
tf = (TypeFunction *)ce->e1->type;
|
||||
else if (ce->e1->type->ty == Tdelegate)
|
||||
@@ -366,46 +374,54 @@ Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NU
|
||||
else
|
||||
e = new DotIdExp(loc, e, ident);
|
||||
|
||||
Expressions *arguments = new Expressions();
|
||||
/* .f(e1, e2)
|
||||
*/
|
||||
if (e2)
|
||||
{
|
||||
arguments->setDim(2);
|
||||
(*arguments)[0] = eleft;
|
||||
(*arguments)[1] = e2;
|
||||
|
||||
/* .f(e1) = e2
|
||||
*/
|
||||
Expression *ex = e->syntaxCopy();
|
||||
e = new CallExp(loc, e, arguments);
|
||||
e = e->trySemantic(sc);
|
||||
if (e)
|
||||
{ checkPropertyCall(e, e1);
|
||||
return e->semantic(sc);
|
||||
}
|
||||
e = ex;
|
||||
}
|
||||
Expressions *a1 = new Expressions();
|
||||
a1->setDim(1);
|
||||
(*a1)[0] = eleft;
|
||||
ex = new CallExp(loc, ex, a1);
|
||||
ex = ex->trySemantic(sc);
|
||||
|
||||
/* .f(e1)
|
||||
* .f(e1) = e2
|
||||
*/
|
||||
/* .f(e1, e2)
|
||||
*/
|
||||
Expressions *a2 = new Expressions();
|
||||
a2->setDim(2);
|
||||
(*a2)[0] = eleft;
|
||||
(*a2)[1] = e2;
|
||||
e = new CallExp(loc, e, a2);
|
||||
if (ex)
|
||||
{ // if fallback setter exists, gag errors
|
||||
e = e->trySemantic(sc);
|
||||
if (!e)
|
||||
{ checkPropertyCall(ex, e1);
|
||||
ex = new AssignExp(loc, ex, e2);
|
||||
return ex->semantic(sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // strict setter prints errors if fails
|
||||
e = e->semantic(sc);
|
||||
}
|
||||
checkPropertyCall(e, e1);
|
||||
return e;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* .f(e1)
|
||||
*/
|
||||
Expressions *arguments = new Expressions();
|
||||
arguments->setDim(1);
|
||||
(*arguments)[0] = eleft;
|
||||
e = new CallExp(loc, e, arguments);
|
||||
e = e->trySemantic(sc);
|
||||
if (!e)
|
||||
goto Leprop;
|
||||
e = e->semantic(sc);
|
||||
checkPropertyCall(e, e1);
|
||||
if (e2)
|
||||
e = new AssignExp(loc, e, e2);
|
||||
return e->semantic(sc);
|
||||
}
|
||||
}
|
||||
return e;
|
||||
|
||||
Leprop:
|
||||
e1->error("not a property %s", e1->toChars());
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
/******************************
|
||||
@@ -1021,7 +1037,37 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
|
||||
}
|
||||
if (p->storageClass & STCref)
|
||||
{
|
||||
arg = arg->toLvalue(sc, arg);
|
||||
if (arg->op == TOKstructliteral)
|
||||
{
|
||||
Identifier *idtmp = Lexer::uniqueId("__tmpsl");
|
||||
VarDeclaration *tmp = new VarDeclaration(loc, arg->type, idtmp, new ExpInitializer(0, arg));
|
||||
tmp->storage_class |= STCctfe;
|
||||
Expression *ae = new DeclarationExp(loc, tmp);
|
||||
Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
|
||||
e = e->semantic(sc);
|
||||
|
||||
arg = e;
|
||||
}
|
||||
else if (arg->op == TOKcall)
|
||||
{
|
||||
CallExp *ce = (CallExp *)arg;
|
||||
if (ce->e1->op == TOKdotvar &&
|
||||
((DotVarExp *)ce->e1)->var->isCtorDeclaration())
|
||||
{
|
||||
DotVarExp *dve = (DotVarExp *)ce->e1;
|
||||
assert(dve->e1->op == TOKcomma);
|
||||
assert(((CommaExp *)dve->e1)->e2->op == TOKvar);
|
||||
VarExp *ve = (VarExp *)((CommaExp *)dve->e1)->e2;
|
||||
VarDeclaration *tmp = ve->var->isVarDeclaration();
|
||||
|
||||
arg = new CommaExp(arg->loc, arg, new VarExp(loc, tmp));
|
||||
arg = arg->semantic(sc);
|
||||
}
|
||||
else
|
||||
arg = arg->toLvalue(sc, arg);
|
||||
}
|
||||
else
|
||||
arg = arg->toLvalue(sc, arg);
|
||||
}
|
||||
else if (p->storageClass & STCout)
|
||||
{
|
||||
@@ -6674,9 +6720,29 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
|
||||
{ goto L2;
|
||||
}
|
||||
|
||||
unsigned errors = global.startGagging();
|
||||
/* This would be much better if we added a "hasProperty" method to types,
|
||||
* i.e. the gagging is a bad way.
|
||||
*/
|
||||
|
||||
if (t1b->ty == Taarray)
|
||||
{
|
||||
TypeAArray *taa = (TypeAArray *)t1b;
|
||||
if (!taa->impl &&
|
||||
ident != Id::__sizeof &&
|
||||
ident != Id::__xalignof &&
|
||||
ident != Id::init &&
|
||||
ident != Id::mangleof &&
|
||||
ident != Id::stringof &&
|
||||
ident != Id::offsetof)
|
||||
{
|
||||
// Find out about these errors when not gagged
|
||||
taa->getImpl();
|
||||
}
|
||||
}
|
||||
|
||||
Type *t1 = e1->type;
|
||||
e = e1->type->dotExp(sc, e1, ident);
|
||||
unsigned errors = global.startGagging();
|
||||
e = t1->dotExp(sc, e1, ident);
|
||||
if (global.endGagging(errors)) // if failed to find the property
|
||||
{
|
||||
e1->type = t1; // kludge to restore type
|
||||
@@ -8716,6 +8782,8 @@ Expression *CastExp::semantic(Scope *sc)
|
||||
}
|
||||
else
|
||||
to = to->semantic(loc, sc);
|
||||
if (to == Type::terror)
|
||||
return new ErrorExp();
|
||||
|
||||
if (!to->equals(e1->type))
|
||||
{
|
||||
@@ -8952,7 +9020,9 @@ Expression *SliceExp::syntaxCopy()
|
||||
if (this->upr)
|
||||
upr = this->upr->syntaxCopy();
|
||||
|
||||
return new SliceExp(loc, e1->syntaxCopy(), lwr, upr);
|
||||
SliceExp *se = new SliceExp(loc, e1->syntaxCopy(), lwr, upr);
|
||||
se->lengthVar = this->lengthVar; // bug7871
|
||||
return se;
|
||||
}
|
||||
|
||||
Expression *SliceExp::semantic(Scope *sc)
|
||||
@@ -9297,7 +9367,9 @@ ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args)
|
||||
|
||||
Expression *ArrayExp::syntaxCopy()
|
||||
{
|
||||
return new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
|
||||
ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
|
||||
ae->lengthVar = this->lengthVar; // bug7871
|
||||
return ae;
|
||||
}
|
||||
|
||||
Expression *ArrayExp::semantic(Scope *sc)
|
||||
@@ -9464,6 +9536,13 @@ IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2)
|
||||
modifiable = 0; // assume it is an rvalue
|
||||
}
|
||||
|
||||
Expression *IndexExp::syntaxCopy()
|
||||
{
|
||||
IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy());
|
||||
ie->lengthVar = this->lengthVar; // bug7871
|
||||
return ie;
|
||||
}
|
||||
|
||||
Expression *IndexExp::semantic(Scope *sc)
|
||||
{ Expression *e;
|
||||
Type *t1;
|
||||
|
||||
@@ -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
|
||||
@@ -1196,6 +1196,7 @@ struct IndexExp : BinExp
|
||||
int modifiable;
|
||||
|
||||
IndexExp(Loc loc, Expression *e1, Expression *e2);
|
||||
Expression *syntaxCopy();
|
||||
Expression *semantic(Scope *sc);
|
||||
int isLvalue();
|
||||
Expression *toLvalue(Scope *sc, Expression *e);
|
||||
|
||||
56
func.c
56
func.c
@@ -156,6 +156,11 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||
semanticRun = PASSsemantic;
|
||||
}
|
||||
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
unsigned dprogress_save = Module::dprogress;
|
||||
|
||||
foverrides.setDim(0); // reset in case semantic() is being retried for this function
|
||||
@@ -2743,6 +2748,9 @@ int FuncDeclaration::isImportedSymbol()
|
||||
|
||||
int FuncDeclaration::isVirtual()
|
||||
{
|
||||
if (toAliasFunc() != this)
|
||||
return toAliasFunc()->isVirtual();
|
||||
|
||||
Dsymbol *p = toParent();
|
||||
#if 0
|
||||
printf("FuncDeclaration::isVirtual(%s)\n", toChars());
|
||||
@@ -2763,6 +2771,9 @@ int FuncDeclaration::isVirtual()
|
||||
|
||||
int FuncDeclaration::isVirtualMethod()
|
||||
{
|
||||
if (toAliasFunc() != this)
|
||||
return toAliasFunc()->isVirtualMethod();
|
||||
|
||||
//printf("FuncDeclaration::isVirtualMethod() %s\n", toChars());
|
||||
if (!isVirtual())
|
||||
return 0;
|
||||
@@ -2776,6 +2787,9 @@ int FuncDeclaration::isVirtualMethod()
|
||||
|
||||
int FuncDeclaration::isFinal()
|
||||
{
|
||||
if (toAliasFunc() != this)
|
||||
return toAliasFunc()->isFinal();
|
||||
|
||||
ClassDeclaration *cd;
|
||||
#if 0
|
||||
printf("FuncDeclaration::isFinal(%s), %x\n", toChars(), Declaration::isFinal());
|
||||
@@ -3285,6 +3299,11 @@ void CtorDeclaration::semantic(Scope *sc)
|
||||
TypeFunction *tf = (TypeFunction *)type;
|
||||
assert(tf && tf->ty == Tfunction);
|
||||
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
sc = sc->push();
|
||||
sc->stc &= ~STCstatic; // not a static constructor
|
||||
sc->flags |= SCOPEctor;
|
||||
@@ -3403,6 +3422,10 @@ void PostBlitDeclaration::semantic(Scope *sc)
|
||||
//printf("PostBlitDeclaration::semantic() %s\n", toChars());
|
||||
//printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
|
||||
//printf("stc = x%llx\n", sc->stc);
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
parent = sc->parent;
|
||||
Dsymbol *parent = toParent();
|
||||
StructDeclaration *ad = parent->isStructDeclaration();
|
||||
@@ -3476,6 +3499,10 @@ void DtorDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
//printf("DtorDeclaration::semantic() %s\n", toChars());
|
||||
//printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
parent = sc->parent;
|
||||
Dsymbol *parent = toParent();
|
||||
AggregateDeclaration *ad = parent->isAggregateDeclaration();
|
||||
@@ -3567,6 +3594,11 @@ void StaticCtorDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
//printf("StaticCtorDeclaration::semantic()\n");
|
||||
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
if (!type)
|
||||
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
|
||||
|
||||
@@ -3695,6 +3727,11 @@ Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
void StaticDtorDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
ClassDeclaration *cd = sc->scopesym->isClassDeclaration();
|
||||
|
||||
if (!type)
|
||||
@@ -3822,6 +3859,10 @@ Dsymbol *InvariantDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
void InvariantDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
parent = sc->parent;
|
||||
Dsymbol *parent = toParent();
|
||||
AggregateDeclaration *ad = parent->isAggregateDeclaration();
|
||||
@@ -3902,6 +3943,11 @@ Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
void UnitTestDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
if (global.params.useUnitTests)
|
||||
{
|
||||
if (!type)
|
||||
@@ -3985,6 +4031,11 @@ void NewDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
//printf("NewDeclaration::semantic()\n");
|
||||
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
parent = sc->parent;
|
||||
Dsymbol *parent = toParent();
|
||||
ClassDeclaration *cd = parent->isClassDeclaration();
|
||||
@@ -4069,6 +4120,11 @@ void DeleteDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
//printf("DeleteDeclaration::semantic()\n");
|
||||
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
parent = sc->parent;
|
||||
Dsymbol *parent = toParent();
|
||||
ClassDeclaration *cd = parent->isClassDeclaration();
|
||||
|
||||
28
init.c
28
init.c
@@ -21,6 +21,7 @@
|
||||
#include "scope.h"
|
||||
#include "mtype.h"
|
||||
#include "hdrgen.h"
|
||||
#include "template.h"
|
||||
|
||||
/********************************** Initializer *******************************/
|
||||
|
||||
@@ -157,8 +158,18 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
||||
if (ad->ctor)
|
||||
error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
|
||||
ad->kind(), ad->toChars(), ad->toChars());
|
||||
size_t nfields = ad->fields.dim;
|
||||
if (((StructDeclaration *)ad)->isnested) nfields--;
|
||||
StructDeclaration *sd = ad->isStructDeclaration();
|
||||
assert(sd);
|
||||
sd->size(loc);
|
||||
if (sd->sizeok != SIZEOKdone)
|
||||
{
|
||||
error(loc, "struct %s is forward referenced", sd->toChars());
|
||||
errors = 1;
|
||||
goto Lerror;
|
||||
}
|
||||
size_t nfields = sd->fields.dim;
|
||||
if (sd->isnested)
|
||||
nfields--;
|
||||
for (size_t i = 0; i < field.dim; i++)
|
||||
{
|
||||
Identifier *id = field[i];
|
||||
@@ -241,6 +252,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
||||
error(loc, "a struct is not a valid initializer for a %s", t->toChars());
|
||||
errors = 1;
|
||||
}
|
||||
Lerror:
|
||||
if (errors)
|
||||
{
|
||||
field.setDim(0);
|
||||
@@ -261,12 +273,11 @@ Expression *StructInitializer::toExpression()
|
||||
|
||||
//printf("StructInitializer::toExpression() %s\n", toChars());
|
||||
if (!ad) // if fwd referenced
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
StructDeclaration *sd = ad->isStructDeclaration();
|
||||
if (!sd)
|
||||
return NULL;
|
||||
|
||||
Expressions *elements = new Expressions();
|
||||
size_t nfields = ad->fields.dim;
|
||||
#if DMDV2
|
||||
@@ -856,6 +867,15 @@ Type *ExpInitializer::inferType(Scope *sc)
|
||||
//printf("ExpInitializer::inferType() %s\n", toChars());
|
||||
exp = exp->semantic(sc);
|
||||
exp = resolveProperties(sc, exp);
|
||||
if (exp->op == TOKimport)
|
||||
{ ScopeExp *se = (ScopeExp *)exp;
|
||||
TemplateInstance *ti = se->sds->isTemplateInstance();
|
||||
if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
|
||||
se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
|
||||
else
|
||||
se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
|
||||
return Type::terror;
|
||||
}
|
||||
|
||||
// Give error for overloaded function addresses
|
||||
if (exp->op == TOKsymoff)
|
||||
|
||||
@@ -6696,7 +6696,8 @@ Expression *TypeStruct::voidInitLiteral(VarDeclaration *var)
|
||||
exps->setDim(sym->fields.dim);
|
||||
for (size_t i = 0; i < sym->fields.dim; i++)
|
||||
{
|
||||
(*exps)[i] = new VoidInitExp(var, sym->fields[i]->type);
|
||||
//(*exps)[i] = new VoidInitExp(var, sym->fields[i]->type);
|
||||
(*exps)[i] = sym->fields[i]->type->voidInitLiteral(var);
|
||||
}
|
||||
StructLiteralExp *se = new StructLiteralExp(var->loc, sym, exps);
|
||||
se->type = this;
|
||||
|
||||
2
module.c
2
module.c
@@ -828,6 +828,8 @@ void Module::semantic2()
|
||||
return;
|
||||
}
|
||||
//printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent);
|
||||
if (semanticRun == 0) // semantic() not completed yet - could be recursive call
|
||||
return;
|
||||
if (semanticstarted >= 2)
|
||||
return;
|
||||
assert(semanticstarted == 1);
|
||||
|
||||
23
mtype.c
23
mtype.c
@@ -5827,6 +5827,19 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag)
|
||||
new IntegerExp(0, ((StringExp *)arg)->len,
|
||||
Type::tindex));
|
||||
}
|
||||
else if (arg->op == TOKstructliteral)
|
||||
match = MATCHconvert;
|
||||
else if (arg->op == TOKcall)
|
||||
{
|
||||
CallExp *ce = (CallExp *)arg;
|
||||
if (ce->e1->op == TOKdotvar &&
|
||||
((DotVarExp *)ce->e1)->var->isCtorDeclaration())
|
||||
{
|
||||
match = MATCHconvert;
|
||||
}
|
||||
else
|
||||
goto Nomatch;
|
||||
}
|
||||
else
|
||||
goto Nomatch;
|
||||
}
|
||||
@@ -7691,7 +7704,15 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
L1:
|
||||
if (!s)
|
||||
{
|
||||
return noMember(sc, e, ident);
|
||||
if (sym->scope) // it's a fwd ref, maybe we can resolve it
|
||||
{
|
||||
sym->semantic(NULL);
|
||||
s = sym->search(e->loc, ident, 0);
|
||||
if (!s)
|
||||
return noMember(sc, e, ident);
|
||||
}
|
||||
else
|
||||
return noMember(sc, e, ident);
|
||||
}
|
||||
if (!s->isFuncDeclaration()) // because of overloading
|
||||
s->checkDeprecated(e->loc, sc);
|
||||
|
||||
4
struct.c
4
struct.c
@@ -444,7 +444,7 @@ void StructDeclaration::semantic(Scope *sc)
|
||||
*/
|
||||
//if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
|
||||
{
|
||||
//printf("setScope %s %s\n", s->kind(), s->toChars());
|
||||
//printf("struct: setScope %s %s\n", s->kind(), s->toChars());
|
||||
s->setScope(sc2);
|
||||
}
|
||||
}
|
||||
@@ -466,7 +466,9 @@ void StructDeclaration::semantic(Scope *sc)
|
||||
// Ungag errors when not speculative
|
||||
unsigned oldgag = global.gag;
|
||||
if (global.isSpeculativeGagging() && !isSpeculative())
|
||||
{
|
||||
global.gag = 0;
|
||||
}
|
||||
s->semantic(sc2);
|
||||
global.gag = oldgag;
|
||||
}
|
||||
|
||||
20
template.c
20
template.c
@@ -1504,7 +1504,23 @@ Lretry:
|
||||
|
||||
if (m && (fparam->storageClass & (STCref | STCauto)) == STCref)
|
||||
{ if (!farg->isLvalue())
|
||||
goto Lnomatch;
|
||||
{
|
||||
if (farg->op == TOKstructliteral)
|
||||
m = MATCHconvert;
|
||||
else if (farg->op == TOKcall)
|
||||
{
|
||||
CallExp *ce = (CallExp *)farg;
|
||||
if (ce->e1->op == TOKdotvar &&
|
||||
((DotVarExp *)ce->e1)->var->isCtorDeclaration())
|
||||
{
|
||||
m = MATCHconvert;
|
||||
}
|
||||
else
|
||||
goto Lnomatch;
|
||||
}
|
||||
else
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
if (m && (fparam->storageClass & STCout))
|
||||
{ if (!farg->isLvalue())
|
||||
@@ -2319,7 +2335,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
|
||||
*wildmatch |= MODmutable;
|
||||
else
|
||||
*wildmatch |= (mod & ~MODshared);
|
||||
tt = mutableOf();
|
||||
tt = mutableOf()->substWildTo(MODmutable);
|
||||
dedtypes->tdata()[i] = tt;
|
||||
goto Lconst;
|
||||
}
|
||||
|
||||
5
traits.c
5
traits.c
@@ -528,6 +528,11 @@ Expression *TraitsExp::semantic(Scope *sc)
|
||||
s1 = s1->toAlias();
|
||||
s2 = s2->toAlias();
|
||||
|
||||
if (s1->isFuncAliasDeclaration())
|
||||
s1 = ((FuncAliasDeclaration *)s1)->toAliasFunc();
|
||||
if (s2->isFuncAliasDeclaration())
|
||||
s2 = ((FuncAliasDeclaration *)s2)->toAliasFunc();
|
||||
|
||||
if (s1 == s2)
|
||||
goto Ltrue;
|
||||
else
|
||||
|
||||
4
typinf.c
4
typinf.c
@@ -594,8 +594,8 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
* function with the name "toHash".
|
||||
* So I'm leaving this here as an experiment for the moment.
|
||||
*/
|
||||
if (!tf->isnothrow || tf->trust == TRUSTsystem || tf->purity == PUREimpure)
|
||||
{ warning(fd->loc, "toHash() must be declared as extern (D) uint toHash() const pure nothrow @safe, not %s", tf->toChars());
|
||||
if (!tf->isnothrow || tf->trust == TRUSTsystem /*|| tf->purity == PUREimpure*/)
|
||||
{ warning(fd->loc, "toHash() must be declared as extern (D) uint toHash() const nothrow @safe, not %s", tf->toChars());
|
||||
if (global.params.warnings == 1)
|
||||
global.errors++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user