Changeset 59

Show
Ignore:
Timestamp:
06/02/06 13:32:07 (2 years ago)
Author:
Gregor
Message:

bcd.gen/bcd/gen/bcdgen.d: It is now possible to derive D classes from C++ classes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/bcd.gen/Makefile

    r50 r59  
    55bcdgen: bcd/gen/bcdgen.d bcd/gen/libxml2.d 
    66    $(DMD) -g bcd/gen/bcdgen.d bcd/gen/libxml2.d -ofbcdgen -L-lxml2 
    7  
    8 fltk2exa: test/fltk2.d bcd/bind.d 
    9     sh test/fltk2.sh ${DMD} 
    10  
    11 libxml2exa: test/libxml2.d 
    12     sh test/libxml2.sh ${DMD} 
    13  
    14 vorbisexa: test/vorbis.d 
    15     sh test/vorbis.sh ${DMD} 
    16  
    17 gtk2exa: test/gtk2.d 
    18     sh test/gtk2.sh ${DMD} 
  • trunk/bcd.gen/bcd/gen/bcdgen.d

    r57 r59  
    4040 
    4141// some global variables (yay) 
     42private { 
    4243/** The full path to the current file */ 
    4344char[] curFile; 
     
    5253/** The C++ functions/variables to explicitly ignore */ 
    5354char[][] ignoreSyms; 
     55} 
    5456/** The D output */ 
    5557char[] dhead; 
     
    5759/** The C[++] output */ 
    5860char[] cout; 
     61private { 
     62/** The class currently being processed */ 
    5963char[] curClass; 
     64/** Was a constructor made for the current class? */ 
     65bool hasConstructor; 
     66/** Was an accessable constructor made for the current class? */ 
     67bool hasPublicConstructor; 
    6068/** Should we output C instead of C++ */ 
    6169bool outputC; 
     
    6472/** Should we generate consts for enums? */ 
    6573bool outputEnumConst; 
     74/** Should we output reflections? */ 
     75bool outputReflections; 
    6676/** Other BCD requirements */ 
    6777char[][char[]] reqDependencies; 
     
    6979xmlNode *gccxml = null; 
    7080 
     81/** Class currently being reflected into D */ 
     82char[] curReflection; 
     83/** The base of the class currently being reflected (in C++) */ 
     84char[] curReflectionCBase; 
     85/** The base of the class currently being reflected (in D) */ 
     86char[] curReflectionDBase; 
     87/** The initializer for the current reflection */ 
     88char[] curReflectionInit; 
     89/** The C++ code for the class currently being reflected */ 
     90char[] reflectionCode; 
     91/** The C++ code to go after we close the class */ 
     92char[] reflectionPostCode; 
     93/** The functions that have already been reflected */ 
     94bool[char[]] reflectedFunctions; 
     95 
    7196char[][char[]] files; 
     97} 
    7298 
    7399 
     
    88114        writefln("  -R<include directory>=<BCD/D namespace>"); 
    89115        writefln("    Depend upon other BCD namespaces."); 
     116        writefln("  -r"); 
     117        writefln("    Reflect C++ classes such that D classes can derive from"); 
     118        writefln("    them."); 
    90119        writefln("  -E"); 
    91120        writefln("    Generate const int's for unnamed enum values"); 
     
    156185            outputEnumConst = true; 
    157186             
     187        } else if (args[i] == "-r") { 
     188            outputReflections = true; 
     189 
    158190        } else { 
    159191            writefln("Argument %s not recognized.", args[i]); 
     
    419451 * Parse the members of a node 
    420452 */ 
    421 void parseMembers(xmlNode *node, bool inclass, bool types
     453void parseMembers(xmlNode *node, bool inclass, bool types, bool reflection = false
    422454{ 
    423455    char *members = xmlGetProp(node, "members"); 
     
    429461    // parse each member in the memberList 
    430462    foreach (m; memberList) { 
    431         parse_GCC_XML_for(m, inclass, types); 
     463        parse_GCC_XML_for(m, inclass, types, reflection); 
    432464    } 
    433465} 
     
    481513 * Parse a GCC_XML node for a specified ID 
    482514 */ 
    483 void parse_GCC_XML_for(char[] parseFor, bool inclass, bool types
     515void parse_GCC_XML_for(char[] parseFor, bool inclass, bool types, bool reflection = false
    484516{ 
    485517    xmlNode *curNode = null; 
     
    492524            char *id = xmlGetProp(curNode, "id"); 
    493525            if (parseFor != toStringFree(id)) continue; 
     526 
     527            if (nname == "Constructor") { 
     528                // this may be private or otherwise unparsable, but we do have one 
     529                hasConstructor = true; 
     530            } 
    494531             
    495532            // types that can be nameless: 
     
    515552             
    516553            if (nname == "Variable" || nname == "Field") { 
    517                 if (!types) parse_Variable(curNode, inclass); 
     554                if (!types && !reflection) parse_Variable(curNode, inclass); 
    518555            } else if (nname == "Method") { 
    519                 if (!types) parse_Method(curNode); 
     556                if (!types) parse_Method(curNode, reflection); 
    520557            } else if (nname == "OperatorMethod") { 
    521                 if (!types) parse_OperatorMethod(curNode); 
     558                if (!types) parse_OperatorMethod(curNode, reflection); 
    522559            } else if (nname == "Function") { 
    523                 if (!types) parse_Function(curNode); 
     560                if (!types && !reflection) parse_Function(curNode); 
    524561            } else if (nname == "Constructor") { 
    525                 if (!types) parse_Constructor(curNode); 
     562                if (!types) parse_Constructor(curNode, reflection); 
    526563            } else if (nname == "Destructor") { 
    527564                // this code is automatic :) 
    528565            } else if (nname == "Typedef") { 
    529                 if (types) parse_Typedef(curNode); 
     566                if (types && !reflection) parse_Typedef(curNode); 
    530567            } else if (nname == "Enumeration") { 
    531                 if (types) parse_Enumeration(curNode); 
     568                if (types && !reflection) parse_Enumeration(curNode); 
    532569            } else { 
    533570                writefln("I don't know how to parse %s!", nname); 
     
    601638    char[] mangled = toStringFree(getMangled(node)); 
    602639    char[] demangled = toStringFree(getDemangled(node)); 
     640    char* isabstract = xmlGetProp(node, "abstract"); 
     641    if (isabstract) free(isabstract); 
     642    curClass = demangled; 
     643    hasConstructor = false; 
     644    hasPublicConstructor = false; 
    603645     
    604646    parseMembers(node, true, true); 
     
    626668    dtail ~= "}\n"; 
    627669     
     670    dtail ~= "this(ifloat ignore, void *x) {\n"; 
     671    dtail ~= "super(ignore);\n"; 
     672    dtail ~= "__C_data = x;\n"; 
     673    dtail ~= "}\n"; 
     674     
    628675    cout ~= "void _BCD_delete_" ~ mangled ~ "(" ~ demangled ~ " *This) {\n"; 
    629676    cout ~= "delete This;\n"; 
     
    637684    dtail ~= "}\n"; 
    638685     
    639     curClass = demangled; 
    640      
    641686    parseMembers(node, true, false); 
     687     
     688    // if the constructor is implicit, replicate it here 
     689    if (!hasConstructor && !isabstract) { 
     690        dhead ~= "extern (C) void *_BCD_new_" ~ mangled ~ "();\n"; 
     691        dtail ~= "this() {\n"; 
     692        dtail ~= "super(cast(ifloat) 0);\n"; 
     693        dtail ~= "__C_data = _BCD_new_" ~ mangled ~ "();\n"; 
     694        dtail ~= "}\n"; 
     695        cout ~= demangled ~ " *_BCD_new_" ~ mangled ~ "() {\n"; 
     696        cout ~= "return new " ~ demangled ~ "();\n"; 
     697        cout ~= "}\n"; 
     698    } 
     699     
    642700    dtail ~= "}\n"; 
     701     
     702    // now make the reflected class 
     703    if (!outputReflections) return; 
     704    if (isabstract) return; // not for abstract classes yet 
     705    curReflectionCBase = demangled; 
     706    curReflectionDBase = safeName(name); 
     707    curReflection = curReflectionDBase ~ "_R"; 
     708    curReflectionInit = "_BCD_RI_" ~ mangled; 
     709     
     710    dhead ~= "extern (C) void " ~ curReflectionInit ~ "(void *cd, void *dd);\n"; 
     711     
     712    dtail ~= "class " ~ curReflection ~ " : " ~ curReflectionDBase ~ " {\n"; 
     713     
     714    dhead ~= "extern (C) void _BCD_delete_" ~ mangled ~ "__" ~ curReflection ~ "(void *This);\n"; 
     715 
     716    dtail ~= "~this() {\n"; 
     717    dtail ~= "if (__C_data) _BCD_delete_" ~ mangled ~ "__" ~ curReflection ~ "(__C_data);\n"; 
     718    dtail ~= "__C_data = null;\n"; 
     719    dtail ~= "}\n"; 
     720     
     721    reflectionPostCode = ""; 
     722     
     723    reflectionCode = "}\n"; // close the extern "C" 
     724    reflectionCode ~= "class " ~ curReflection ~ " : " ~ curReflectionCBase ~ " {\n"; 
     725    reflectionCode ~= "public:\n"; 
     726    reflectionCode ~= "void *__D_data;\n"; 
     727 
     728    hasConstructor = false; 
     729    hasPublicConstructor = false; 
     730    parseBaseReflections(node); 
     731     
     732    reflectionCode ~= "};\n"; 
     733    reflectionCode ~= "extern \"C\" {\n"; 
     734     
     735    cout ~= reflectionCode ~ reflectionPostCode; 
     736     
     737    reflectionCode = ""; 
     738    reflectedFunctions = null; 
     739     
     740    cout ~= "void _BCD_delete_" ~ mangled ~ "__" ~ curReflection ~ "(" ~ curReflection ~ " *This) {\n"; 
     741    cout ~= "delete This;\n"; 
     742    cout ~= "}\n"; 
     743     
     744    // if the constructor is implicit, make it here 
     745    if (!hasConstructor) { 
     746        dhead ~= "extern (C) void *_BCD_new_" ~ mangled ~ "__" ~ curReflection ~ "();\n"; 
     747        dtail ~= "this() {\n"; 
     748        dtail ~= "super(cast(ifloat) 0);\n"; 
     749        dtail ~= "__C_data = _BCD_new_" ~ mangled ~ "__" ~ curReflection ~ "();\n"; 
     750        dtail ~= "}\n"; 
     751        cout ~= curReflection ~ " *_BCD_new_" ~ mangled ~ "__" ~ curReflection ~ "() {\n"; 
     752        cout ~= "return new " ~ curReflection ~ "();\n"; 
     753        cout ~= "}\n"; 
     754    } else if (!hasPublicConstructor) { 
     755        dtail ~= "this() { super(cast(ireal) 0); }\n"; 
     756    } 
     757     
     758    dtail ~= "}\n"; 
     759     
     760    // then make the initializer 
     761    cout ~= "void _BCD_RI_" ~ mangled ~ "(" ~ curReflection ~ " *cd, void *dd) {\n"; 
     762    cout ~= "cd->__D_data = dd;\n"; 
     763    cout ~= "}\n"; 
     764} 
     765 
     766/** 
     767 * Recursively and reflectively parse a class' bases 
     768 */ 
     769void parseBaseReflections(xmlNode *node) 
     770{ 
     771    xmlNode *curNode = null; 
     772    for (curNode = node.children; curNode; curNode = curNode.next) { 
     773        if (curNode.type == xmlElementType.XML_ELEMENT_NODE) { 
     774            if (toString(curNode.name) == "Base") { 
     775                 
     776                // find the base class 
     777                char[] type = toStringFree(xmlGetProp(curNode, "type")); 
     778                xmlNode *curBCNode = null; 
     779                for (curBCNode = gccxml.children; curBCNode; curBCNode = curBCNode.next) { 
     780                    if (curBCNode.type == xmlElementType.XML_ELEMENT_NODE) { 
     781                        if (type == toStringFree(xmlGetProp(curBCNode, "id"))) { 
     782                            // parse this one too 
     783                            parseBaseReflections(curBCNode); 
     784                        } 
     785                    } 
     786                } 
     787                 
     788            } 
     789        } 
     790    } 
     791     
     792    // then parse this level 
     793    parseMembers(node, true, false, true); 
    643794} 
    644795 
     
    753904void parse_Arguments(xmlNode *node, inout char[] Dargs, inout char[] Deargs, 
    754905                     inout char[] Cargs, inout char[] Dcall, 
    755                      inout char[] Ccall, 
     906                     inout char[] Ccall, bool reflection = false, 
    756907                     int *argc = null) 
    757908{ 
     
    772923                    Dargs ~= ", "; 
    773924                } 
    774                 Dargs ~= atype.DType ~ " " ~ aname; 
    775                  
    776                 if (atype.isClass || atype.isClassPtr) { 
     925                if (!reflection || (!atype.isClass && !atype.isClassPtr)) { 
     926                    Dargs ~= atype.DType ~ " " ~ aname; 
     927                } else { 
     928                    Dargs ~= "void *" ~ aname; 
     929                } 
     930                 
     931                if (!reflection && (atype.isClass || atype.isClassPtr)) { 
    777932                    // this becomes a void * in D's view 
    778933                    if (Deargs != "") { 
    779934                        Deargs ~= ", "; 
    780935                    } 
    781                     Deargs ~= "void *" ~ aname
     936                    Deargs ~= "void *"
    782937                } else { 
    783938                    if (Deargs != "") { 
    784939                        Deargs ~= ", "; 
    785940                    } 
    786                     Deargs ~= atype.DType ~ " " ~ aname
     941                    Deargs ~= atype.DType
    787942                } 
    788943                 
     
    795950                    Dcall ~= ", "; 
    796951                } 
    797                 Dcall ~= aname; 
    798                 if (atype.isClass || atype.isClassPtr) { 
    799                     // turn this into the real info 
    800                     Dcall ~= ".__C_data"; 
     952                if (!reflection) { 
     953                    Dcall ~= aname; 
     954                    if (atype.isClass || atype.isClassPtr) { 
     955                        // turn this into the real info 
     956                        Dcall ~= ".__C_data"; 
     957                    } 
     958                } else { 
     959                    if (atype.isClass) { 
     960                        Dcall ~= "new " ~ atype.className ~ "(cast(ifloat) 0, " ~ aname ~ ")"; 
     961                    } else if (atype.isClassPtr) { 
     962                        Dcall ~= "cast(" ~ atype.DType ~ ") new " ~ replace(atype.DType, " *", "") ~ "(cast(ifloat) 0, " ~ aname ~ ")"; 
     963                    } else { 
     964                        Dcall ~= aname; 
     965                    } 
    801966                } 
    802967                 
     
    806971                        Ccall ~= ", "; 
    807972                    } 
    808                     Ccall ~= "*" ~ aname; 
     973                    if (!reflection) { 
     974                        Ccall ~= "*" ~ aname; 
     975                    } else { 
     976                        Ccall ~= "&" ~ aname; 
     977                    } 
    809978                } else { 
    810979                    if (Ccall != "") { 
     
    8901059} 
    8911060 
     1061void parse_Function_reflection(xmlNode *node, char[] name, char[] cname, 
     1062                               char[] mangled, ParsedType type, 
     1063                               char[] Dargs, char[] Deargs, char[] Cargs, char[] Dcall, char[] Ccall) 
     1064{ 
     1065    // tie to the particular class being reflected 
     1066    mangled ~= "__" ~ curReflection; 
     1067 
     1068    // make sure it's not already reflected 
     1069    char[] fid = name ~ "(" ~ Deargs ~ ")"; 
     1070    if (fid in reflectedFunctions) return; 
     1071    reflectedFunctions[fid] = true; 
     1072     
     1073    // make sure it's virtual 
     1074    char* isvirtual = xmlGetProp(node, "virtual"); 
     1075    if (isvirtual) free(isvirtual); 
     1076    else return; 
     1077     
     1078    // the C++ interface to the reflection 
     1079    cout ~= "int _BCD_R_" ~ mangled ~ "_CHECK(void *);\n"; 
     1080     
     1081    if (Cargs != "") 
     1082        cout ~= type.CType ~ " _BCD_R_" ~ mangled ~ "(void *, " ~ Cargs ~ ");\n"; 
     1083    else 
     1084        cout ~= type.CType ~ " _BCD_R_" ~ mangled ~ "(void *);\n"; 
     1085     
     1086    reflectionCode ~= type.CType ~ " " ~ name ~ "(" ~ Cargs ~ ") {\n"; 
     1087     
     1088    reflectionCode ~= "if (_BCD_R_" ~ mangled ~ "_CHECK(__D_data))\n"; 
     1089    if (type.CType != "void") reflectionCode ~= "return "; 
     1090     
     1091    reflectionCode ~= "_BCD_R_" ~ mangled ~ "(__D_data"; 
     1092    if (Ccall != "") reflectionCode ~= ", "; 
     1093    reflectionCode ~= Ccall ~ ");\n"; 
     1094     
     1095    reflectionCode ~= "else\n"; 
     1096    if (type.CType != "void") reflectionCode ~= "return "; 
     1097    reflectionCode ~= curReflectionCBase ~ "::" ~ cname ~ "(" ~ Ccall ~ ");\n"; 
     1098    reflectionCode ~= "}\n"; 
     1099     
     1100    // and the D interface 
     1101    dhead ~= "extern (C) int _BCD_R_" ~ mangled ~ "_CHECK(" ~ curReflection ~ " x) {\n"; 
     1102    dhead ~= "union dp {\n"; 
     1103    dhead ~= type.DType ~ " delegate(" ~ Deargs ~ ") d;\n"; 
     1104    dhead ~= "struct { void *o; void *f; }\n"; 
     1105    dhead ~= "}\n"; 
     1106    dhead ~= "dp d; d.d = &x." ~ name ~ ";\n"; 
     1107    dhead ~= "return cast(int) (d.f != &" ~ curReflectionDBase ~ "." ~ name ~ ");\n"; 
     1108    dhead ~= "}\n"; 
     1109     
     1110    dhead ~= "extern (C) " ~ type.DType ~ " _BCD_R_" ~ mangled ~ "(" ~ curReflection ~ " __D_class, " ~ 
     1111    Dargs ~ ") {\n"; 
     1112    if (type.DType != "void") dhead ~= "return "; 
     1113    dhead ~= "__D_class." ~ name ~ "(" ~ Dcall ~ ");\n"; 
     1114    dhead ~= "}\n"; 
     1115} 
     1116 
    8921117/** 
    8931118 * Parse a Method node 
    8941119 */ 
    895 void parse_Method(xmlNode *node
     1120void parse_Method(xmlNode *node, bool reflection
    8961121{ 
    8971122    char[] name = getNName(node); 
     
    8991124    ParsedType type = parseType(toStringFree(xmlGetProp(node, "returns"))); 
    9001125    char[] Dargs; 
    901     char[] Deargs = "void *This"; 
    902     char[] Cargs = curClass ~ " *This"; 
    903     char[] Dcall = "__C_data"; 
     1126    char[] Deargs; 
     1127    if (!reflection) Deargs = "void *This"; 
     1128    char[] Cargs; 
     1129    if (!reflection) Cargs = curClass ~ " *This"; 
     1130    char[] Dcall; 
     1131    if (!reflection) Dcall = "__C_data"; 
    9041132    char[] Ccall; 
    9051133     
    906     parse_Arguments(node, Dargs, Deargs, Cargs, Dcall, Ccall); 
    907     parse_Function_body(node, safeName(name), mangled, "This->" ~ name, type, 
    908                         Dargs, Deargs, Cargs, Dcall, Ccall); 
     1134    parse_Arguments(node, Dargs, Deargs, Cargs, Dcall, Ccall, reflection); 
     1135    if (!reflection) 
     1136        parse_Function_body(node, safeName(name), mangled, "This->" ~ name, type, 
     1137                            Dargs, Deargs, Cargs, Dcall, Ccall); 
     1138    else 
     1139        parse_Function_reflection(node, safeName(name), name, mangled, type, 
     1140                                  Dargs, Deargs, Cargs, Dcall, Ccall); 
    9091141} 
    9101142 
     
    9121144 * Parse an OperatorMethod node 
    9131145 */ 
    914 void parse_OperatorMethod(xmlNode *node
     1146void parse_OperatorMethod(xmlNode *node, bool reflection
    9151147{ 
    9161148    char[] name = toStringFree(xmlGetProp(node, "name"));; 
     
    9181150    ParsedType type = parseType(toStringFree(xmlGetProp(node, "returns"))); 
    9191151    char[] Dargs; 
    920     char[] Deargs = "void *This"; 
    921     char[] Cargs = curClass ~ " *This"; 
    922     char[] Dcall = "__C_data"; 
     1152    char[] Deargs; 
     1153    if (!reflection) Deargs = "void *This"; 
     1154    char[] Cargs; 
     1155    if (!reflection) Cargs = curClass ~ " *This"; 
     1156    char[] Dcall; 
     1157    if (!reflection) Dcall = "__C_data"; 
    9231158    char[] Ccall; 
    9241159    int argc; 
    9251160     
    926     parse_Arguments(node, Dargs, Deargs, Cargs, Dcall, Ccall, &argc); 
     1161    parse_Arguments(node, Dargs, Deargs, Cargs, Dcall, Ccall, reflection, &argc); 
    9271162     
    9281163    // get the D name 
     
    10691304    if (dname == "") return; 
    10701305     
    1071     parse_Function_body(node, dname, mangled, "This->" ~ name, type, 
    1072                         Dargs, Deargs, Cargs, Dcall, Ccall); 
     1306    if (!reflection) 
     1307        parse_Function_body(node, dname, mangled, "This->" ~ name, type, 
     1308                            Dargs, Deargs, Cargs, Dcall, Ccall); 
     1309    else 
     1310        parse_Function_reflection(node, dname, name, mangled, type, 
     1311                                  Dargs, Deargs, Cargs, Dcall, Ccall); 
    10731312} 
    10741313 
     
    11021341 * Parse a Constructor node 
    11031342 */ 
    1104 void parse_Constructor(xmlNode *node
     1343void parse_Constructor(xmlNode *node, bool reflection
    11051344{ 
    11061345    if (outputC) return; // no constructors in C 
     
    11081347    char[] name = getNName(node); 
    11091348    char[] mangled = toStringFree(getMangled(node)); 
     1349    if (reflection) mangled ~= "_R"; 
    11101350     
    11111351    while (find(mangled, "*INTERNAL*") != -1) { 
     
    11141354     
    11151355    char[] Dargs; 
    1116     char[] Deargs = "void *This"; 
     1356    char[] Deargs; 
     1357    if (!reflection) Deargs = "void *"; 
    11171358    char[] Cargs; 
    1118     if (outputC) { 
    1119         Cargs = "struct " ~ curClass ~ " *This"; 
    1120     } else { 
    1121         Cargs = curClass ~ " *This"; 
    1122     } 
    1123     char[] Dcall = "__C_data"; 
     1359    if (!reflection) { 
     1360        if (outputC) { 
     1361            Cargs = "struct " ~ curClass ~ " *This"; 
     1362        } else { 
     1363            Cargs = curClass ~ " *This"; 
     1364        } 
     1365    } 
     1366    char[] Dcall; 
     1367    if (!reflection) Dcall = "__C_data"; 
    11241368    char[] Ccall; 
    11251369     
    1126     parse_Arguments(node, Dargs, Deargs, Cargs, Dcall, Ccall); 
     1370    if (reflection) { 
     1371        // only reflect one level of constructors 
     1372        if (name != curReflectionDBase) return; 
     1373    } 
     1374     
     1375    parse_Arguments(node, Dargs, Deargs, Cargs, Dcall, Ccall, reflection); 
     1376     
     1377    if (reflection) { 
     1378        // make sure it's not already reflected 
     1379        char[] fid = name ~ "(" ~ Deargs ~ ")"; 
     1380        if (fid in reflectedFunctions) return; 
     1381        reflectedFunctions[fid] = true; 
     1382    } 
    11271383     
    11281384    dhead ~= "extern (C) void *_BCD_new_" ~ mangled ~ "(" ~ Deargs ~ ");\n"; 
     
    11311387    dtail ~= "super(cast(ifloat) 0);\n"; 
    11321388    dtail ~= "__C_data = _BCD_new_" ~ mangled ~ "(" ~ Dcall ~ ");\n"; 
     1389    if (reflection) { 
     1390        dtail ~= curReflectionInit ~ "(__C_data, cast(void *) this);\n"; 
     1391    } 
    11331392    dtail ~= "}\n"; 
    11341393     
    1135     cout ~= curClass ~ " *_BCD_new_" ~ mangled ~ "(" ~ Cargs ~ ") {\n"; 
    1136     cout ~= "return new " ~ curClass ~ "(" ~ Ccall ~ ");\n"; 
    1137     cout ~= "}\n"; 
     1394    if (!reflection) { 
     1395        cout ~= curClass ~ " *_BCD_new_" ~ mangled ~ "(" ~ Cargs ~ ") {\n"; 
     1396        cout ~= "return new "; 
     1397        cout ~= curClass; 
     1398        cout ~= "(" ~ Ccall ~ ");\n"; 
     1399        cout ~= "}\n"; 
     1400    } else { 
     1401        reflectionCode ~= curReflection ~ "(" ~ Cargs ~ ") : " ~ curReflectionCBase ~ "(" ~ Ccall ~ ") {}\n"; 
     1402        reflectionPostCode ~= curReflection ~ " *_BCD_new_" ~ mangled ~ "(" ~ Cargs ~ ") {\n"; 
     1403        reflectionPostCode ~= "return new "; 
     1404        reflectionPostCode ~= curReflection; 
     1405        reflectionPostCode ~= "(" ~ Ccall ~ ");\n"; 
     1406        reflectionPostCode ~= "}\n"; 
     1407    } 
     1408 
     1409    hasPublicConstructor = true; 
    11381410} 
    11391411 
     
    13771649                        pt.DType ~= " *"; 
    13781650                        pt.isClassPtr = true; 
     1651                         
     1652                        // if this is a const, our const will be on the wrong side! 
     1653                        if (pt.CType.length >= 7 && 
     1654                            pt.CType[pt.CType.length - 7 .. pt.CType.length] == "* const") { 
     1655                            pt.CType[pt.CType.length - 7 .. pt.CType.length] = "const *"; 
     1656                        } 
     1657                         
    13791658                        parsedCache[type] = pt; 
    13801659                    } else { 
     
    14191698                     
    14201699                        // 1) cut off the * 
    1421                         baseType.CType = baseType.CType[0 .. baseType.CType.length - 2]; 
     1700                        int l = rfind(baseType.CType, '*'); 
     1701                        if (l != -1) baseType.CType[l] = ' '; 
    14221702                         
    14231703                        // 2) add the & 
     
    14931773                    // this is just a const 
    14941774                    ParsedType pt = parseType(toStringFree(xmlGetProp(curNode, "type"))); 
    1495                  
    1496                     if (pt.CType.length < 6 || 
     1775                     
     1776                    /*if (pt.CType.length >= 2) { 
     1777                        char[] pfix = pt.CType[pt.CType.length - 2 .. pt.CType.length]; 
     1778                        if (pfix == " *" || 
     1779                            pfix == " &") { 
     1780                            pt.CType = pt.CType[0 .. pt.CType.length - 2] ~ 
     1781                            " const" ~ pfix; 
     1782                            parsedCache[type] = pt; 
     1783                            break; 
     1784                        } 
     1785                    }*/ 
     1786                     
     1787                    /*if (pt.CType.length < 6 || 
    14971788                        pt.CType[0..6] != "const ") 
    1498                         pt.CType = "const " ~ pt.CType; 
     1789                        pt.CType = "const " ~ pt.CType;*/ 
     1790                    pt.CType ~= " const"; 
     1791                     
    14991792                    parsedCache[type] = pt; 
    15001793