www.digitalmars.com         C & C++   DMDScript  

D.gnu - [Issue 36] New: Templates declared in functions have wrong scope

http://gdcproject.org/bugzilla/show_bug.cgi?id=36

             Bug #: 36
           Summary: Templates declared in functions have wrong scope
    Classification: Unclassified
           Product: GDC
           Version: development
          Platform: x86_64
        OS/Version: Linux
            Status: NEW
          Severity: major
          Priority: Normal
         Component: gdc
        AssignedTo: ibuclaw gdcproject.org
        ReportedBy: johannespfau gmail.com


Created attachment 27
  --> http://gdcproject.org/bugzilla/attachment.cgi?id=27
Proposed partial patch

Template instances of templates declared in functions must have their scope set
to that function. (Template instances with nested args have even more strict
requirements, their scope should be the scope where they are instantiated).

Here's a pseudo-example:
-------------------
void func()
{
    void nested(){}
    void nestedTemplate()()
    {nested();}

    void nested2()
    {nestedTemplate()} //<--creates instance. scope should be func,
    //currently is module scope
}
-------------------

There are two reasons for this problem:
TemplateInstances created in functions are added to the Module->members array
by the frontend.
TemplateInstances created in structs/classes/interfaces are added to the
struct/class/interface members array and work fine.

The other reason is the way gdc sets the scope of functions/classes/etc: The
scope is set by FuncDeclaration::toObjFile which calls irs->startScope(); then
emits it's member functions, then calls irs->endScope();

So the simplest solution would be to add code to toObjFile which emits
templates instantiated in that function. This is what the attached patch does
(it also makes sure that the TemplateInstace->toObjFile method is not called
from the modules genobjfile first) and I'll probably file a pull request for
it.

But this solution is incomplete. It fixes test case 1&2 which is already good.
But it can't fix test case 3: There's a fundamental problem:

We require the S!(int) instance to be output from parseJSON(test3a) to set the
scope correctly. This means we have to call S!(int)->toObjFile from
parseJSON->toObjFile.
But when the S!int instance is actually created in module test3b,
parseJSON->toObjFile has already been called when compiling test3a and we can't
call parseJSON->toObjFile in module test3b! So with the current way of pushing
scopes there's no way to implement this correctly!

BTW: DMD does not push any scopes in it's FuncDeclaration::toObjFile and
therefore avoids this problem.

-- 
Configure issuemail: http://gdcproject.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all issue changes.
Jan 19 2013