http://d.puremagic.com/issues/show_bug.cgi?id=2339





------- Comment #2 from matti.niemenmaa+dbugzi...@iki.fi  2009-04-23 09:53 
-------
I think the problem in the fourth case might be in how it gets parsed. Here's a
snippet from the frontend's normally-commented-out printf() and logging calls
on the first, working case:

parseStaticAssert()
p = 0xf97c4a, *p = ' '
p = 0xf97c4b, *p = '('
p = 0xf97c4c, *p = 'C'
t->value = 120
parsePrimaryExp(): loc = 13
p = 0xf97c51, *p = '!'
p = 0xf97c52, *p = '('
Dsymbol::Dsymbol(0xf98df0, ident <NULL>)
TemplateInstance(this = 0xf98df0, ident = 'Check')
Parser::parseTemplateArgumentList()
p = 0xf97c53, *p = 'F'
t->value = 120
isDeclaration(needId = 0)
p = 0xf97c5b, *p = '.'
p = 0xf97c5c, *p = 'x'
t->value = 120
p = 0xf97c5d, *p = ')'
is
Parser::isDeclarator()
parseBasicType()
parseDeclarator(tpl = (nil))
parseBasicType2()
p = 0xf97c5e, *p = ')'
Expression::Expression(op = 156) this = 0xf990f0
ObjectToCBuffer()
        t: FooMixin.x ty = 6
ScopeExp::ScopeExp(pkg = 'Check!(FooMixin.x)')

As far as I can tell, when the whole expression is recognized as a template
instantiation it goes into parseTemplateArgumentList() and makes it into an
expression of type TOKimport (??). The whole thing is then one big ScopeExp.

Here's how the contents of the string mixin are parsed:

Lexer::Lexer(0xf99430,0,10)
lexer.mod = 0xf97770, 0xf97ab0
Parser::Parser()
p = 0xf99430, *p = 'F'
t->value = 120
p.loc.linnum = 21
Parser::parseExpression() loc = 21
parsePrimaryExp(): loc = 21
p = 0xf99438, *p = '.'
Expression::Expression(op = 120) this = 0xfcded0
p = 0xf99439, *p = 'x'
t->value = 120
p = 0xf9943a, *p = '^@'
Expression::Expression(op = 101) this = 0xfcdf20
DotIdExp::toCBuffer()
DotIdExp::semantic(this = 0xfcdf20, 'FooMixin.x')

This time, the inner expression becomes a DotIdExp, which I think has something
to do with why the semantic phases diverge later on. Here's the working one,
starting from just before a Scope::search call:

TypeIdentifier::resolve(sc = 0xfca6f0, idents = 'FooMixin.x')
Scope::search(0xfca6f0, 'FooMixin')
        looking in scopesym 'X', kind = 'class'
X.ClassDeclaration::search('FooMixin')
X->ScopeDsymbol::search(ident='FooMixin', flags=x0)
        s = 'X.FooTemplate!()'
        found X.FooTemplate!(), kind = 'mixin'
TypeQualified::resolveHelper(sc = 0xfca6f0, idents = 'FooMixin.x')
        scopesym = 'X'
        1: s = 'FooTemplate!()' 0xf98c30, kind = 'mixin'

And here's the non-working one:

UnaExp::semantic('FooMixin.x')
IdentifierExp::semantic('FooMixin')
Scope::search(0xfca6f0, 'FooMixin')
        looking in scopesym 'X', kind = 'class'
X.ClassDeclaration::search('FooMixin')
X->ScopeDsymbol::search(ident='FooMixin', flags=x0)
        s = 'X.FooTemplate!()'
        found X.FooTemplate!(), kind = 'mixin'
Expression::Expression(op = 42) this = 0xfce010
DsymbolExp::semantic('FooTemplate!()')
DsymbolExp:: 0xfce010 'FooTemplate!()' is a symbol

For a solution, I considered setting a flag in
TemplateInstance::semanticTiargs, just prior to the latter Expression::semantic
call, which would tell CompileExp (the one that handles string mixins) that
we're actually looking for template arguments. It would then do something like
what Parser::parseTemplateArgumentList does, instead of just looking at the
expression in isolation. But I don't actually have any clue whether this would
help or not. Also, I think it would require some special handling for comma
expressions, or manually wrapping the contents of the mixin'd string in
brackets before passing it to the parser.


-- 

Reply via email to