www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [DDMD] Reasoning behind converting new Type -> Type::create

reply "Iain Buclaw" <ibuclaw ubuntu.com> writes:
Question aimed at Daniel.

I noticed this change in the frontend merge:

---
   -4539,6 +4736,11    TypeAArray::TypeAArray(Type *t, Type 
*index)
      this->sc = NULL;
  }

+TypeAArray *TypeAArray::create(Type *t, Type *index)
+{
+    return new TypeAArray(t, index);
+}
+
  const char *TypeAArray::kind()
  {
      return "aarray";
---

I couldn't see any reference to this in the frontend, so did a 
quick diff 2.064 from master and saw the following at a glance.

---
   -5179,7 +5020,7    elem *AssocArrayLiteralExp::toElem(IRState 
*irs)
          else
          {   // It's the AssociativeArray type.
              // Turn it back into a TypeAArray
-            ta = new TypeAArray((*values)[0]->type, 
(*keys)[0]->type);
+            ta = TypeAArray::create((*values)[0]->type, 
(*keys)[0]->type);
              ta = ta->semantic(loc, NULL);
          }
---

Assuming this needs to be done for all new'ing of classes across 
C++ -> D, it looks like you've only done half a job?  Surely you 
should define a ::create for all Type's on the chance that the 
backend might *actually* need it irrespective of what DMD does?

This is what I see in gdc's code.

---
$ grep "Type.*::create" d/dfrontend/mtype.c
TypeAArray *TypeAArray::create(Type *t, Type *index)
TypeFunction *TypeFunction::create(Parameters *parameters, Type 
*treturn, int varargs, LINK linkage, StorageClass stc)
TypeTuple *TypeTuple::create(Parameters *arguments)

$ grep "new Type" d/*
d-builtins.c:	    return new TypePointer (d);
d-builtins.c:	  d = new TypePointer (d);
d-builtins.c:	  d = new TypeVector (Loc(), d);
d-builtins.c:      sdecl->type = new TypeStruct (sdecl);
d-builtins.c:      d = new TypeFunction (t_args, typefunc_ret, 
t_varargs, LINKc);
d-codegen.cc:      TypeFunction *tf = new TypeFunction (NULL, 
decl->type, false, LINKd);
d-codegen.cc:      TypeDelegate *t = new TypeDelegate (tf);
d-codegen.cc:      TypeFunction *tf = new TypeFunction (NULL, 
arg->type, false, LINKd);
d-codegen.cc:      TypeDelegate *t = new TypeDelegate (tf);
d-codegen.cc:	aatype = new TypeAArray (Type::tvoidptr, 
Type::tvoidptr);
d-elem.cc:      aa_type = new TypeAArray ((*values)[0]->type, 
(*keys)[0]->type);
d-objfile.cc:  TypeFunction *func_type = new TypeFunction (0, 
Type::tvoid, 0, LINKc);
---

I guess this means that things would be broken if I switched to 
DDMD today... =)

Regards
Iain.
Jan 27 2014
next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw"  wrote in message news:tahhleknrghaegcdvfgz forum.dlang.org...

 Question aimed at Daniel.

 Assuming this needs to be done for all new'ing of classes across C++ -> D, 
 it looks like you've only done half a job?  Surely you should define a 
 ::create for all Type's on the chance that the backend might *actually* 
 need it irrespective of what DMD does?

Yeah, for now you can't new anything from C++ that's written in D. You also can't stack-allocate if it has a constructor and destructor. I'm not expecting these limitations to go away any time soon. This applies to pretty much every struct/class except OutBuffer. I didn't want to introduce new dead code. It should be trivial to add more methods if you like, or it can wait until you start building DDMD and get linker errors!
 I guess this means that things would be broken if I switched to DDMD 
 today... =)

There are probably a couple of other things too, but there shouldn't be anything non-trivial. Maybe tomorrow?
Jan 27 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw"  wrote in message 
news:mailman.99.1390837599.13884.digitalmars-d puremagic.com...
 OK.  Have you tested calling C++ destructors from D?

No, and I don't think they even mangle correctly.
 This I ask in sincerity as there is a file with functions re-written
 from the frontend to work with gdc.  Wouldn't want to hit any brick
 walls here...

I guess we should get to splitting up mars.c global.c/global.h/error.c/error.h ? Are you planning to have all the gdc driver/glue code in C++ or port some of it to D?
Jan 27 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw"  wrote in message 
news:mailman.100.1390839683.13884.digitalmars-d puremagic.com...
 I tried that once before, only to be asked "Why are you doing this?" :o)

I still think 'verbose' is a good idea (that switch has zero coverage in the test suite btw). But yeah, one thing at a time.
 Admittedly, it had some other stuff until I gave up waiting, sent a
 pull for global.stdmsg (which got merged in) then reimplemented error,
 warning, etc... in gdc.

That seems fine for error/warning/etc but Loc and Global should really be shared. Although global really shouldn't have so much crammed into it. eg doXGeneration and debugf mean nothing to the frontend.
 There are some parts that could be ported to D.  But by and large,
 it's not going to be pretty.  ie: There's no possible way for us to
 correctly mangle c_long in D, and there are some types in GCC that -
 depending on the host - could be typedef'd to long, long long or
 int64_t.

We seem to be getting away with that in dmd, as long as OSX and win64 don't hide any more nasties. (btw do you have any idea what's wrong with pull 3158?) Making functions extern(C) seems to be the easiest short-term solution, and pragma(mangle) will start actually working on windows once the new C++ mangler is in.
Jan 27 2014
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw"  wrote in message 
news:mailman.103.1390845530.13884.digitalmars-d puremagic.com...

 I have toyed around with the thought of moving backend specific
 members into a Compiler struct which may vary across gdc, dmd, ldc...

I feel like Global should just be for frontend and semantic config, and the backend/glue stuff should be kept somewhere else.
 I can't see at a glance any target specific mangling for long.  Only
 __float128 and __float80.

 As for long size, there's no darwin specific value for LONG_SIZE nor
 LONG_LONG_SIZE, so whatever you are getting, it's the same on Linux
 too...

:(
 Making functions extern(C) seems to be the easiest short-term solution, 
 and
 pragma(mangle) will start actually working on windows once the new C++
 mangler is in.

Don't know what you are talking about, it already works on Windows... :o)

Not so much with the dmc backend doing the mangling... it just re-mangles using the mangle string you set in place of the ident.
 I would have to seriously consider keeping or forking cppmangle once
 it is visual studio-afied....

It should be trivial to let Target choose the mangler.
Jan 27 2014
prev sibling next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 27 January 2014 15:00, Daniel Murphy <yebbliesnospam gmail.com> wrote:
 "Iain Buclaw"  wrote in message news:tahhleknrghaegcdvfgz forum.dlang.org...

 Question aimed at Daniel.

 Assuming this needs to be done for all new'ing of classes across C++ -> D,
 it looks like you've only done half a job?  Surely you should define a
 ::create for all Type's on the chance that the backend might *actually* need
 it irrespective of what DMD does?

Yeah, for now you can't new anything from C++ that's written in D. You also can't stack-allocate if it has a constructor and destructor. I'm not expecting these limitations to go away any time soon. This applies to pretty much every struct/class except OutBuffer. I didn't want to introduce new dead code. It should be trivial to add more methods if you like, or it can wait until you start building DDMD and get linker errors!

OK. Have you tested calling C++ destructors from D? This I ask in sincerity as there is a file with functions re-written from the frontend to work with gdc. Wouldn't want to hit any brick walls here... --- $ grep "^[a-zA-Z].* (" d-glue.cc Global::init (void) Global::startGagging (void) Global::endGagging (unsigned oldGagged) Global::isSpeculativeGagging (void) Global::increaseErrorCount (void) Dsymbol::ungagSpeculative (void) Ungag::~Ungag (void) Loc::toChars (void) Loc::Loc (Module *mod, unsigned linnum) Loc::equals (const Loc& loc) error (Loc loc, const char *format, ...) error (const char *filename, unsigned linnum, const char *format, ...) verror (Loc loc, const char *format, va_list ap, errorSupplemental (Loc loc, const char *format, ...) verrorSupplemental (Loc loc, const char *format, va_list ap) warning (Loc loc, const char *format, ...) vwarning (Loc loc, const char *format, va_list ap) deprecation (Loc loc, const char *format, ...) vdeprecation (Loc loc, const char *format, va_list ap, fatal (void) escapePath (OutBuffer *buf, const char *fname) readFile (Loc loc, File *f) writeFile (Loc loc, File *f) ensurePathToNameExists (Loc loc, const char *name) FuncDeclaration::isBuiltin (void) eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments) ---
Jan 27 2014
prev sibling next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 27 January 2014 16:04, Daniel Murphy <yebbliesnospam gmail.com> wrote:
 "Iain Buclaw"  wrote in message
 news:mailman.99.1390837599.13884.digitalmars-d puremagic.com...

 OK.  Have you tested calling C++ destructors from D?

No, and I don't think they even mangle correctly.
 This I ask in sincerity as there is a file with functions re-written
 from the frontend to work with gdc.  Wouldn't want to hit any brick
 walls here...

I guess we should get to splitting up mars.c global.c/global.h/error.c/error.h ?

I tried that once before, only to be asked "Why are you doing this?" :o) Admittedly, it had some other stuff until I gave up waiting, sent a pull for global.stdmsg (which got merged in) then reimplemented error, warning, etc... in gdc.
 Are you planning to have all the gdc driver/glue code in C++ or port some of
 it to D?

There are some parts that could be ported to D. But by and large, it's not going to be pretty. ie: There's no possible way for us to correctly mangle c_long in D, and there are some types in GCC that - depending on the host - could be typedef'd to long, long long or int64_t.
Jan 27 2014
prev sibling next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 27 January 2014 16:50, Daniel Murphy <yebbliesnospam gmail.com> wrote:
 "Iain Buclaw"  wrote in message
 news:mailman.100.1390839683.13884.digitalmars-d puremagic.com...

 I tried that once before, only to be asked "Why are you doing this?" :o)

I still think 'verbose' is a good idea (that switch has zero coverage in the test suite btw). But yeah, one thing at a time.
 Admittedly, it had some other stuff until I gave up waiting, sent a
 pull for global.stdmsg (which got merged in) then reimplemented error,
 warning, etc... in gdc.

That seems fine for error/warning/etc but Loc and Global should really be shared. Although global really shouldn't have so much crammed into it. eg doXGeneration and debugf mean nothing to the frontend.

Not to mention undocumented --f --c style switches that on the surface don't even look like they do anything. But that is dmd baggage... I have toyed around with the thought of moving backend specific members into a Compiler struct which may vary across gdc, dmd, ldc...
 There are some parts that could be ported to D.  But by and large,
 it's not going to be pretty.  ie: There's no possible way for us to
 correctly mangle c_long in D, and there are some types in GCC that -
 depending on the host - could be typedef'd to long, long long or
 int64_t.

We seem to be getting away with that in dmd, as long as OSX and win64 don't hide any more nasties. (btw do you have any idea what's wrong with pull 3158?)

I can't see at a glance any target specific mangling for long. Only __float128 and __float80. As for long size, there's no darwin specific value for LONG_SIZE nor LONG_LONG_SIZE, so whatever you are getting, it's the same on Linux too...
 Making functions extern(C) seems to be the easiest short-term solution, and
 pragma(mangle) will start actually working on windows once the new C++
 mangler is in.

Don't know what you are talking about, it already works on Windows... :o) I would have to seriously consider keeping or forking cppmangle once it is visual studio-afied....
Jan 27 2014
prev sibling next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 28 January 2014 02:27, Daniel Murphy <yebbliesnospam gmail.com> wrote:
 I would have to seriously consider keeping or forking cppmangle once
 it is visual studio-afied....

It should be trivial to let Target choose the mangler.

That isn't half the point. Anyway, I've had some plans with cppmangler for sometime now.
Jan 28 2014
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Tue, 28 Jan 2014 13:10:52 +0000
schrieb Iain Buclaw <ibuclaw gdcproject.org>:

 On 28 January 2014 02:27, Daniel Murphy <yebbliesnospam gmail.com>
 wrote:
 I would have to seriously consider keeping or forking cppmangle
 once it is visual studio-afied....

It should be trivial to let Target choose the mangler.

That isn't half the point. Anyway, I've had some plans with cppmangler for sometime now.

Somehow sounds like you want to hook into the g++ frontend to do the mangling?
Jan 28 2014
prev sibling next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 28 January 2014 13:25, Johannes Pfau <nospam example.com> wrote:
 Am Tue, 28 Jan 2014 13:10:52 +0000
 schrieb Iain Buclaw <ibuclaw gdcproject.org>:

 On 28 January 2014 02:27, Daniel Murphy <yebbliesnospam gmail.com>
 wrote:
 I would have to seriously consider keeping or forking cppmangle
 once it is visual studio-afied....

It should be trivial to let Target choose the mangler.

That isn't half the point. Anyway, I've had some plans with cppmangler for sometime now.

Somehow sounds like you want to hook into the g++ frontend to do the mangling?

Nah... Keep the same implementation. I was thinking more along the lines of using bells and whistles that are GDC specific. For example: targetm.mangle_type - which is needed if we want compatible C++ mangling on ARM for va_list or vector types. As for g++ frontend mangle.c, we would require having some form of -fabi-version=n switch; which is a bit exper. And besides I don't feel like satisfying the need of some lone guy out there who requires C++ mangling ABI greater than v.3 from D. Regards Iain
Jan 28 2014
prev sibling parent Johannes Pfau <nospam example.com> writes:
Am Tue, 28 Jan 2014 16:00:50 +0000
schrieb Iain Buclaw <ibuclaw gdcproject.org>:

 Somehow sounds like you want to hook into the g++ frontend to do the
 mangling?

Nah... Keep the same implementation. I was thinking more along the lines of using bells and whistles that are GDC specific. For example: targetm.mangle_type - which is needed if we want compatible C++ mangling on ARM for va_list or vector types. As for g++ frontend mangle.c, we would require having some form of -fabi-version=n switch; which is a bit exper. And besides I don't feel like satisfying the need of some lone guy out there who requires C++ mangling ABI greater than v.3 from D. Regards Iain

That sounds reasonable. I had a quick look on how difficult it is to hook into another frontend in GCC some time ago and IIRC it's almost impossible so I was kinda surprised.
Jan 28 2014