Skip to content

Commit

Permalink
Merge pull request #1588 from 9rnsr/fix9276
Browse files Browse the repository at this point in the history
Issue 9276 - regression(2.061): Forward reference error
  • Loading branch information
WalterBright committed Jan 31, 2013
2 parents 3ad0028 + 4d3c753 commit 04902fc
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 33 deletions.
66 changes: 45 additions & 21 deletions src/template.c
Original file line number Diff line number Diff line change
Expand Up @@ -6455,30 +6455,25 @@ void TemplateMixin::semantic(Scope *sc)
{
if (!td->semanticRun)
{
if (td->scope)
td->semantic(td->scope);
/* Cannot handle forward references if mixin is a struct member,
* because addField must happen during struct's semantic, not
* during the mixin semantic.
* runDeferred will re-run mixin's semantic outside of the struct's
* semantic.
*/
semanticRun = PASSinit;
AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
if (ad)
ad->sizeok = SIZEOKfwd;
else
{
/* Cannot handle forward references if mixin is a struct member,
* because addField must happen during struct's semantic, not
* during the mixin semantic.
* runDeferred will re-run mixin's semantic outside of the struct's
* semantic.
*/
semanticRun = PASSinit;
AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
if (ad)
ad->sizeok = SIZEOKfwd;
else
{
// Forward reference
//printf("forward reference - deferring\n");
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
}
return;
// Forward reference
//printf("forward reference - deferring\n");
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
}
return;
}
}

Expand Down Expand Up @@ -6597,6 +6592,8 @@ void TemplateMixin::semantic(Scope *sc)
sc2 = argscope->push(this);
sc2->offset = sc->offset;

size_t deferred_dim = sc->module->deferred.dim;

static int nest;
//printf("%d\n", nest);
if (++nest > 500)
Expand All @@ -6616,6 +6613,33 @@ void TemplateMixin::semantic(Scope *sc)

sc->offset = sc2->offset;

if (!sc->func && sc->module->deferred.dim > deferred_dim)
{
sc2->pop();
argscope->pop();
scy->pop();

/* Cannot handle forward references if mixin is a struct member,
* because addField must happen during struct's semantic, not
* during the mixin semantic.
* runDeferred will re-run mixin's semantic outside of the struct's
* semantic.
*/
semanticRun = PASSinit;
AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
if (ad)
ad->sizeok = SIZEOKfwd;
else
{
// Forward reference
//printf("forward reference - deferring\n");
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
}
return;
}

/* The problem is when to parse the initializer for a variable.
* Perhaps VarDeclaration::semantic() should do it like it does
* for initializers inside a function.
Expand Down
14 changes: 14 additions & 0 deletions test/compilable/imports/test9276decl.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module imports.test9276decl;

import imports.test9276sem, imports.test9276visitors, imports.test9276util;

class Declaration
{
mixin DownCastMethods!TemplateDecl;
}

class TemplateDecl : OverloadableDecl
{
mixin Visitors;
}

15 changes: 15 additions & 0 deletions test/compilable/imports/test9276expr.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module imports.test9276expr;

import imports.test9276parser;
import imports.test9276util;

class Node
{
mixin DownCastMethods!Declaration;

}

class Expression : Node
{
}

1 change: 1 addition & 0 deletions test/compilable/imports/test9276hash.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module imports.test9276hash;
4 changes: 4 additions & 0 deletions test/compilable/imports/test9276parser.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module imports.test9276parser;

public import imports.test9276expr, imports.test9276decl;

25 changes: 25 additions & 0 deletions test/compilable/imports/test9276sem.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module imports.test9276sem;

class Declaration
{
mixin Visitors;
}

template Semantic(T)
{
private:
struct
{
import imports.test9276hash;
}

}



import imports.test9276visitors;

class OverloadableDecl : Declaration
{
}

12 changes: 12 additions & 0 deletions test/compilable/imports/test9276type.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module imports.test9276type;

import imports.test9276parser;

class Type : Expression // <- note to Walter.
{
}

class BasicType : Type
{
}

13 changes: 13 additions & 0 deletions test/compilable/imports/test9276util.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module imports.test9276util;

string _dgliteral(T...)()
{
foreach (t; T)
return t.stringof;
assert(0);
}
template DownCastMethods(T...)
{
enum x = _dgliteral!T;
}

16 changes: 16 additions & 0 deletions test/compilable/imports/test9276visitors.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module imports.test9276visitors;

template Visitors()
{
mixin Semantic!(typeof(this));
mixin DeepDup!(typeof(this));
}

import imports.test9276type;

template DeepDup(T) if (is(T : BasicType))
{}

template DeepDup(T)
{}

6 changes: 6 additions & 0 deletions test/compilable/test9276.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// REQUIRED_ARGS: compilable/imports/test9276parser.d


// This is a dummy module for compilable test
void main()
{}
24 changes: 12 additions & 12 deletions test/runnable/xtest46.d
Original file line number Diff line number Diff line change
Expand Up @@ -4831,7 +4831,7 @@ void test3091(inout int = 0)

template Id6837(T)
{
alias T Id6837;
alias T Id6837;
}
static assert(is(Id6837!(shared const int) == shared const int));
static assert(is(Id6837!(shared inout int) == shared inout int));
Expand Down Expand Up @@ -5703,17 +5703,17 @@ struct S162
{
static int generateMethodStubs( Class )()
{
int text;
int text;

foreach( m; __traits( allMembers, Class ) )
{
static if( is( typeof( mixin( m ) ) ) && is( typeof( mixin( m ) ) == function ) )
{
pragma(msg, __traits( getOverloads, Class, m ));
}
}
foreach( m; __traits( allMembers, Class ) )
{
static if( is( typeof( mixin( m ) ) ) && is( typeof( mixin( m ) ) == function ) )
{
pragma(msg, __traits( getOverloads, Class, m ));
}
}

return text;
return text;
}

enum int ttt = generateMethodStubs!( S162 )();
Expand Down Expand Up @@ -5776,10 +5776,10 @@ mixin template DefineCoreType(string type)

static void instance()
{
x = 3;
x = 3;
}

X164!() xxx;
X164!() xxx;
}
}

Expand Down

0 comments on commit 04902fc

Please sign in to comment.