From 537bf545a2a341f823c496b69696abac6ed05543 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Wed, 22 Aug 2018 01:11:22 +0200 Subject: [PATCH 01/44] Testing D to H tool --- src/dmd/dtoh.d | 1256 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1256 insertions(+) create mode 100644 src/dmd/dtoh.d diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d new file mode 100644 index 000000000000..1eaf4ddea043 --- /dev/null +++ b/src/dmd/dtoh.d @@ -0,0 +1,1256 @@ +// Compiler implementation of the D programming language +// Copyright (c) 1999-2015 by Digital Mars +// All Rights Reserved +// written by Walter Bright +// http://www.digitalmars.com +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +module dmd.dtoh; + +import core.stdc.stdio; +import core.stdc.string; +import core.stdc.ctype; + +import dmd.astcodegen; +import dmd.arraytypes; +import dmd.globals; +import dmd.identifier; +import dmd.visitor; + +import dmd.root.outbuffer; + +immutable string[] frontendSources = [ + "access.d", "aggregate.d", "aliasthis.d", "apply.d", "argtypes.d", "arrayop.d", "arraytypes.d", "attrib.d", + "blockexit.d", "builtin.d", + "canthrow.d", "clone.d", "compiler.d", "complex.d", "cond.d", "console.d", "constfold.d", "cppmangle.d", "cppmanglewin.d", "ctfeexpr.d", "ctorflow.d", + "dcast.d", "dclass.d", "declaration.d", "delegatize.d", "denum.d", "dimport.d", "dinterpret.d", + "dmacro.d", "dmangle.d", "dmodule.d", "doc.d", "dscope.d", "dstruct.d", "dsymbol.d", "dsymbolsem.d", "dtemplate.d", "dversion.d", + "entity.d", "errors.d", "escape.d", "expression.d", "expressionsem.d", + "func.d", + "globals.d", "gluelayer.d", + "hdrgen.d", + "iasm.d", "id.d", "identifier.d", "impcnvtab.d", "imphint.d", "init.d", "initsem.d", "inline.d", "inlinecost.d", "intrange.d", + "json.d", + "lambdacomp.d", "lexer.d", + "mtype.d", + "nogc.d", "nspace.d", + "objc.d", "opover.d", "optimize.d", + "parse.d", "printast.d", + "safe.d", "sapply.d", "semantic2.d", "semantic3.d", "sideeffect.d", "statement.d", + "statementsem.d", "staticassert.d", "staticcond.d", + "target.d", "templateparamsem.d", "tokens.d", "traits.d", "typesem.d", "typinf.d", + "utf.d", "utils.d", +]; + +private bool isIdentifierClass(ASTCodegen.ClassDeclaration cd) +{ + return (cd.ident == Identifier.idPool("Identifier") && + cd.parent !is null && + cd.parent.ident == Identifier.idPool("identifier") && + cd.parent.parent && cd.parent.parent.ident == Identifier.idPool("dmd") && + !cd.parent.parent.parent); +} + +private bool isVisitorClass(ASTCodegen.ClassDeclaration cd) +{ + for (auto cdb = cd; cdb; cdb = cdb.baseClass) + { + if (cdb.ident == Identifier.idPool("Visitor") || + cdb.ident == Identifier.idPool("ParseTimeVisitor")) + return true; + } + return false; +} + +private bool isFrontendModule(ASTCodegen.Module m) +{ + if (!m || !m.parent) + return false; + + // Ignore dmd.root + if (m.parent.ident == Identifier.idPool("root") && + m.parent.parent && m.parent.parent.ident == Identifier.idPool("dmd") && + !m.parent.parent.parent) + { + return false; + } + + // Ignore dmd.visitor and derivatives + if ((m.ident == Identifier.idPool("visitor") || + m.ident == Identifier.idPool("parsetimevisitor") || + m.ident == Identifier.idPool("permissivevisitor") || + m.ident == Identifier.idPool("strictvisitor") || + m.ident == Identifier.idPool("transitivevisitor")) && + m.parent && m.parent.ident == Identifier.idPool("dmd") && + !m.parent.parent) + { + return false; + } + + return ((m.parent.ident == Identifier.idPool("dmd") && !m.parent.parent) || + (m.parent.parent.ident == Identifier.idPool("dmd") && !m.parent.parent.parent)); +} + +/**************************************************** + */ +void genCppFiles(OutBuffer* buf, Modules *ms) +{ + import dmd.tokens; + + extern(C++) final class ToCppBuffer(AST) : Visitor + { + alias visit = super.visit; + public: + bool[void*] visited; + bool[void*] forwarded; + OutBuffer *fwdbuf; + OutBuffer *checkbuf; + OutBuffer *donebuf; + OutBuffer *buf; + AST.AggregateDeclaration adparent; + AST.ClassDeclaration cdparent; + AST.TemplateDeclaration tdparent; + Identifier ident; + LINK linkage = LINK.d; + + this(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf) + { + this.checkbuf = checkbuf; + this.fwdbuf = fwdbuf; + this.donebuf = donebuf; + this.buf = buf; + } + + private void indent() + { + if (adparent) + buf.writestring(" "); + } + + override void visit(AST.Dsymbol s) + { + if (s.getModule() && s.getModule().isFrontendModule()) + { + indent(); + buf.printf("// ignored %s %s\n", s.kind(), s.toPrettyChars()); + } + } + + override void visit(AST.Import) + { + } + + override void visit(AST.AttribDeclaration pd) + { + Dsymbols* decl = pd.include(null); + if (decl) + { + foreach (s; *decl) + { + if (!adparent && s.prot().kind < AST.Prot.Kind.public_) + continue; + s.accept(this); + } + } + } + + override void visit(AST.LinkDeclaration ld) + { + auto save = linkage; + linkage = ld.linkage; + if (ld.linkage != LINK.c && ld.linkage != LINK.cpp) + { + indent(); + buf.printf("// ignoring %s block because of linkage\n", ld.toPrettyChars()); + } + else + visit(cast(AST.AttribDeclaration)ld); + linkage = save; + } + + override void visit(AST.Module m) + { + foreach (s; *m.members) + { + if (s.prot().kind < AST.Prot.Kind.public_) + continue; + s.accept(this); + } + } + + override void visit(AST.FuncDeclaration fd) + { + if (cast(void*)fd in visited) + return; + if (fd.getModule() && !fd.getModule().isFrontendModule()) + return; + // printf("FuncDeclaration %s %s\n", fd.toPrettyChars(), fd.type.toChars()); + visited[cast(void*)fd] = true; + + auto tf = cast(AST.TypeFunction)fd.type; + indent(); + if (!tf || !tf.deco) + { + buf.printf("// ignoring function %s because semantic hasn't been run\n", fd.toPrettyChars()); + return; + } + if (tf.linkage != LINK.c && tf.linkage != LINK.cpp) + { + buf.printf("// ignoring function %s because of linkage\n", fd.toPrettyChars()); + return; + } + if (!adparent && !fd.fbody) + { + buf.printf("// ignoring function %s because it's extern\n", fd.toPrettyChars()); + return; + } + + if (tf.linkage == LINK.c) + buf.writestring("extern \"C\" "); + else if (!adparent) + buf.writestring("extern "); + if (adparent && fd.isStatic()) + buf.writestring("static "); + if (adparent && fd.vtblIndex != -1) + { + if (!fd.isOverride()) + buf.writestring("virtual "); + + auto s = adparent.search(Loc.initial, fd.ident); + if (!(adparent.storage_class & AST.STC.abstract_) && + !(cast(AST.ClassDeclaration)adparent).isAbstract() && + s is fd && !fd.overnext) + { + auto save = buf; + buf = checkbuf; + buf.writestring(" assert(getSlotNumber<"); + buf.writestring(adparent.ident.toChars()); + buf.writestring(">(0, &"); + buf.writestring(adparent.ident.toChars()); + buf.writestring("::"); + buf.writestring(fd.ident.toChars()); + buf.printf(") == %d);\n", fd.vtblIndex); + buf = save; + } + } + funcToBuffer(tf, fd.ident); + if (adparent && tf.isConst()) + buf.writestring(" const"); + if (adparent && fd.isAbstract()) + buf.writestring(" = 0"); + buf.printf(";\n"); + if (!adparent) + buf.printf("\n"); + } + + override void visit(AST.UnitTestDeclaration fd) + { + } + + override void visit(AST.VarDeclaration vd) + { + if (cast(void*)vd in visited) + return; + if (vd.getModule() && !vd.getModule().isFrontendModule()) + return; + visited[cast(void*)vd] = true; + + if (vd.storage_class & AST.STC.manifest && + vd.type.isintegral() && + vd._init && vd._init.isExpInitializer()) + { + indent(); + buf.writestring("#define "); + buf.writestring(vd.ident.toChars()); + buf.writestring(" "); + auto e = AST.initializerToExpression(vd._init); + if (e.type.ty == AST.Tbool) + buf.printf("%d", e.toInteger()); + else + AST.initializerToExpression(vd._init).accept(this); + buf.writestring("\n"); + if (!adparent) + buf.printf("\n"); + return; + } + + if (tdparent && vd.type && !vd.type.deco) + { + indent(); + if (linkage != LINK.c && linkage != LINK.cpp) + { + buf.printf("// ignoring variable %s because of linkage\n", vd.toPrettyChars()); + return; + } + typeToBuffer(vd.type, vd.ident); + buf.writestring(";\n"); + return; + } + + if (vd.storage_class & (AST.STC.static_ | AST.STC.extern_ | AST.STC.tls | AST.STC.gshared) || + vd.parent && vd.parent.isModule()) + { + indent(); + if (vd.linkage != LINK.c && vd.linkage != LINK.cpp) + { + buf.printf("// ignoring variable %s because of linkage\n", vd.toPrettyChars()); + return; + } + if (vd.storage_class & AST.STC.tls) + { + buf.printf("// ignoring variable %s because of thread-local storage\n", vd.toPrettyChars()); + return; + } + if (vd.linkage == LINK.c) + buf.writestring("extern \"C\" "); + else if (!adparent) + buf.writestring("extern "); + if (adparent) + buf.writestring("static "); + typeToBuffer(vd.type, vd.ident); + buf.writestring(";\n"); + if (!adparent) + buf.printf("\n"); + return; + } + + if (adparent && vd.type && vd.type.deco) + { + indent(); + auto save = cdparent; + cdparent = vd.isField() ? adparent.isClassDeclaration() : null; + typeToBuffer(vd.type, vd.ident); + cdparent = save; + buf.writestring(";\n"); + if (vd.type.ty == AST.Tstruct) + { + auto t = cast(AST.TypeStruct)vd.type; + includeSymbol(t.sym); + } + auto savex = buf; + buf = checkbuf; + buf.writestring(" assert(offsetof("); + buf.writestring(adparent.ident.toChars()); + buf.writestring(", "); + buf.writestring(vd.ident.toChars()); + buf.printf(") == %d);\n", vd.offset); + buf = savex; + return; + } + + visit(cast(AST.Dsymbol)vd); + } + + override void visit(AST.TypeInfoDeclaration) + { + } + + override void visit(AST.AliasDeclaration ad) + { + if (ad.getModule() && !ad.getModule().isFrontendModule()) + return; + if (auto t = ad.type) + { + if (t.ty == AST.Tdelegate) + { + visit(cast(AST.Dsymbol)ad); + return; + } + buf.writestring("typedef "); + typeToBuffer(t, ad.ident); + buf.writestring(";\n"); + if (!adparent) + buf.printf("\n"); + return; + } + if (!ad.aliassym) + { + ad.print(); + assert(0); + } + if (auto ti = ad.aliassym.isTemplateInstance()) + { + visitTi(ti); + return; + } + if (auto sd = ad.aliassym.isStructDeclaration()) + { + buf.writestring("typedef "); + sd.type.accept(this); + buf.writestring(" "); + buf.writestring(ad.ident.toChars()); + buf.writestring(";\n"); + if (!adparent) + buf.printf("\n"); + return; + } + indent(); + buf.printf("// ignored %s %s\n", ad.aliassym.kind(), ad.aliassym.toPrettyChars()); + } + + override void visit(AST.AnonDeclaration ad) + { + buf.writestring(ad.isunion ? "union" : "struct"); + buf.writestring("\n{\n"); + foreach (s; *ad.decl) + { + s.accept(this); + } + buf.writestring("};\n"); + } + + private bool memberField(AST.VarDeclaration vd) + { + if (!vd.type || !vd.type.deco || !vd.ident) + return false; + if (!vd.isField()) + return false; + if (vd.type.ty == AST.Tfunction) + return false; + if (vd.type.ty == AST.Tsarray) + return false; + return true; + } + + override void visit(AST.StructDeclaration sd) + { + if (sd.isInstantiated()) + return; + if (cast(void*)sd in visited) + return; + if (!sd.type || !sd.type.deco) + return; + if (sd.getModule() && !sd.getModule().isFrontendModule()) + return; + visited[cast(void*)sd] = true; + + if (sd.alignment == 1) + buf.writestring("#pragma pack(push, 1)\n"); + buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); + buf.writestring(sd.ident.toChars()); + if (sd.members) + { + buf.writestring("\n{\n"); + auto save = adparent; + adparent = sd; + foreach (m; *sd.members) + { + m.accept(this); + } + adparent = save; + // Generate default ctor + buf.printf(" %s(", sd.ident.toChars()); + buf.printf(") {"); + size_t varCount; + foreach (m; *sd.members) + { + if (auto vd = m.isVarDeclaration()) + { + if (!memberField(vd)) + continue; + varCount++; + if (!vd._init && !vd.type.isTypeBasic()) + continue; + buf.printf(" this->%s = ", vd.ident.toChars()); + if (vd._init) + AST.initializerToExpression(vd._init).accept(this); + else if (vd.type.isTypeBasic()) + vd.type.defaultInitLiteral(Loc.initial).accept(this); + buf.printf(";"); + } + } + buf.printf(" }\n"); + + if (varCount) + { + buf.printf(" %s(", sd.ident.toChars()); + bool first = true; + foreach (m; *sd.members) + { + if (auto vd = m.isVarDeclaration()) + { + if (!memberField(vd)) + continue; + if (first) + first = false; + else + buf.writestring(", "); + assert(vd.type); + assert(vd.ident); + typeToBuffer(vd.type, vd.ident); + } + } + buf.printf(") {"); + foreach (m; *sd.members) + { + if (auto vd = m.isVarDeclaration()) + { + if (!memberField(vd)) + continue; + buf.printf(" this->%s = %s;", vd.ident.toChars(), vd.ident.toChars()); + } + } + buf.printf(" }\n"); + } + + buf.writestring("};\n\n"); + + if (sd.alignment == 1) + buf.writestring("#pragma pack(pop)\n"); + + auto savex = buf; + buf = checkbuf; + buf.writestring(" assert(sizeof("); + buf.writestring(sd.ident.toChars()); + buf.printf(") == %d);\n", sd.size(Loc.initial)); + buf = savex; + } + else + buf.writestring(";\n\n"); + } + + private void includeSymbol(AST.Dsymbol ds) + { + // printf("Forward declaring %s %d\n", ds.toChars(), level); + if (cast(void*)ds !in visited) + { + OutBuffer decl; + auto save = buf; + buf = &decl; + ds.accept(this); + buf = save; + donebuf.writestring(decl.peekString()); + } + } + + override void visit(AST.ClassDeclaration cd) + { + if (cast(void*)cd in visited) + return; + if (cd.getModule() && !cd.getModule().isFrontendModule()) + return; + if (cd.isVisitorClass()) + return; + visited[cast(void*)cd] = true; + if (!cd.isCPPclass()) + { + buf.printf("// ignoring non-cpp class %s\n", cd.toChars()); + return; + } + + buf.writestring("class "); + buf.writestring(cd.ident.toChars()); + if (cd.baseClass) + { + buf.writestring(" : public "); + buf.writestring(cd.baseClass.ident.toChars()); + + includeSymbol(cd.baseClass); + } + if (cd.members) + { + buf.writestring("\n{\npublic:\n"); + auto save = adparent; + adparent = cd; + foreach (m; *cd.members) + { + m.accept(this); + } + adparent = save; + // Generate special static inline function. + if (cd.isIdentifierClass()) + { + buf.writestring(" static inline Identifier *idPool(const char *s) { return idPool(s, strlen(s)); }\n"); + } + buf.writestring("};\n\n"); + } + else + buf.writestring(";\n\n"); + } + + override void visit(AST.EnumDeclaration ed) + { + if (cast(void*)ed in visited) + return; + if (ed.getModule() && !ed.getModule().isFrontendModule()) + return; + visited[cast(void*)ed] = true; + if (ed.isSpecial()) + return; + buf.writestring("enum"); + const(char)* ident = null; + if (ed.ident) + ident = ed.ident.toChars(); + if (ident) + { + buf.writeByte(' '); + buf.writestring(ident); + } + if (ed.members) + { + buf.writestring("\n{\n"); + foreach (i, m; *ed.members) + { + if (i) + buf.writestring(",\n"); + buf.writestring(" "); + if (ident) + { + foreach (c; ident[0 .. strlen(ident)]) + buf.writeByte(toupper(c)); + } + m.accept(this); + } + buf.writestring("\n};\n\n"); + } + else + buf.writestring(";\n\n"); + } + + override void visit(AST.EnumMember em) + { + buf.writestring(em.ident.toChars()); + buf.writestring(" = "); + assert(em.value.op == TOK.int64); + auto ie = cast(AST.IntegerExp)em.value; + visitInteger(ie.toInteger(), em.ed.memtype); + } + + private void typeToBuffer(AST.Type t, Identifier ident) + { + this.ident = ident; + t.accept(this); + if (this.ident) + { + buf.writeByte(' '); + buf.writestring(ident.toChars()); + } + this.ident = null; + if (t.ty == AST.Tsarray) + { + auto tsa = cast(AST.TypeSArray)t; + buf.writeByte('['); + tsa.dim.accept(this); + buf.writeByte(']'); + } + } + + override void visit(AST.Type t) + { + printf("Invalid type: %s\n", t.toPrettyChars()); + assert(0); + } + + override void visit(AST.TypeIdentifier t) + { + buf.writestring(t.ident.toChars()); + } + + override void visit(AST.TypeBasic t) + { + if (!cdparent && t.isConst()) + buf.writestring("const "); + switch (t.ty) + { + case AST.Tbool, AST.Tvoid: + case AST.Tchar, AST.Twchar, AST.Tdchar: + case AST.Tint8, AST.Tuns8: + case AST.Tint16, AST.Tuns16: + case AST.Tint32, AST.Tuns32: + case AST.Tint64, AST.Tuns64: + case AST.Tfloat32, AST.Tfloat64, AST.Tfloat80: + buf.writestring("_d_"); + buf.writestring(t.dstring); + break; + default: + t.print(); + assert(0); + } + } + + override void visit(AST.TypePointer t) + { + if (t.next.ty == AST.Tstruct && + !strcmp((cast(AST.TypeStruct)t.next).sym.ident.toChars(), "__va_list_tag")) + { + buf.writestring("va_list"); + return; + } + t.next.accept(this); + if (t.next.ty != AST.Tfunction) + buf.writeByte('*'); + if (!cdparent && t.isConst()) + buf.writestring(" const"); + } + + override void visit(AST.TypeSArray t) + { + t.next.accept(this); + } + + override void visit(AST.TypeAArray t) + { + AST.Type.tvoidptr.accept(this); + } + + override void visit(AST.TypeFunction tf) + { + tf.next.accept(this); + buf.writeByte('('); + buf.writeByte('*'); + if (ident) + buf.writestring(ident.toChars()); + ident = null; + buf.writeByte(')'); + buf.writeByte('('); + foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) + { + if (i) + buf.writestring(", "); + auto fparam = AST.Parameter.getNth(tf.parameters, i); + fparam.accept(this); + } + if (tf.varargs) + { + if (tf.parameters.dim && tf.varargs == 1) + buf.writestring(", "); + buf.writestring("..."); + } + buf.writeByte(')'); + } + + private void enumToBuffer(AST.EnumDeclaration ed) + { + if (ed.isSpecial()) + { + if (ed.ident == Identifier.idPool("__c_long")) + buf.writestring("long"); + else if (ed.ident == Identifier.idPool("__c_ulong")) + buf.writestring("unsigned long"); + else if (ed.ident == Identifier.idPool("__c_longlong")) + buf.writestring("long long"); + else if (ed.ident == Identifier.idPool("__c_ulonglong")) + buf.writestring("unsigned long long"); + else if (ed.ident == Identifier.idPool("__c_long_double")) + buf.writestring("long double"); + else + { + ed.print(); + assert(0); + } + } + else + buf.writestring(ed.toChars()); + } + + override void visit(AST.TypeEnum t) + { + if (cast(void*)t.sym !in forwarded) + { + forwarded[cast(void*)t.sym] = true; + auto save = buf; + buf = fwdbuf; + t.sym.accept(this); + buf = save; + } + if (!cdparent && t.isConst()) + buf.writestring("const "); + enumToBuffer(t.sym); + } + + override void visit(AST.TypeStruct t) + { + if (cast(void*)t.sym !in forwarded && + !t.sym.parent.isTemplateInstance()) + { + forwarded[cast(void*)t.sym] = true; + fwdbuf.writestring(t.sym.isUnionDeclaration() ? "union " : "struct "); + fwdbuf.writestring(t.sym.toChars()); + fwdbuf.writestring(";\n"); + } + + if (!cdparent && t.isConst()) + buf.writestring("const "); + if (auto ti = t.sym.parent.isTemplateInstance()) + { + visitTi(ti); + return; + } + buf.writestring(t.sym.toChars()); + } + + override void visit(AST.TypeDArray t) + { + if (!cdparent && t.isConst()) + buf.writestring("const "); + buf.writestring("DArray<"); + t.next.accept(this); + buf.writestring(">"); + } + + private void visitTi(AST.TemplateInstance ti) + { + if (ti.tempdecl.ident == Identifier.idPool("AssocArray")) + { + buf.writestring("AA*"); + return; + } + if (ti.tempdecl.ident == Identifier.idPool("Array")) + buf.writestring("Array"); + else + { + foreach (o; *ti.tiargs) + { + if (!AST.isType(o)) + return; + } + buf.writestring(ti.tempdecl.ident.toChars()); + } + buf.writeByte('<'); + foreach (i, o; *ti.tiargs) + { + if (i) + buf.writestring(", "); + if (auto tt = AST.isType(o)) + { + tt.accept(this); + } + else + { + ti.print(); + o.print(); + assert(0); + } + } + buf.writeByte('>'); + } + + override void visit(AST.TemplateDeclaration td) + { + if (cast(void*)td in visited) + return; + visited[cast(void*)td] = true; + + if (td.getModule() && !td.getModule().isFrontendModule()) + return; + if (!td.parameters || !td.onemember || !td.onemember.isStructDeclaration()) + { + visit(cast(AST.Dsymbol)td); + return; + } + + // Explcitly disallow templates with non-type parameters or specialization. + foreach (p; *td.parameters) + { + if (!p.isTemplateTypeParameter() || p.specialization()) + { + visit(cast(AST.Dsymbol)td); + return; + } + } + + if (linkage != LINK.c && linkage != LINK.cpp) + { + buf.printf("// ignoring template %s because of linkage\n", td.toPrettyChars()); + return; + } + + auto sd = td.onemember.isStructDeclaration(); + auto save = tdparent; + tdparent = td; + indent(); + buf.writestring("template <"); + bool first = true; + foreach (p; *td.parameters) + { + if (first) + first = false; + else + buf.writestring(", "); + buf.writestring("typename "); + buf.writestring(p.ident.toChars()); + } + buf.writestring(">\n"); + buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); + buf.writestring(sd.ident.toChars()); + if (sd.members) + { + buf.writestring("\n{\n"); + auto savex = adparent; + adparent = sd; + foreach (m; *sd.members) + { + m.accept(this); + } + adparent = savex; + buf.writestring("};\n\n"); + } + else + buf.writestring(";\n\n"); + tdparent = save; + } + + override void visit(AST.TypeClass t) + { + if (cast(void*)t.sym !in forwarded) + { + forwarded[cast(void*)t.sym] = true; + fwdbuf.writestring("class "); + fwdbuf.writestring(t.sym.toChars()); + fwdbuf.writestring(";\n"); + } + + if (!cdparent && t.isConst()) + buf.writestring("const "); + buf.writestring(t.sym.toChars()); + buf.writeByte('*'); + if (!cdparent && t.isConst()) + buf.writestring(" const"); + } + + private void funcToBuffer(AST.TypeFunction tf, Identifier ident) + { + assert(tf.next); + tf.next.accept(this); + if (tf.isref) + buf.writeByte('&'); + buf.writeByte(' '); + buf.writestring(ident.toChars()); + + buf.writeByte('('); + foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) + { + if (i) + buf.writestring(", "); + auto fparam = AST.Parameter.getNth(tf.parameters, i); + fparam.accept(this); + } + if (tf.varargs) + { + if (tf.parameters.dim && tf.varargs == 1) + buf.writestring(", "); + buf.writestring("..."); + } + buf.writeByte(')'); + } + + override void visit(AST.Parameter p) + { + ident = p.ident; + p.type.accept(this); + assert(!(p.storageClass & ~(AST.STC.ref_))); + if (p.storageClass & AST.STC.ref_) + buf.writeByte('&'); + buf.writeByte(' '); + if (ident) + buf.writestring(ident.toChars()); + ident = null; + if (p.defaultArg) + { + // buf.writestring("/*"); + buf.writestring(" = "); + p.defaultArg.accept(this); + // buf.writestring("*/"); + } + } + + override void visit(AST.Expression e) + { + e.print(); + assert(0); + } + + override void visit(AST.NullExp e) + { + buf.writestring("_d_null"); + } + + override void visit(AST.ArrayLiteralExp e) + { + buf.writestring("arrayliteral"); + } + + override void visit(AST.StringExp e) + { + assert(e.sz == 1 || e.sz == 2); + if (e.sz == 2) + buf.writeByte('L'); + buf.writeByte('"'); + size_t o = buf.offset; + for (size_t i = 0; i < e.len; i++) + { + uint c = e.charAt(i); + switch (c) + { + case '"': + case '\\': + buf.writeByte('\\'); + goto default; + default: + if (c <= 0xFF) + { + if (c <= 0x7F && isprint(c)) + buf.writeByte(c); + else + buf.printf("\\x%02x", c); + } + else if (c <= 0xFFFF) + buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8); + else + buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24); + break; + } + } + buf.writeByte('"'); + } + + override void visit(AST.RealExp e) + { + buf.writestring("0"); + } + + override void visit(AST.IntegerExp e) + { + visitInteger(e.toInteger, e.type); + } + + private void visitInteger(dinteger_t v, AST.Type t) + { + switch (t.ty) + { + case AST.Tenum: + auto te = cast(AST.TypeEnum)t; + buf.writestring("("); + enumToBuffer(te.sym); + buf.writestring(")"); + visitInteger(v, te.sym.memtype); + break; + case AST.Tbool: + buf.writestring(v ? "true" : "false"); + break; + case AST.Tint8: + buf.printf("%d", cast(byte)v); + break; + case AST.Tuns8: + case AST.Tchar: + buf.printf("%uu", cast(ubyte)v); + break; + case AST.Tint16: + buf.printf("%d", cast(short)v); + break; + case AST.Tuns16: + buf.printf("%uu", cast(ushort)v); + break; + case AST.Tint32: + buf.printf("%d", cast(int)v); + break; + case AST.Tuns32: + buf.printf("%uu", cast(uint)v); + break; + case AST.Tint64: + buf.printf("%lldLL", v); + break; + case AST.Tuns64: + buf.printf("%lluLLU", v); + break; + default: + t.print(); + assert(0); + } + } + + override void visit(AST.StructLiteralExp sle) + { + buf.writestring(sle.sd.ident.toChars()); + buf.writeByte('('); + foreach(i, e; *sle.elements) + { + if (i) + buf.writestring(", "); + e.accept(this); + } + buf.writeByte(')'); + } + } + + buf.writeByte('\n'); + buf.printf("// Automatically generated by dtoh\n"); + buf.writeByte('\n'); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writeByte('\n'); + buf.writestring("#define _d_void void\n"); + buf.writestring("#define _d_bool bool\n"); + buf.writestring("#define _d_byte signed char\n"); + buf.writestring("#define _d_ubyte unsigned char\n"); + buf.writestring("#define _d_short short\n"); + buf.writestring("#define _d_ushort unsigned short\n"); + buf.writestring("#define _d_int int\n"); + buf.writestring("#define _d_uint unsigned\n"); + if (global.params.isLP64) + { + buf.writestring("#define _d_long long\n"); + buf.writestring("#define _d_ulong unsigned long\n"); + } + else + { + buf.writestring("#define _d_long long long\n"); + buf.writestring("#define _d_ulong unsigned long long\n"); + } + buf.writestring("#define _d_float float\n"); + buf.writestring("#define _d_double double\n"); + buf.writestring("#define _d_real long double\n"); + buf.writestring("#define _d_char char\n"); + buf.writestring("#define _d_wchar wchar_t\n"); + buf.writestring("#define _d_dchar unsigned\n"); + buf.writestring("\n"); + buf.writestring("#define _d_null NULL\n"); + buf.writestring("\n"); + buf.writestring("struct AA;\n"); + buf.writestring("\n"); + + OutBuffer check; + check.writestring(` +#if OFFSETS + +template +size_t getSlotNumber(int dummy, ...) +{ + T c; + va_list ap; + va_start(ap, dummy); + void *f = va_arg(ap, void*); + for (size_t i = 0; ; i++) + { + if ( (*(void***)&c)[i] == f) + return i; + } + va_end(ap); +} + +void testOffsets() +{ + `); + + OutBuffer done; + OutBuffer decl; + scope v = new ToCppBuffer!ASTCodegen(&check, buf, &done, &decl); + foreach (m; *ms) + { + buf.printf("// Parsing module %s\n", m.toPrettyChars()); + m.accept(v); + } + buf.write(&done); + buf.write(&decl); + + check.writestring(` +} +#endif + `); + + debug buf.write(&check); +} + +void main() +{ + import std.stdio; + import std.algorithm.sorting : sort; + import std.array : array; + import std.file : readText; + import std.path : baseName, buildPath, dirName; + import std.string : toStringz; + + import dmd.id; + import dmd.parse; + import dmd.dsymbolsem; + import dmd.semantic2; + import dmd.semantic3; + import dmd.builtin : builtin_init; + import dmd.dmodule : Module; + import dmd.cond : VersionCondition; + import dmd.expression : Expression; + import dmd.objc : Objc; + import dmd.target : Target; + + import core.memory; + + GC.disable(); + + global._init(); + global.params.isLinux = true; + global.params.is64bit = (size_t.sizeof == 8); + global.params.isLP64 = global.params.is64bit; + + global.path = new Strings(); + global.path.push(__FILE_FULL_PATH__.dirName.buildPath("../../../druntime/src/").toStringz()); + + global.filePath = new Strings(); + global.params.fileImppath = global.filePath; + global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../").toStringz()); + global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../res/").toStringz()); + + ASTCodegen.Type._init(); + Id.initialize(); + Module._init(); + Target._init(); + Expression._init(); + Objc._init(); + builtin_init(); + + VersionCondition.addPredefinedGlobalIdent("all"); + VersionCondition.addPredefinedGlobalIdent("DigitalMars"); + VersionCondition.addPredefinedGlobalIdent("Posix"); + VersionCondition.addPredefinedGlobalIdent("linux"); + VersionCondition.addPredefinedGlobalIdent("CRuntime_Glibc"); + VersionCondition.addPredefinedGlobalIdent("NoBackend"); + VersionCondition.addPredefinedGlobalIdent("NoMain"); + if (global.params.is64bit) + VersionCondition.addPredefinedGlobalIdent("X86_64"); + else + VersionCondition.addPredefinedGlobalIdent("X86"); + if (global.params.isLP64) + VersionCondition.addPredefinedGlobalIdent("D_LP64"); + + Modules modules; + + string path = __FILE_FULL_PATH__.dirName.buildPath("../dmd/"); + + foreach (f; frontendSources) + { + string fn = buildPath(path, f); + + auto id = Identifier.idPool(baseName(fn, ".d")); + auto m = new Module(fn.toStringz(), id, false, false); + auto input = readText(fn); + + if (!Module.rootModule) + Module.rootModule = m; + + m.importedFrom = m; + m.srcfile.setbuffer(cast(void*)input.ptr, input.length); + m.srcfile._ref = 1; + m.parse(); + modules.push(m); + } + + foreach (m; modules) + m.importAll(null); + foreach (m; modules) + m.dsymbolSemantic(null); + Module.dprogress = 1; + Module.runDeferredSemantic(); + foreach (m; modules) + m.semantic2(null); + Module.runDeferredSemantic2(); + foreach (m; modules) + m.semantic3(null); + Module.runDeferredSemantic3(); + + OutBuffer buf; + genCppFiles(&buf, &modules); + + writeln(buf.peekSlice()); +} From 2910025777de3752204a88cb87cd2df931f41d20 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Wed, 22 Aug 2018 01:19:33 +0200 Subject: [PATCH 02/44] Use generated frontend.h in C++ test --- src/posix.mak | 18 ++++++++++++++++++ src/tests/cxxfrontend.c | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/posix.mak b/src/posix.mak index c60b6d70460f..07c743f6afcb 100644 --- a/src/posix.mak +++ b/src/posix.mak @@ -370,6 +370,8 @@ build-examples: $(EXAMPLES) clean: rm -Rf $(GENERATED) + rm -f $(addprefix $D/backend/, $(optabgen_output)) + rm -f $D/frontend.h @[ ! -d ${PGO_DIR} ] || echo You should issue manually: rm -rf ${PGO_DIR} ######## Download and install the last dmd buildable without dmd @@ -433,6 +435,22 @@ style: $(GENERATED)/build cxx-unittest: $(GENERATED)/build $(RUN_BUILD) $@ +#======= +#$G/dtoh: $D/dtoh.d $(FRONT_SRCS) $D/gluelayer.d $(ROOT_SRCS) $G/newdelete.o $G/lexer.a $(STRING_IMPORT_FILES) $(HOST_DMD_PATH) + #CC="$(HOST_CXX)" $(HOST_DMD_RUN) -of$@ $(MODEL_FLAG) -vtls -J$G -J../res -L-lstdc++ $(DFLAGS) -version=NoBackend -version=NoMain $(filter-out $(STRING_IMPORT_FILES) $(HOST_DMD_PATH),$^) + +#$D/frontend.h: $G/dtoh + #$G/dtoh > $D/frontend.h + +#$G/cxxfrontend.o: $G/%.o: tests/%.c $D/frontend.h $(SRC) $(ROOT_SRC) + #$(CXX) -c -o$@ $(CXXFLAGS) $(DMD_FLAGS) $(MMD) $< + +#$G/cxx-unittest: $G/cxxfrontend.o $(DMD_SRCS) $(ROOT_SRCS) $G/lexer.a $G/backend.o $(STRING_IMPORT_FILES) $(HOST_DMD_PATH) + #CC=$(HOST_CXX) $(HOST_DMD_RUN) -of$@ $(MODEL_FLAG) -vtls -J$G -J$(RES) -L-lstdc++ $(DFLAGS) -version=NoMain $(filter-out $(STRING_IMPORT_FILES) $(HOST_DMD_PATH),$^) + +#cxx-unittest: $G/cxx-unittest + #$< +#>>>>>>> Use generated frontend.h in C++ test ###################################################### diff --git a/src/tests/cxxfrontend.c b/src/tests/cxxfrontend.c index f931b409f8e4..8b5d6792881c 100644 --- a/src/tests/cxxfrontend.c +++ b/src/tests/cxxfrontend.c @@ -54,7 +54,23 @@ #include "template.h" #include "tokens.h" #include "version.h" + +#include "array.h" +#include "ctfloat.h" +#include "file.h" +#include "filename.h" +#include "longdouble.h" +#include "object.h" +// FIXME: UINT64_MAX +//#include "outbuffer.h" +//#include "port.h" +#include "rmem.h" +//#include "root.h" +//#include "stringtable.h" +#include "thread.h" + #include "visitor.h" +#include "frontend.h" /**********************************/ From 24c841b6783fd64cddbf7a49f2cfef5a18aa943b Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Wed, 22 Aug 2018 01:36:45 +0200 Subject: [PATCH 03/44] Remove unused and redundant dmd headers --- src/dmd/aggregate.h | 332 ---------- src/dmd/aliasthis.h | 31 - src/dmd/attrib.h | 252 -------- src/dmd/cond.h | 99 --- src/dmd/ctfe.h | 64 -- src/dmd/declaration.h | 808 ----------------------- src/dmd/dsymbol.h | 397 ------------ src/dmd/enum.h | 88 --- src/dmd/expression.h | 1373 ---------------------------------------- src/dmd/hdrgen.h | 18 - src/dmd/id.h | 16 - src/dmd/identifier.h | 39 -- src/dmd/import.h | 54 -- src/dmd/init.h | 93 --- src/dmd/json.h | 19 - src/dmd/module.h | 166 ----- src/dmd/mtype.h | 859 ------------------------- src/dmd/nspace.h | 34 - src/dmd/objc.h | 75 --- src/dmd/scope.h | 139 ---- src/dmd/statement.h | 773 ---------------------- src/dmd/staticassert.h | 28 - src/dmd/target.h | 108 ---- src/dmd/template.h | 313 --------- src/dmd/tokens.h | 235 ------- src/dmd/version.h | 39 -- 26 files changed, 6452 deletions(-) delete mode 100644 src/dmd/aggregate.h delete mode 100644 src/dmd/aliasthis.h delete mode 100644 src/dmd/attrib.h delete mode 100644 src/dmd/cond.h delete mode 100644 src/dmd/ctfe.h delete mode 100644 src/dmd/declaration.h delete mode 100644 src/dmd/dsymbol.h delete mode 100644 src/dmd/enum.h delete mode 100644 src/dmd/expression.h delete mode 100644 src/dmd/hdrgen.h delete mode 100644 src/dmd/id.h delete mode 100644 src/dmd/identifier.h delete mode 100644 src/dmd/import.h delete mode 100644 src/dmd/init.h delete mode 100644 src/dmd/json.h delete mode 100644 src/dmd/module.h delete mode 100644 src/dmd/mtype.h delete mode 100644 src/dmd/nspace.h delete mode 100644 src/dmd/objc.h delete mode 100644 src/dmd/scope.h delete mode 100644 src/dmd/statement.h delete mode 100644 src/dmd/staticassert.h delete mode 100644 src/dmd/target.h delete mode 100644 src/dmd/template.h delete mode 100644 src/dmd/tokens.h delete mode 100644 src/dmd/version.h diff --git a/src/dmd/aggregate.h b/src/dmd/aggregate.h deleted file mode 100644 index 42adaa5bf3d0..000000000000 --- a/src/dmd/aggregate.h +++ /dev/null @@ -1,332 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.h - */ - -#pragma once - -#include "dsymbol.h" -#include "objc.h" - -class AliasThis; -class Identifier; -class Type; -class TypeFunction; -class Expression; -class FuncDeclaration; -class CtorDeclaration; -class DtorDeclaration; -class NewDeclaration; -class DeleteDeclaration; -class InterfaceDeclaration; -class TypeInfoClassDeclaration; -class VarDeclaration; - -enum Sizeok -{ - SIZEOKnone, // size of aggregate is not yet able to compute - SIZEOKfwd, // size of aggregate is ready to compute - SIZEOKinProcess, // in the midst of computing the size - SIZEOKdone // size of aggregate is set correctly -}; - -enum Baseok -{ - BASEOKnone, // base classes not computed yet - BASEOKin, // in process of resolving base classes - BASEOKdone, // all base classes are resolved - BASEOKsemanticdone // all base classes semantic done -}; - -enum StructPOD -{ - ISPODno, // struct is not POD - ISPODyes, // struct is POD - ISPODfwd // POD not yet computed -}; - -enum Abstract -{ - ABSfwdref = 0, // whether an abstract class is not yet computed - ABSyes, // is abstract class - ABSno // is not abstract class -}; - -FuncDeclaration *search_toString(StructDeclaration *sd); - -struct ClassKind -{ - enum Type - { - /// the aggregate is a d(efault) struct/class/interface - d, - /// the aggregate is a C++ struct/class/interface - cpp, - /// the aggregate is an Objective-C class/interface - objc - }; -}; - -class AggregateDeclaration : public ScopeDsymbol -{ -public: - Type *type; - StorageClass storage_class; - Prot protection; - unsigned structsize; // size of struct - unsigned alignsize; // size of struct for alignment purposes - VarDeclarations fields; // VarDeclaration fields - Sizeok sizeok; // set when structsize contains valid data - Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol - bool isdeprecated; // true if deprecated - - ClassKind::Type classKind; // specifies the linkage type - - /* !=NULL if is nested - * pointing to the dsymbol that directly enclosing it. - * 1. The function that enclosing it (nested struct and class) - * 2. The class that enclosing it (nested class only) - * 3. If enclosing aggregate is template, its enclosing dsymbol. - * See AggregateDeclaraton::makeNested for the details. - */ - Dsymbol *enclosing; - VarDeclaration *vthis; // 'this' parameter if this aggregate is nested - VarDeclaration *vthis2; // 'this' parameter if this aggregate is a template and is nested - // Special member functions - FuncDeclarations invs; // Array of invariants - FuncDeclaration *inv; // invariant - NewDeclaration *aggNew; // allocator - DeleteDeclaration *aggDelete; // deallocator - - Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration - - // default constructor - should have no arguments, because - // it would be stored in TypeInfo_Class.defaultConstructor - CtorDeclaration *defaultCtor; - - AliasThis *aliasthis; // forward unresolved lookups to aliasthis - bool noDefaultCtor; // no default construction - - DtorDeclarations dtors; // Array of destructors - DtorDeclaration *dtor; // aggregate destructor - DtorDeclaration *primaryDtor; // non-deleting C++ destructor, same as dtor for D - DtorDeclaration *tidtor; // aggregate destructor used in TypeInfo (must have extern(D) ABI) - FuncDeclaration *fieldDtor; // aggregate destructor for just the fields - - Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this) - - virtual Scope *newScope(Scope *sc); - void setScope(Scope *sc); - bool determineFields(); - size_t nonHiddenFields(); - bool determineSize(Loc loc); - virtual void finalizeSize() = 0; - d_uns64 size(const Loc &loc); - bool fill(Loc loc, Expressions *elements, bool ctorinit); - Type *getType(); - bool isDeprecated() const; // is aggregate deprecated? - bool isNested() const; - bool isExport() const; - Dsymbol *searchCtor(); - - Prot prot(); - - // 'this' type - Type *handleType() { return type; } - - // Back end - Symbol *stag; // tag symbol for debug data - Symbol *sinit; - - AggregateDeclaration *isAggregateDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -struct StructFlags -{ - enum Type - { - none = 0x0, - hasPointers = 0x1 // NB: should use noPointers as in ClassFlags - }; -}; - -class StructDeclaration : public AggregateDeclaration -{ -public: - bool zeroInit; // !=0 if initialize with 0 fill - bool hasIdentityAssign; // true if has identity opAssign - bool hasIdentityEquals; // true if has identity opEquals - bool hasNoFields; // has no fields - FuncDeclarations postblits; // Array of postblit functions - FuncDeclaration *postblit; // aggregate postblit - - bool hasCopyCtor; // copy constructor - - FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals - FuncDeclaration *xcmp; // TypeInfo_Struct.xopCmp - FuncDeclaration *xhash; // TypeInfo_Struct.xtoHash - static FuncDeclaration *xerreq; // object.xopEquals - static FuncDeclaration *xerrcmp; // object.xopCmp - - structalign_t alignment; // alignment applied outside of the struct - StructPOD ispod; // if struct is POD - - // For 64 bit Efl function call/return ABI - Type *arg1type; - Type *arg2type; - - // Even if struct is defined as non-root symbol, some built-in operations - // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo. - // For those, today TypeInfo_Struct is generated in COMDAT. - bool requestTypeInfo; - - static StructDeclaration *create(Loc loc, Identifier *id, bool inObject); - Dsymbol *syntaxCopy(Dsymbol *s); - void semanticTypeInfoMembers(); - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - const char *kind() const; - void finalizeSize(); - bool fit(const Loc &loc, Scope *sc, Expressions *elements, Type *stype); - bool isPOD(); - - StructDeclaration *isStructDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class UnionDeclaration : public StructDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *s); - const char *kind() const; - - UnionDeclaration *isUnionDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -struct BaseClass -{ - Type *type; // (before semantic processing) - - ClassDeclaration *sym; - unsigned offset; // 'this' pointer offset - // for interfaces: Array of FuncDeclaration's - // making up the vtbl[] - FuncDeclarations vtbl; - - DArray baseInterfaces; // if BaseClass is an interface, these - // are a copy of the InterfaceDeclaration::interfaces - - bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance); -}; - -struct ClassFlags -{ - enum Type - { - none = 0x0, - isCOMclass = 0x1, - noPointers = 0x2, - hasOffTi = 0x4, - hasCtor = 0x8, - hasGetMembers = 0x10, - hasTypeInfo = 0x20, - isAbstract = 0x40, - isCPPclass = 0x80, - hasDtor = 0x100 - }; -}; - -class ClassDeclaration : public AggregateDeclaration -{ -public: - static ClassDeclaration *object; - static ClassDeclaration *throwable; - static ClassDeclaration *exception; - static ClassDeclaration *errorException; - static ClassDeclaration *cpp_type_info_ptr; - - ClassDeclaration *baseClass; // NULL only if this is Object - FuncDeclaration *staticCtor; - FuncDeclaration *staticDtor; - Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[] - Dsymbols vtblFinal; // More FuncDeclaration's that aren't in vtbl[] - - BaseClasses *baseclasses; // Array of BaseClass's; first is super, - // rest are Interface's - - DArray interfaces; // interfaces[interfaces_dim] for this class - // (does not include baseClass) - - BaseClasses *vtblInterfaces; // array of base interfaces that have - // their own vtbl[] - - TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration - bool com; // true if this is a COM class (meaning it derives from IUnknown) - bool stack; // true if this is a scope class - int cppDtorVtblIndex; // slot reserved for the virtual destructor [extern(C++)] - bool inuse; // to prevent recursive attempts - bool isActuallyAnonymous; // true if this class has an identifier, but was originally declared anonymous - // used in support of https://issues.dlang.org/show_bug.cgi?id=17371 - - Abstract isabstract; // 0: fwdref, 1: is abstract class, 2: not abstract - Baseok baseok; // set the progress of base classes resolving - ObjcClassDeclaration objc; // Data for a class declaration that is needed for the Objective-C integration - Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr - - static ClassDeclaration *create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject); - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - bool isBaseOf2(ClassDeclaration *cd); - - #define OFFSET_RUNTIME 0x76543210 - #define OFFSET_FWDREF 0x76543211 - virtual bool isBaseOf(ClassDeclaration *cd, int *poffset); - bool isAnonymous(); - - bool isBaseInfoComplete(); - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - ClassDeclaration *searchBase(Identifier *ident); - void finalizeSize(); - bool hasMonitor(); - bool isFuncHidden(FuncDeclaration *fd); - FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); - bool isCOMclass() const; - virtual bool isCOMinterface() const; - bool isCPPclass() const; - virtual bool isCPPinterface() const; - bool isAbstract(); - virtual int vtblOffset() const; - const char *kind() const; - - void addLocalClass(ClassDeclarations *); - void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories); - - // Back end - Dsymbol *vtblsym; - Dsymbol *vtblSymbol(); - - ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class InterfaceDeclaration : public ClassDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - bool isBaseOf(ClassDeclaration *cd, int *poffset); - bool isBaseOf(BaseClass *bc, int *poffset); - const char *kind() const; - int vtblOffset() const; - bool isCPPinterface() const; - bool isCOMinterface() const; - - InterfaceDeclaration *isInterfaceDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/aliasthis.h b/src/dmd/aliasthis.h deleted file mode 100644 index 0fa89c1b6993..000000000000 --- a/src/dmd/aliasthis.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 2009-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/aliasthis.h - */ - -#pragma once - -#include "globals.h" -#include "dsymbol.h" - -/**************************************************************/ - -class AliasThis : public Dsymbol -{ -public: - // alias Identifier this; - Identifier *ident; - Dsymbol *sym; - bool isDeprecated_; - - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind() const; - AliasThis *isAliasThis() { return this; } - void accept(Visitor *v) { v->visit(this); } - bool isDeprecated() const { return this->isDeprecated_; } -}; diff --git a/src/dmd/attrib.h b/src/dmd/attrib.h deleted file mode 100644 index 4b2dfa9e02d6..000000000000 --- a/src/dmd/attrib.h +++ /dev/null @@ -1,252 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/attrib.h - */ - -#pragma once - -#include "root/port.h" -#include "dsymbol.h" - -class Expression; -class Condition; -class StaticForeach; - -/**************************************************************/ - -class AttribDeclaration : public Dsymbol -{ -public: - Dsymbols *decl; // array of Dsymbol's - - virtual Dsymbols *include(Scope *sc); - int apply(Dsymbol_apply_ft_t fp, void *param); - virtual Scope *newScope(Scope *sc); - void addMember(Scope *sc, ScopeDsymbol *sds); - void setScope(Scope *sc); - void importAll(Scope *sc); - void addComment(const utf8_t *comment); - const char *kind() const; - bool oneMember(Dsymbol **ps, Identifier *ident); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - bool hasPointers(); - bool hasStaticCtorOrDtor(); - void checkCtorConstInit(); - void addLocalClass(ClassDeclarations *); - AttribDeclaration *isAttribDeclaration() { return this; } - - void accept(Visitor *v) { v->visit(this); } -}; - -class StorageClassDeclaration : public AttribDeclaration -{ -public: - StorageClass stc; - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - bool oneMember(Dsymbol **ps, Identifier *ident); - void addMember(Scope *sc, ScopeDsymbol *sds); - StorageClassDeclaration *isStorageClassDeclaration() { return this; } - - void accept(Visitor *v) { v->visit(this); } -}; - -class DeprecatedDeclaration : public StorageClassDeclaration -{ -public: - Expression *msg; - const char *msgstr; - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - void setScope(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class LinkDeclaration : public AttribDeclaration -{ -public: - LINK linkage; - - static LinkDeclaration *create(LINK p, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - const char *toChars() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class CPPMangleDeclaration : public AttribDeclaration -{ -public: - CPPMANGLE cppmangle; - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - const char *toChars() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class CPPNamespaceDeclaration : public AttribDeclaration -{ -public: - Expression *exp; - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - const char *toChars() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class ProtDeclaration : public AttribDeclaration -{ -public: - Prot protection; - Identifiers* pkg_identifiers; - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - void addMember(Scope *sc, ScopeDsymbol *sds); - const char *kind() const; - const char *toPrettyChars(bool unused); - ProtDeclaration *isProtDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class AlignDeclaration : public AttribDeclaration -{ -public: - Expression *ealign; - structalign_t salign; - - AlignDeclaration(const Loc &loc, Expression *ealign, Dsymbols *decl); - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class AnonDeclaration : public AttribDeclaration -{ -public: - bool isunion; - int sem; // 1 if successful semantic() - unsigned anonoffset; // offset of anonymous struct - unsigned anonstructsize; // size of anonymous struct - unsigned anonalignsize; // size of anonymous struct for alignment purposes - - Dsymbol *syntaxCopy(Dsymbol *s); - void setScope(Scope *sc); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - const char *kind() const; - AnonDeclaration *isAnonDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class PragmaDeclaration : public AttribDeclaration -{ -public: - Expressions *args; // array of Expression's - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class ConditionalDeclaration : public AttribDeclaration -{ -public: - Condition *condition; - Dsymbols *elsedecl; // array of Dsymbol's for else block - - Dsymbol *syntaxCopy(Dsymbol *s); - bool oneMember(Dsymbol **ps, Identifier *ident); - Dsymbols *include(Scope *sc); - void addComment(const utf8_t *comment); - void setScope(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticIfDeclaration : public ConditionalDeclaration -{ -public: - ScopeDsymbol *scopesym; - bool addisdone; - bool onStack; - - Dsymbol *syntaxCopy(Dsymbol *s); - Dsymbols *include(Scope *sc); - void addMember(Scope *sc, ScopeDsymbol *sds); - void setScope(Scope *sc); - void importAll(Scope *sc); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticForeachDeclaration : public ConditionalDeclaration -{ -public: - StaticForeach *sfe; - ScopeDsymbol *scopesym; - bool cached; - Dsymbols *cache; - - Dsymbol *syntaxCopy(Dsymbol *s); - bool oneMember(Dsymbol **ps, Identifier *ident); - Dsymbols *include(Scope *sc); - void addMember(Scope *sc, ScopeDsymbol *sds); - void addComment(const utf8_t *comment); - void setScope(Scope *sc); - void importAll(Scope *sc); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class ForwardingAttribDeclaration : AttribDeclaration -{ -public: - ForwardingScopeDsymbol *sym; - - Scope *newScope(Scope *sc); - void addMember(Scope *sc, ScopeDsymbol *sds); - ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return this; } -}; - -// Mixin declarations - -class CompileDeclaration : public AttribDeclaration -{ -public: - Expressions *exps; - - ScopeDsymbol *scopesym; - bool compiled; - - Dsymbol *syntaxCopy(Dsymbol *s); - void addMember(Scope *sc, ScopeDsymbol *sds); - void setScope(Scope *sc); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; - -/** - * User defined attributes look like: - * @(args, ...) - */ -class UserAttributeDeclaration : public AttribDeclaration -{ -public: - Expressions *atts; - - Dsymbol *syntaxCopy(Dsymbol *s); - Scope *newScope(Scope *sc); - void setScope(Scope *sc); - Expressions *getAttributes(); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/cond.h b/src/dmd/cond.h deleted file mode 100644 index 009d6e7f650c..000000000000 --- a/src/dmd/cond.h +++ /dev/null @@ -1,99 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/cond.h - */ - -#pragma once - -#include "ast_node.h" -#include "globals.h" -#include "visitor.h" - -class Expression; -class Identifier; -class Module; -struct Scope; -class DebugCondition; -class ForeachStatement; -class ForeachRangeStatement; - -enum Include -{ - INCLUDEnotComputed, /// not computed yet - INCLUDEyes, /// include the conditional code - INCLUDEno /// do not include the conditional code -}; - -class Condition : public ASTNode -{ -public: - Loc loc; - Include inc; - - virtual Condition *syntaxCopy() = 0; - virtual int include(Scope *sc) = 0; - virtual DebugCondition *isDebugCondition() { return NULL; } - virtual VersionCondition *isVersionCondition() { return NULL; } - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticForeach -{ -public: - Loc loc; - - ForeachStatement *aggrfe; - ForeachRangeStatement *rangefe; - - bool needExpansion; - - StaticForeach *syntaxCopy(); -}; - -class DVCondition : public Condition -{ -public: - unsigned level; - Identifier *ident; - Module *mod; - - Condition *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class DebugCondition : public DVCondition -{ -public: - static void addGlobalIdent(const char *ident); - - int include(Scope *sc); - DebugCondition *isDebugCondition() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class VersionCondition : public DVCondition -{ -public: - static void addGlobalIdent(const char *ident); - static void addPredefinedGlobalIdent(const char *ident); - - int include(Scope *sc); - VersionCondition *isVersionCondition() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticIfCondition : public Condition -{ -public: - Expression *exp; - int nest; // limit circular dependencies - - Condition *syntaxCopy(); - int include(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/ctfe.h b/src/dmd/ctfe.h deleted file mode 100644 index 51da94c9a643..000000000000 --- a/src/dmd/ctfe.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/ctfe.h - */ - -#pragma once - -#include "tokens.h" -#include "expression.h" - -/** - A reference to a class, or an interface. We need this when we - point to a base class (we must record what the type is). - */ -class ClassReferenceExp : public Expression -{ -public: - StructLiteralExp *value; - ClassDeclaration *originalClass(); - - /// Return index of the field, or -1 if not found - /// Same as getFieldIndex, but checks for a direct match with the VarDeclaration - int findFieldIndexByName(VarDeclaration *v); - void accept(Visitor *v) { v->visit(this); } -}; - -/** - An uninitialized value - */ -class VoidInitExp : public Expression -{ -public: - VarDeclaration *var; - - const char *toChars() const; - void accept(Visitor *v) { v->visit(this); } -}; - -/** - Fake class which holds the thrown exception. - Used for implementing exception handling. -*/ -class ThrownExceptionExp : public Expression -{ -public: - ClassReferenceExp *thrown; // the thing being tossed - const char *toChars() const; - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -// This type is only used by the interpreter. - -class CTFEExp : public Expression -{ -public: - const char *toChars() const; -}; diff --git a/src/dmd/declaration.h b/src/dmd/declaration.h deleted file mode 100644 index 7d1206e9577f..000000000000 --- a/src/dmd/declaration.h +++ /dev/null @@ -1,808 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/declaration.h - */ - -#pragma once - -#include "dsymbol.h" -#include "mtype.h" -#include "tokens.h" - -class Expression; -class Statement; -class LabelDsymbol; -class Initializer; -class ForeachStatement; -struct Ensure -{ - Identifier *id; - Statement *ensure; -}; -class FuncDeclaration; -class StructDeclaration; -struct ObjcSelector; -struct IntRange; - -#define STCundefined 0LL -#define STCstatic 1LL -#define STCextern 2LL -#define STCconst 4LL -#define STCfinal 8LL -#define STCabstract 0x10LL -#define STCparameter 0x20LL -#define STCfield 0x40LL -#define STCoverride 0x80LL -#define STCauto 0x100LL -#define STCsynchronized 0x200LL -#define STCdeprecated 0x400LL -#define STCin 0x800LL // in parameter -#define STCout 0x1000LL // out parameter -#define STClazy 0x2000LL // lazy parameter -#define STCforeach 0x4000LL // variable for foreach loop -#define STCvariadic 0x10000LL // the 'variadic' parameter in: T foo(T a, U b, V variadic...) -#define STCctorinit 0x20000LL // can only be set inside constructor -#define STCtemplateparameter 0x40000LL // template parameter -#define STCscope 0x80000LL -#define STCimmutable 0x100000LL -#define STCref 0x200000LL -#define STCinit 0x400000LL // has explicit initializer -#define STCmanifest 0x800000LL // manifest constant -#define STCnodtor 0x1000000LL // don't run destructor -#define STCnothrow 0x2000000LL // never throws exceptions -#define STCpure 0x4000000LL // pure function -#define STCtls 0x8000000LL // thread local -#define STCalias 0x10000000LL // alias parameter -#define STCshared 0x20000000LL // accessible from multiple threads -// accessible from multiple threads -// but not typed as "shared" -#define STCgshared 0x40000000LL -#define STCwild 0x80000000LL // for "wild" type constructor -#define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild) -#define STC_FUNCATTR (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem) - -#define STCproperty 0x100000000LL -#define STCsafe 0x200000000LL -#define STCtrusted 0x400000000LL -#define STCsystem 0x800000000LL -#define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static -#define STCdisable 0x2000000000LL // for functions that are not callable -#define STCresult 0x4000000000LL // for result variables passed to out contracts -#define STCnodefaultctor 0x8000000000LL // must be set inside constructor -#define STCtemp 0x10000000000LL // temporary variable -#define STCrvalue 0x20000000000LL // force rvalue for variables -#define STCnogc 0x40000000000LL // @nogc -#define STCvolatile 0x80000000000LL // destined for volatile in the back end -#define STCreturn 0x100000000000LL // 'return ref' or 'return scope' for function parameters -#define STCautoref 0x200000000000LL // Mark for the already deduced 'auto ref' parameter -#define STCinference 0x400000000000LL // do attribute inference -#define STCexptemp 0x800000000000LL // temporary variable that has lifetime restricted to an expression -#define STCmaybescope 0x1000000000000LL // parameter might be 'scope' -#define STCscopeinferred 0x2000000000000LL // 'scope' has been inferred and should not be part of mangling -#define STCfuture 0x4000000000000LL // introducing new base class function -#define STClocal 0x8000000000000LL // do not forward (see dmd.dsymbol.ForwardingScopeDsymbol). -#define STCreturninferred 0x10000000000000LL // 'return' has been inferred and should not be part of mangling - -void ObjectNotFound(Identifier *id); - -/**************************************************************/ - -class Declaration : public Dsymbol -{ -public: - Type *type; - Type *originalType; // before semantic analysis - StorageClass storage_class; - Prot protection; - LINK linkage; - int inuse; // used to detect cycles - DString mangleOverride; // overridden symbol with pragma(mangle, "...") - - const char *kind() const; - d_uns64 size(const Loc &loc); - - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - - bool isStatic() const { return (storage_class & STCstatic) != 0; } - virtual bool isDelete(); - virtual bool isDataseg(); - virtual bool isThreadlocal(); - virtual bool isCodeseg() const; - bool isCtorinit() const { return (storage_class & STCctorinit) != 0; } - bool isFinal() const { return (storage_class & STCfinal) != 0; } - virtual bool isAbstract() { return (storage_class & STCabstract) != 0; } - bool isConst() const { return (storage_class & STCconst) != 0; } - bool isImmutable() const { return (storage_class & STCimmutable) != 0; } - bool isWild() const { return (storage_class & STCwild) != 0; } - bool isAuto() const { return (storage_class & STCauto) != 0; } - bool isScope() const { return (storage_class & STCscope) != 0; } - bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; } - bool isParameter() const { return (storage_class & STCparameter) != 0; } - bool isDeprecated() const { return (storage_class & STCdeprecated) != 0; } - bool isOverride() const { return (storage_class & STCoverride) != 0; } - bool isResult() const { return (storage_class & STCresult) != 0; } - bool isField() const { return (storage_class & STCfield) != 0; } - - bool isIn() const { return (storage_class & STCin) != 0; } - bool isOut() const { return (storage_class & STCout) != 0; } - bool isRef() const { return (storage_class & STCref) != 0; } - - bool isFuture() const { return (storage_class & STCfuture) != 0; } - - Prot prot(); - - Declaration *isDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -class TupleDeclaration : public Declaration -{ -public: - Objects *objects; - bool isexp; // true: expression tuple - - TypeTuple *tupletype; // !=NULL if this is a type tuple - - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind() const; - Type *getType(); - Dsymbol *toAlias2(); - bool needThis(); - - TupleDeclaration *isTupleDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -class AliasDeclaration : public Declaration -{ -public: - Dsymbol *aliassym; - Dsymbol *overnext; // next in overload list - Dsymbol *_import; // !=NULL if unresolved internal alias for selective import - - static AliasDeclaration *create(Loc loc, Identifier *id, Type *type); - Dsymbol *syntaxCopy(Dsymbol *); - bool overloadInsert(Dsymbol *s); - const char *kind() const; - Type *getType(); - Dsymbol *toAlias(); - Dsymbol *toAlias2(); - bool isOverloadable() const; - - AliasDeclaration *isAliasDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -class OverDeclaration : public Declaration -{ -public: - Dsymbol *overnext; // next in overload list - Dsymbol *aliassym; - bool hasOverloads; - - const char *kind() const; - bool equals(const RootObject *o) const; - bool overloadInsert(Dsymbol *s); - - Dsymbol *toAlias(); - Dsymbol *isUnique(); - bool isOverloadable() const; - - OverDeclaration *isOverDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -class VarDeclaration : public Declaration -{ -public: - Initializer *_init; - unsigned offset; - unsigned sequenceNumber; // order the variables are declared - FuncDeclarations nestedrefs; // referenced by these lexically nested functions - structalign_t alignment; - bool isargptr; // if parameter that _argptr points to - bool ctorinit; // it has been initialized in a ctor - bool iscatchvar; // this is the exception object variable in catch() clause - bool onstack; // it is a class that was allocated on the stack - bool mynew; // it is a class new'd with custom operator new - int canassign; // it can be assigned to - bool overlapped; // if it is a field and has overlapping - bool overlapUnsafe; // if it is an overlapping field and the overlaps are unsafe - bool doNotInferScope; // do not infer 'scope' for this variable - bool doNotInferReturn; // do not infer 'return' for this variable - unsigned char isdataseg; // private data for isDataseg - Dsymbol *aliassym; // if redone as alias to another symbol - VarDeclaration *lastVar; // Linked list of variables for goto-skips-init detection - unsigned endlinnum; // line number of end of scope that this var lives in - - // When interpreting, these point to the value (NULL if value not determinable) - // The index of this variable on the CTFE stack, ~0u if not allocated - unsigned ctfeAdrOnStack; - Expression *edtor; // if !=NULL, does the destruction of the variable - IntRange *range; // if !NULL, the variable is known to be within the range - - VarDeclarations *maybes; // STCmaybescope variables that are assigned to this STCmaybescope variable - -private: - bool _isAnonymous; - -public: - static VarDeclaration *create(const Loc &loc, Type *t, Identifier *id, Initializer *init, StorageClass storage_class = STCundefined); - Dsymbol *syntaxCopy(Dsymbol *); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - const char *kind() const; - AggregateDeclaration *isThis(); - bool needThis(); - bool isAnonymous(); - bool isExport() const; - bool isImportedSymbol() const; - bool isDataseg(); - bool isThreadlocal(); - bool isCTFE(); - bool isOverlappedWith(VarDeclaration *v); - bool hasPointers(); - bool canTakeAddressOf(); - bool needsScopeDtor(); - bool enclosesLifetimeOf(VarDeclaration *v) const; - void checkCtorConstInit(); - Dsymbol *toAlias(); - // Eliminate need for dynamic_cast - VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -// This is a shell around a back end symbol - -class SymbolDeclaration : public Declaration -{ -public: - StructDeclaration *dsym; - - // Eliminate need for dynamic_cast - SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoDeclaration : public VarDeclaration -{ -public: - Type *tinfo; - - static TypeInfoDeclaration *create(Type *tinfo); - Dsymbol *syntaxCopy(Dsymbol *); - const char *toChars() const; - - TypeInfoDeclaration *isTypeInfoDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoStructDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoStructDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoClassDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoClassDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoInterfaceDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoPointerDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoPointerDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoArrayDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoArrayDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoStaticArrayDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoEnumDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoEnumDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoFunctionDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoFunctionDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoDelegateDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoDelegateDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoTupleDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoTupleDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoConstDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoConstDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoInvariantDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoInvariantDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoSharedDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoSharedDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoWildDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoWildDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeInfoVectorDeclaration : public TypeInfoDeclaration -{ -public: - static TypeInfoVectorDeclaration *create(Type *tinfo); - - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -class ThisDeclaration : public VarDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - ThisDeclaration *isThisDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -enum ILS -{ - ILSuninitialized, // not computed yet - ILSno, // cannot inline - ILSyes // can inline -}; - -/**************************************************************/ - -enum BUILTIN -{ - BUILTINunknown = -1, // not known if this is a builtin - BUILTINno, // this is not a builtin - BUILTINyes // this is a builtin -}; - -Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments); -BUILTIN isBuiltin(FuncDeclaration *fd); -void builtin_init(); - -class FuncDeclaration : public Declaration -{ -public: - struct HiddenParameters - { - VarDeclaration *this_; - bool isThis2; - VarDeclaration *selector; - }; - - Statements *frequires; // in contracts - Ensures *fensures; // out contracts - Statement *frequire; // lowered in contract - Statement *fensure; // lowered out contract - Statement *fbody; - - FuncDeclarations foverrides; // functions this function overrides - FuncDeclaration *fdrequire; // function that does the in contract - FuncDeclaration *fdensure; // function that does the out contract - - Expressions *fdrequireParams; // argument list for __require - Expressions *fdensureParams; // argument list for __ensure - - const char *mangleString; // mangled symbol created from mangleExact() - - VarDeclaration *vresult; // result variable for out contracts - LabelDsymbol *returnLabel; // where the return goes - - // used to prevent symbols in different - // scopes from having the same name - DsymbolTable *localsymtab; - VarDeclaration *vthis; // 'this' parameter (member and nested) - bool isThis2; // has a dual-context 'this' parameter - VarDeclaration *v_arguments; // '_arguments' parameter - ObjcSelector *selector; // Objective-C method selector (member function only) - VarDeclaration *selectorParameter; // Objective-C implicit selector parameter - - VarDeclaration *v_argptr; // '_argptr' variable - VarDeclarations *parameters; // Array of VarDeclaration's for parameters - DsymbolTable *labtab; // statement label symbol table - Dsymbol *overnext; // next in overload list - FuncDeclaration *overnext0; // next in overload list (only used during IFTI) - Loc endloc; // location of closing curly bracket - int vtblIndex; // for member functions, index into vtbl[] - bool naked; // true if naked - bool generated; // true if function was generated by the compiler rather than - // supplied by the user - unsigned char isCrtCtorDtor; // has attribute pragma(crt_constructor(1)/crt_destructor(2)) - // not set before the glue layer - ILS inlineStatusStmt; - ILS inlineStatusExp; - PINLINE inlining; - - int inlineNest; // !=0 if nested inline - bool isArrayOp; // true if array operation - bool eh_none; /// true if no exception unwinding is needed - - // true if errors in semantic3 this function's frame ptr - bool semantic3Errors; - ForeachStatement *fes; // if foreach body, this is the foreach - BaseClass* interfaceVirtual; // if virtual, but only appears in interface vtbl[] - bool introducing; // true if 'introducing' function - // if !=NULL, then this is the type - // of the 'introducing' function - // this one is overriding - Type *tintro; - bool inferRetType; // true if return type is to be inferred - StorageClass storage_class2; // storage class for template onemember's - - // Things that should really go into Scope - - // 1 if there's a return exp; statement - // 2 if there's a throw statement - // 4 if there's an assert(0) - // 8 if there's inline asm - // 16 if there are multiple return statements - int hasReturnExp; - - // Support for NRVO (named return value optimization) - bool nrvo_can; // true means we can do it - VarDeclaration *nrvo_var; // variable to replace with shidden - Symbol *shidden; // hidden pointer passed to function - - ReturnStatements *returns; - - GotoStatements *gotos; // Gotos with forward references - - // set if this is a known, builtin function we can evaluate at compile time - BUILTIN builtin; - - // set if someone took the address of this function - int tookAddressOf; - bool requiresClosure; // this function needs a closure - - // local variables in this function which are referenced by nested functions - VarDeclarations closureVars; - - /** Outer variables which are referenced by this nested function - * (the inverse of closureVars) - */ - VarDeclarations outerVars; - - // Sibling nested functions which called this one - FuncDeclarations siblingCallers; - - FuncDeclarations *inlinedNestedCallees; - - unsigned flags; // FUNCFLAGxxxxx - - static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type); - Dsymbol *syntaxCopy(Dsymbol *); - bool functionSemantic(); - bool functionSemantic3(); - bool equals(const RootObject *o) const; - - int overrides(FuncDeclaration *fd); - int findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349 = true); - BaseClass *overrideInterface(); - bool overloadInsert(Dsymbol *s); - bool inUnittest(); - MATCH leastAsSpecialized(FuncDeclaration *g); - LabelDsymbol *searchLabel(Identifier *ident); - int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference - int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd); - const char *toPrettyChars(bool QualifyTypes = false); - const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' - bool isMain() const; - bool isCMain() const; - bool isWinMain() const; - bool isDllMain() const; - bool isExport() const; - bool isImportedSymbol() const; - bool isCodeseg() const; - bool isOverloadable() const; - bool isAbstract(); - PURE isPure(); - PURE isPureBypassingInference(); - bool isSafe(); - bool isSafeBypassingInference(); - bool isTrusted(); - - bool isNogc(); - bool isNogcBypassingInference(); - - virtual bool isNested() const; - AggregateDeclaration *isThis(); - bool needThis(); - bool isVirtualMethod(); - virtual bool isVirtual() const; - bool isFinalFunc() const; - virtual bool addPreInvariant(); - virtual bool addPostInvariant(); - const char *kind() const; - bool isUnique(); - bool needsClosure(); - bool hasNestedFrameRefs(); - ParameterList getParameterList(); - - static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0); - static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0); - - FuncDeclaration *isFuncDeclaration() { return this; } - - virtual FuncDeclaration *toAliasFunc() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class FuncAliasDeclaration : public FuncDeclaration -{ -public: - FuncDeclaration *funcalias; - bool hasOverloads; - - FuncAliasDeclaration *isFuncAliasDeclaration() { return this; } - const char *kind() const; - - FuncDeclaration *toAliasFunc(); - void accept(Visitor *v) { v->visit(this); } -}; - -class FuncLiteralDeclaration : public FuncDeclaration -{ -public: - TOK tok; // TOKfunction or TOKdelegate - Type *treq; // target of return type inference - - // backend - bool deferToObj; - - Dsymbol *syntaxCopy(Dsymbol *); - bool isNested() const; - AggregateDeclaration *isThis(); - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - - void modifyReturns(Scope *sc, Type *tret); - - FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } - const char *kind() const; - const char *toPrettyChars(bool QualifyTypes = false); - void accept(Visitor *v) { v->visit(this); } -}; - -class CtorDeclaration : public FuncDeclaration -{ -public: - bool isCpCtor; - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind() const; - const char *toChars() const; - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - - CtorDeclaration *isCtorDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class PostBlitDeclaration : public FuncDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - bool overloadInsert(Dsymbol *s); - - PostBlitDeclaration *isPostBlitDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class DtorDeclaration : public FuncDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind() const; - const char *toChars() const; - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - bool overloadInsert(Dsymbol *s); - - DtorDeclaration *isDtorDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticCtorDeclaration : public FuncDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - AggregateDeclaration *isThis(); - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - bool hasStaticCtorOrDtor(); - - StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class SharedStaticCtorDeclaration : public StaticCtorDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - - SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticDtorDeclaration : public FuncDeclaration -{ -public: - VarDeclaration *vgate; // 'gate' variable - - Dsymbol *syntaxCopy(Dsymbol *); - AggregateDeclaration *isThis(); - bool isVirtual() const; - bool hasStaticCtorOrDtor(); - bool addPreInvariant(); - bool addPostInvariant(); - - StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class SharedStaticDtorDeclaration : public StaticDtorDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - - SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class InvariantDeclaration : public FuncDeclaration -{ -public: - Dsymbol *syntaxCopy(Dsymbol *); - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - - InvariantDeclaration *isInvariantDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class UnitTestDeclaration : public FuncDeclaration -{ -public: - char *codedoc; /** For documented unittest. */ - - // toObjFile() these nested functions after this one - FuncDeclarations deferredNested; - - Dsymbol *syntaxCopy(Dsymbol *); - AggregateDeclaration *isThis(); - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - - UnitTestDeclaration *isUnitTestDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class NewDeclaration : public FuncDeclaration -{ -public: - Parameters *parameters; - VarArg varargs; - - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind() const; - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - - NewDeclaration *isNewDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - - -class DeleteDeclaration : public FuncDeclaration -{ -public: - Parameters *parameters; - - Dsymbol *syntaxCopy(Dsymbol *); - const char *kind() const; - bool isDelete(); - bool isVirtual() const; - bool addPreInvariant(); - bool addPostInvariant(); - - DeleteDeclaration *isDeleteDeclaration() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/dsymbol.h b/src/dmd/dsymbol.h deleted file mode 100644 index 411b261b5521..000000000000 --- a/src/dmd/dsymbol.h +++ /dev/null @@ -1,397 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/dsymbol.h - */ - -#pragma once - -#include "root/port.h" -#include "ast_node.h" -#include "globals.h" -#include "arraytypes.h" -#include "visitor.h" - -class CPPNamespaceDeclaration; -class Identifier; -struct Scope; -class DsymbolTable; -class Declaration; -class ThisDeclaration; -class TypeInfoDeclaration; -class TupleDeclaration; -class AliasDeclaration; -class AggregateDeclaration; -class EnumDeclaration; -class ClassDeclaration; -class InterfaceDeclaration; -class StructDeclaration; -class UnionDeclaration; -class FuncDeclaration; -class FuncAliasDeclaration; -class OverDeclaration; -class FuncLiteralDeclaration; -class CtorDeclaration; -class PostBlitDeclaration; -class DtorDeclaration; -class StaticCtorDeclaration; -class StaticDtorDeclaration; -class SharedStaticCtorDeclaration; -class SharedStaticDtorDeclaration; -class InvariantDeclaration; -class UnitTestDeclaration; -class NewDeclaration; -class VarDeclaration; -class AttribDeclaration; -class ProtDeclaration; -class Package; -class Module; -class Import; -class Type; -class TypeTuple; -class WithStatement; -class LabelDsymbol; -class ScopeDsymbol; -class ForwardingScopeDsymbol; -class TemplateDeclaration; -class TemplateInstance; -class TemplateMixin; -class ForwardingAttribDeclaration; -class Nspace; -class EnumMember; -class WithScopeSymbol; -class ArrayScopeSymbol; -class SymbolDeclaration; -class Expression; -class ExpressionDsymbol; -class DeleteDeclaration; -class OverloadSet; -struct AA; -#ifdef IN_GCC -typedef union tree_node Symbol; -#else -struct Symbol; -#endif - -struct Ungag -{ - unsigned oldgag; - - Ungag(unsigned old) : oldgag(old) {} - ~Ungag() { global.gag = oldgag; } -}; - -void dsymbolSemantic(Dsymbol *dsym, Scope *sc); -void semantic2(Dsymbol *dsym, Scope *sc); -void semantic3(Dsymbol *dsym, Scope* sc); - -struct Prot -{ - enum Kind - { - undefined, - none, // no access - private_, - package_, - protected_, - public_, - export_ - }; - Kind kind; - Package *pkg; - - bool isMoreRestrictiveThan(const Prot other) const; - bool isSubsetOf(const Prot& other) const; -}; - -/* State of symbol in winding its way through the passes of the compiler - */ -enum PASS -{ - PASSinit, // initial state - PASSsemantic, // semantic() started - PASSsemanticdone, // semantic() done - PASSsemantic2, // semantic2() started - PASSsemantic2done, // semantic2() done - PASSsemantic3, // semantic3() started - PASSsemantic3done, // semantic3() done - PASSinline, // inline started - PASSinlinedone, // inline done - PASSobj // toObjFile() run -}; - -/* Flags for symbol search - */ -enum -{ - IgnoreNone = 0x00, // default - IgnorePrivateImports = 0x01, // don't search private imports - IgnoreErrors = 0x02, // don't give error messages - IgnoreAmbiguous = 0x04, // return NULL if ambiguous - SearchLocalsOnly = 0x08, // only look at locals (don't search imports) - SearchImportsOnly = 0x10, // only look in imports - SearchUnqualifiedModule = 0x20, // the module scope search is unqualified, - // meaning don't search imports in that scope, - // because qualified module searches search - // their imports - IgnoreSymbolVisibility = 0x80 // also find private and package protected symbols -}; - -typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *); - -class Dsymbol : public ASTNode -{ -public: - Identifier *ident; - Dsymbol *parent; - /// C++ namespace this symbol belongs to - CPPNamespaceDeclaration *namespace_; - Symbol *csym; // symbol for code generator - Symbol *isym; // import version of csym - const utf8_t *comment; // documentation comment for this Dsymbol - Loc loc; // where defined - Scope *_scope; // !=NULL means context to use for semantic() - const utf8_t *prettystring; - bool errors; // this symbol failed to pass semantic() - PASS semanticRun; - DeprecatedDeclaration *depdecl; // customized deprecation message - UserAttributeDeclaration *userAttribDecl; // user defined attributes - UnitTestDeclaration *ddocUnittest; // !=NULL means there's a ddoc unittest associated with this symbol (only use this with ddoc) - - static Dsymbol *create(Identifier *); - const char *toChars() const; - virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments - Loc getLoc(); - const char *locToChars(); - bool equals(const RootObject *o) const; - virtual bool isAnonymous(); - void error(const Loc &loc, const char *format, ...); - void error(const char *format, ...); - void deprecation(const Loc &loc, const char *format, ...); - void deprecation(const char *format, ...); - bool checkDeprecated(const Loc &loc, Scope *sc); - Module *getModule(); - Module *getAccessModule(); - Dsymbol *pastMixin(); - Dsymbol *toParent(); - Dsymbol *toParent2(); - Dsymbol *toParentDecl(); - Dsymbol *toParentLocal(); - Dsymbol *toParentP(Dsymbol *p1, Dsymbol *p2 = NULL); - TemplateInstance *isInstantiated(); - bool followInstantiationContext(Dsymbol *p1, Dsymbol *p2 = NULL); - TemplateInstance *isSpeculative(); - Ungag ungagSpeculative(); - - // kludge for template.isSymbol() - DYNCAST dyncast() const { return DYNCAST_DSYMBOL; } - - virtual Identifier *getIdent(); - virtual const char *toPrettyChars(bool QualifyTypes = false); - virtual const char *kind() const; - virtual Dsymbol *toAlias(); // resolve real symbol - virtual Dsymbol *toAlias2(); - virtual int apply(Dsymbol_apply_ft_t fp, void *param); - virtual void addMember(Scope *sc, ScopeDsymbol *sds); - virtual void setScope(Scope *sc); - virtual void importAll(Scope *sc); - virtual Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone); - virtual bool overloadInsert(Dsymbol *s); - virtual d_uns64 size(const Loc &loc); - virtual bool isforwardRef(); - virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member - virtual bool isExport() const; // is Dsymbol exported? - virtual bool isImportedSymbol() const; // is Dsymbol imported? - virtual bool isDeprecated() const; // is Dsymbol deprecated? - virtual bool isOverloadable() const; - virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol? - AggregateDeclaration *isMember(); // is toParent() an AggregateDeclaration? - AggregateDeclaration *isMember2(); // is toParent2() an AggregateDeclaration? - AggregateDeclaration *isMemberDecl(); // is toParentDecl() an AggregateDeclaration? - AggregateDeclaration *isMemberLocal(); // is toParentLocal() an AggregateDeclaration? - ClassDeclaration *isClassMember(); // isMember() is a ClassDeclaration? - virtual Type *getType(); // is this a type? - virtual bool needThis(); // need a 'this' pointer? - virtual Prot prot(); - virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees - virtual bool oneMember(Dsymbol **ps, Identifier *ident); - virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - virtual bool hasPointers(); - virtual bool hasStaticCtorOrDtor(); - virtual void addLocalClass(ClassDeclarations *) { } - virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { } - virtual void checkCtorConstInit() { } - - virtual void addComment(const utf8_t *comment); - - bool inNonRoot(); - - // Eliminate need for dynamic_cast - virtual Package *isPackage() { return NULL; } - virtual Module *isModule() { return NULL; } - virtual EnumMember *isEnumMember() { return NULL; } - virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; } - virtual TemplateInstance *isTemplateInstance() { return NULL; } - virtual TemplateMixin *isTemplateMixin() { return NULL; } - virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return NULL; } - virtual Nspace *isNspace() { return NULL; } - virtual Declaration *isDeclaration() { return NULL; } - virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; } - virtual ExpressionDsymbol *isExpressionDsymbol() { return NULL; } - virtual ThisDeclaration *isThisDeclaration() { return NULL; } - virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; } - virtual TupleDeclaration *isTupleDeclaration() { return NULL; } - virtual AliasDeclaration *isAliasDeclaration() { return NULL; } - virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; } - virtual FuncDeclaration *isFuncDeclaration() { return NULL; } - virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; } - virtual OverDeclaration *isOverDeclaration() { return NULL; } - virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } - virtual CtorDeclaration *isCtorDeclaration() { return NULL; } - virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } - virtual DtorDeclaration *isDtorDeclaration() { return NULL; } - virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } - virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; } - virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; } - virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; } - virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; } - virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; } - virtual NewDeclaration *isNewDeclaration() { return NULL; } - virtual VarDeclaration *isVarDeclaration() { return NULL; } - virtual ClassDeclaration *isClassDeclaration() { return NULL; } - virtual StructDeclaration *isStructDeclaration() { return NULL; } - virtual UnionDeclaration *isUnionDeclaration() { return NULL; } - virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; } - virtual ScopeDsymbol *isScopeDsymbol() { return NULL; } - virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return NULL; } - virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; } - virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; } - virtual Import *isImport() { return NULL; } - virtual EnumDeclaration *isEnumDeclaration() { return NULL; } - virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } - virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } - virtual AttribDeclaration *isAttribDeclaration() { return NULL; } - virtual AnonDeclaration *isAnonDeclaration() { return NULL; } - virtual CPPNamespaceDeclaration *isCPPNamespaceDeclaration() { return NULL; } - virtual ProtDeclaration *isProtDeclaration() { return NULL; } - virtual OverloadSet *isOverloadSet() { return NULL; } - virtual CompileDeclaration *isCompileDeclaration() { return NULL; } - void accept(Visitor *v) { v->visit(this); } -}; - -// Dsymbol that generates a scope - -class ScopeDsymbol : public Dsymbol -{ -public: - Dsymbols *members; // all Dsymbol's in this scope - DsymbolTable *symtab; // members[] sorted into table - unsigned endlinnum; // the linnumber of the statement after the scope (0 if unknown) - -private: - Dsymbols *importedScopes; // imported Dsymbol's - Prot::Kind *prots; // array of PROTKIND, one for each import - - BitArray accessiblePackages, privateAccessiblePackages; - -public: - Dsymbol *syntaxCopy(Dsymbol *s); - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - virtual void importScope(Dsymbol *s, Prot protection); - virtual bool isPackageAccessible(Package *p, Prot protection, int flags = 0); - bool isforwardRef(); - static void multiplyDefined(const Loc &loc, Dsymbol *s1, Dsymbol *s2); - const char *kind() const; - FuncDeclaration *findGetMembers(); - virtual Dsymbol *symtabInsert(Dsymbol *s); - virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id); - bool hasStaticCtorOrDtor(); - - ScopeDsymbol *isScopeDsymbol() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -// With statement scope - -class WithScopeSymbol : public ScopeDsymbol -{ -public: - WithStatement *withstate; - - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - - WithScopeSymbol *isWithScopeSymbol() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -// Array Index/Slice scope - -class ArrayScopeSymbol : public ScopeDsymbol -{ -public: - Expression *exp; // IndexExp or SliceExp - TypeTuple *type; // for tuple[length] - TupleDeclaration *td; // for tuples of objects - Scope *sc; - - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone); - - ArrayScopeSymbol *isArrayScopeSymbol() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -// Overload Sets - -class OverloadSet : public Dsymbol -{ -public: - Dsymbols a; // array of Dsymbols - - void push(Dsymbol *s); - OverloadSet *isOverloadSet() { return this; } - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; - -// Forwarding ScopeDsymbol - -class ForwardingScopeDsymbol : public ScopeDsymbol -{ - ScopeDsymbol *forward; - - Dsymbol *symtabInsert(Dsymbol *s); - Dsymbol *symtabLookup(Dsymbol *s, Identifier *id); - void importScope(Dsymbol *s, Prot protection); - const char *kind() const; - - ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; } -}; - -class ExpressionDsymbol : public Dsymbol -{ - Expression *exp; - - ExpressionDsymbol *isExpressionDsymbol() { return this; } -}; - -// Table of Dsymbol's - -class DsymbolTable : public RootObject -{ -public: - AA *tab; - - // Look up Identifier. Return Dsymbol if found, NULL if not. - Dsymbol *lookup(Identifier const * const ident); - - // Insert Dsymbol in table. Return NULL if already there. - Dsymbol *insert(Dsymbol *s); - - // Look for Dsymbol in table. If there, return it. If not, insert s and return that. - Dsymbol *update(Dsymbol *s); - Dsymbol *insert(Identifier const * const ident, Dsymbol *s); // when ident and s are not the same -}; diff --git a/src/dmd/enum.h b/src/dmd/enum.h deleted file mode 100644 index d0ae0981399a..000000000000 --- a/src/dmd/enum.h +++ /dev/null @@ -1,88 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/enum.h - */ - -#pragma once - -#include "dsymbol.h" -#include "declaration.h" - -class Identifier; -class Type; -class Expression; - -class EnumDeclaration : public ScopeDsymbol -{ -public: - /* The separate, and distinct, cases are: - * 1. enum { ... } - * 2. enum : memtype { ... } - * 3. enum id { ... } - * 4. enum id : memtype { ... } - * 5. enum id : memtype; - * 6. enum id; - */ - Type *type; // the TypeEnum - Type *memtype; // type of the members - Prot protection; - - Expression *maxval; - Expression *minval; - Expression *defaultval; // default initializer - - bool isdeprecated; - bool added; - int inuse; - - Dsymbol *syntaxCopy(Dsymbol *s); - void addMember(Scope *sc, ScopeDsymbol *sds); - void setScope(Scope *sc); - bool oneMember(Dsymbol **ps, Identifier *ident); - Type *getType(); - const char *kind() const; - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - bool isDeprecated() const; // is Dsymbol deprecated? - Prot prot(); - Expression *getMaxMinValue(const Loc &loc, Identifier *id); - bool isSpecial() const; - Expression *getDefaultValue(const Loc &loc); - Type *getMemtype(const Loc &loc); - - EnumDeclaration *isEnumDeclaration() { return this; } - - Symbol *sinit; - void accept(Visitor *v) { v->visit(this); } -}; - - -class EnumMember : public VarDeclaration -{ -public: - /* Can take the following forms: - * 1. id - * 2. id = value - * 3. type id = value - */ - Expression *&value(); - - // A cast() is injected to 'value' after semantic(), - // but 'origValue' will preserve the original value, - // or previous value + 1 if none was specified. - Expression *origValue; - Type *origType; - - EnumDeclaration *ed; - - Dsymbol *syntaxCopy(Dsymbol *s); - const char *kind() const; - Expression *getVarExp(const Loc &loc, Scope *sc); - - EnumMember *isEnumMember() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/expression.h b/src/dmd/expression.h deleted file mode 100644 index b8599d29c2d5..000000000000 --- a/src/dmd/expression.h +++ /dev/null @@ -1,1373 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/expression.h - */ - -#pragma once - -#include "ast_node.h" -#include "complex_t.h" -#include "globals.h" -#include "arraytypes.h" -#include "visitor.h" -#include "tokens.h" - -#include "root/dcompat.h" - -class Type; -class TypeVector; -struct Scope; -class TupleDeclaration; -class VarDeclaration; -class FuncDeclaration; -class FuncLiteralDeclaration; -class CtorDeclaration; -class NewDeclaration; -class Dsymbol; -class ScopeDsymbol; -class Expression; -class Declaration; -class StructDeclaration; -class TemplateInstance; -class TemplateDeclaration; -class ClassDeclaration; -class OverloadSet; -class StringExp; -struct UnionExp; -#ifdef IN_GCC -typedef union tree_node Symbol; -#else -struct Symbol; // back end symbol -#endif - -void expandTuples(Expressions *exps); -bool isTrivialExp(Expression *e); -bool hasSideEffect(Expression *e); -bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow); - -typedef unsigned char OwnedBy; -enum -{ - OWNEDcode, // normal code expression in AST - OWNEDctfe, // value expression for CTFE - OWNEDcache // constant value cached for CTFE -}; - -class Expression : public ASTNode -{ -public: - TOK op; // to minimize use of dynamic_cast - unsigned char size; // # of bytes in Expression so we can copy() it - unsigned char parens; // if this is a parenthesized expression - Type *type; // !=NULL means that semantic() has been run - Loc loc; // file location - - static void _init(); - Expression *copy(); - virtual Expression *syntaxCopy(); - - // kludge for template.isExpression() - DYNCAST dyncast() const { return DYNCAST_EXPRESSION; } - - const char *toChars() const; - void error(const char *format, ...) const; - void warning(const char *format, ...) const; - void deprecation(const char *format, ...) const; - - virtual dinteger_t toInteger(); - virtual uinteger_t toUInteger(); - virtual real_t toReal(); - virtual real_t toImaginary(); - virtual complex_t toComplex(); - virtual StringExp *toStringExp(); - virtual TupleExp *toTupleExp(); - virtual bool isLvalue(); - virtual Expression *toLvalue(Scope *sc, Expression *e); - virtual Expression *modifiableLvalue(Scope *sc, Expression *e); - Expression *implicitCastTo(Scope *sc, Type *t); - MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); - virtual Expression *resolveLoc(const Loc &loc, Scope *sc); - virtual bool checkType(); - virtual bool checkValue(); - bool checkDeprecated(Scope *sc, Dsymbol *s); - virtual int checkModifiable(Scope *sc, int flag = 0); - virtual Expression *toBoolean(Scope *sc); - virtual Expression *addDtorHook(Scope *sc); - Expression *addressOf(); - Expression *deref(); - - Expression *optimize(int result, bool keepLvalue = false); - - // Entry point for CTFE. - // A compile-time result is required. Give an error if not possible - Expression *ctfeInterpret(); - int isConst(); - virtual bool isBool(bool result); - - virtual bool hasCode() - { - return true; - } - - IntegerExp* isIntegerExp(); - ErrorExp* isErrorExp(); - VoidInitExp* isVoidInitExp(); - RealExp* isRealExp(); - ComplexExp* isComplexExp(); - IdentifierExp* isIdentifierExp(); - DollarExp* isDollarExp(); - DsymbolExp* isDsymbolExp(); - ThisExp* isThisExp(); - SuperExp* isSuperExp(); - NullExp* isNullExp(); - StringExp* isStringExp(); - TupleExp* isTupleExp(); - ArrayLiteralExp* isArrayLiteralExp(); - AssocArrayLiteralExp* isAssocArrayLiteralExp(); - StructLiteralExp* isStructLiteralExp(); - TypeExp* isTypeExp(); - ScopeExp* isScopeExp(); - TemplateExp* isTemplateExp(); - NewExp* isNewExp(); - NewAnonClassExp* isNewAnonClassExp(); - SymOffExp* isSymOffExp(); - VarExp* isVarExp(); - OverExp* isOverExp(); - FuncExp* isFuncExp(); - DeclarationExp* isDeclarationExp(); - TypeidExp* isTypeidExp(); - TraitsExp* isTraitsExp(); - HaltExp* isHaltExp(); - IsExp* isExp(); - CompileExp* isCompileExp(); - ImportExp* isImportExp(); - AssertExp* isAssertExp(); - DotIdExp* isDotIdExp(); - DotTemplateExp* isDotTemplateExp(); - DotVarExp* isDotVarExp(); - DotTemplateInstanceExp* isDotTemplateInstanceExp(); - DelegateExp* isDelegateExp(); - DotTypeExp* isDotTypeExp(); - CallExp* isCallExp(); - AddrExp* isAddrExp(); - PtrExp* isPtrExp(); - NegExp* isNegExp(); - UAddExp* isUAddExp(); - ComExp* isComExp(); - NotExp* isNotExp(); - DeleteExp* isDeleteExp(); - CastExp* isCastExp(); - VectorExp* isVectorExp(); - VectorArrayExp* isVectorArrayExp(); - SliceExp* isSliceExp(); - ArrayLengthExp* isArrayLengthExp(); - ArrayExp* isArrayExp(); - DotExp* isDotExp(); - CommaExp* isCommaExp(); - IntervalExp* isIntervalExp(); - DelegatePtrExp* isDelegatePtrExp(); - DelegateFuncptrExp* isDelegateFuncptrExp(); - IndexExp* isIndexExp(); - PostExp* isPostExp(); - PreExp* isPreExp(); - AssignExp* isAssignExp(); - ConstructExp* isConstructExp(); - BlitExp* isBlitExp(); - AddAssignExp* isAddAssignExp(); - MinAssignExp* isMinAssignExp(); - MulAssignExp* isMulAssignExp(); - DivAssignExp* isDivAssignExp(); - ModAssignExp* isModAssignExp(); - AndAssignExp* isAndAssignExp(); - OrAssignExp* isOrAssignExp(); - XorAssignExp* isXorAssignExp(); - PowAssignExp* isPowAssignExp(); - ShlAssignExp* isShlAssignExp(); - ShrAssignExp* isShrAssignExp(); - UshrAssignExp* isUshrAssignExp(); - CatAssignExp* isCatAssignExp(); - AddExp* isAddExp(); - MinExp* isMinExp(); - CatExp* isCatExp(); - MulExp* isMulExp(); - DivExp* isDivExp(); - ModExp* isModExp(); - PowExp* isPowExp(); - ShlExp* isShlExp(); - ShrExp* isShrExp(); - UshrExp* isUshrExp(); - AndExp* isAndExp(); - OrExp* isOrExp(); - XorExp* isXorExp(); - LogicalExp* isLogicalExp(); - InExp* isInExp(); - RemoveExp* isRemoveExp(); - EqualExp* isEqualExp(); - IdentityExp* isIdentityExp(); - CondExp* isCondExp(); - DefaultInitExp* isDefaultInitExp(); - FileInitExp* isFileInitExp(); - LineInitExp* isLineInitExp(); - ModuleInitExp* isModuleInitExp(); - FuncInitExp* isFuncInitExp(); - PrettyFuncInitExp* isPrettyFuncInitExp(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class IntegerExp : public Expression -{ -public: - dinteger_t value; - - static IntegerExp *create(Loc loc, dinteger_t value, Type *type); - static void emplace(UnionExp *pue, Loc loc, dinteger_t value, Type *type); - bool equals(const RootObject *o) const; - dinteger_t toInteger(); - real_t toReal(); - real_t toImaginary(); - complex_t toComplex(); - bool isBool(bool result); - Expression *toLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } - dinteger_t getInteger() { return value; } - void setInteger(dinteger_t value); - template - static IntegerExp literal(); -}; - -class ErrorExp : public Expression -{ -public: - Expression *toLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } - - static ErrorExp *errorexp; // handy shared value -}; - -class RealExp : public Expression -{ -public: - real_t value; - - static RealExp *create(Loc loc, real_t value, Type *type); - static void emplace(UnionExp *pue, Loc loc, real_t value, Type *type); - bool equals(const RootObject *o) const; - dinteger_t toInteger(); - uinteger_t toUInteger(); - real_t toReal(); - real_t toImaginary(); - complex_t toComplex(); - bool isBool(bool result); - void accept(Visitor *v) { v->visit(this); } -}; - -class ComplexExp : public Expression -{ -public: - complex_t value; - - static ComplexExp *create(Loc loc, complex_t value, Type *type); - static void emplace(UnionExp *pue, Loc loc, complex_t value, Type *type); - bool equals(const RootObject *o) const; - dinteger_t toInteger(); - uinteger_t toUInteger(); - real_t toReal(); - real_t toImaginary(); - complex_t toComplex(); - bool isBool(bool result); - void accept(Visitor *v) { v->visit(this); } -}; - -class IdentifierExp : public Expression -{ -public: - Identifier *ident; - - static IdentifierExp *create(Loc loc, Identifier *ident); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -class DollarExp : public IdentifierExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class DsymbolExp : public Expression -{ -public: - Dsymbol *s; - bool hasOverloads; - - Expression *syntaxCopy(); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -class ThisExp : public Expression -{ -public: - VarDeclaration *var; - - bool isBool(bool result); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - - void accept(Visitor *v) { v->visit(this); } -}; - -class SuperExp : public ThisExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class NullExp : public Expression -{ -public: - unsigned char committed; // !=0 if type is committed - - bool equals(const RootObject *o) const; - bool isBool(bool result); - StringExp *toStringExp(); - void accept(Visitor *v) { v->visit(this); } -}; - -class StringExp : public Expression -{ -public: - void *string; // char, wchar, or dchar data - size_t len; // number of chars, wchars, or dchars - unsigned char sz; // 1: char, 2: wchar, 4: dchar - unsigned char committed; // !=0 if type is committed - utf8_t postfix; // 'c', 'w', 'd' - OwnedBy ownedByCtfe; - - static StringExp *create(Loc loc, char *s); - static StringExp *create(Loc loc, void *s, size_t len); - static void emplace(UnionExp *pue, Loc loc, char *s); - static void emplace(UnionExp *pue, Loc loc, void *s, size_t len); - bool equals(const RootObject *o) const; - StringExp *toStringExp(); - StringExp *toUTF8(Scope *sc); - bool isBool(bool result); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - unsigned charAt(uinteger_t i) const; - void accept(Visitor *v) { v->visit(this); } - size_t numberOfCodeUnits(int tynto = 0) const; - void writeTo(void* dest, bool zero, int tyto = 0) const; -}; - -// Tuple - -class TupleExp : public Expression -{ -public: - Expression *e0; // side-effect part - /* Tuple-field access may need to take out its side effect part. - * For example: - * foo().tupleof - * is rewritten as: - * (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...)) - * The declaration of temporary variable __tup will be stored in TupleExp::e0. - */ - Expressions *exps; - - static TupleExp *create(Loc loc, Expressions *exps); - TupleExp *toTupleExp(); - Expression *syntaxCopy(); - bool equals(const RootObject *o) const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ArrayLiteralExp : public Expression -{ -public: - Expression *basis; - Expressions *elements; - OwnedBy ownedByCtfe; - - static ArrayLiteralExp *create(Loc loc, Expressions *elements); - static void emplace(UnionExp *pue, Loc loc, Expressions *elements); - Expression *syntaxCopy(); - bool equals(const RootObject *o) const; - Expression *getElement(d_size_t i); // use opIndex instead - Expression *opIndex(d_size_t i); - bool isBool(bool result); - StringExp *toStringExp(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class AssocArrayLiteralExp : public Expression -{ -public: - Expressions *keys; - Expressions *values; - OwnedBy ownedByCtfe; - - bool equals(const RootObject *o) const; - Expression *syntaxCopy(); - bool isBool(bool result); - - void accept(Visitor *v) { v->visit(this); } -}; - -class StructLiteralExp : public Expression -{ -public: - StructDeclaration *sd; // which aggregate this is for - Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip - Type *stype; // final type of result (can be different from sd's type) - - Symbol *sym; // back end symbol to initialize with literal - - /** pointer to the origin instance of the expression. - * once a new expression is created, origin is set to 'this'. - * anytime when an expression copy is created, 'origin' pointer is set to - * 'origin' pointer value of the original expression. - */ - StructLiteralExp *origin; - - // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. - StructLiteralExp *inlinecopy; - - /** anytime when recursive function is calling, 'stageflags' marks with bit flag of - * current stage and unmarks before return from this function. - * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline' - * (with infinite recursion) of this expression. - */ - int stageflags; - - bool useStaticInit; // if this is true, use the StructDeclaration's init symbol - bool isOriginal; // used when moving instances to indicate `this is this.origin` - OwnedBy ownedByCtfe; - - static StructLiteralExp *create(Loc loc, StructDeclaration *sd, void *elements, Type *stype = NULL); - bool equals(const RootObject *o) const; - Expression *syntaxCopy(); - Expression *getField(Type *type, unsigned offset); - int getFieldIndex(Type *type, unsigned offset); - Expression *addDtorHook(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeExp : public Expression -{ -public: - Expression *syntaxCopy(); - bool checkType(); - bool checkValue(); - void accept(Visitor *v) { v->visit(this); } -}; - -class ScopeExp : public Expression -{ -public: - ScopeDsymbol *sds; - - Expression *syntaxCopy(); - bool checkType(); - bool checkValue(); - void accept(Visitor *v) { v->visit(this); } -}; - -class TemplateExp : public Expression -{ -public: - TemplateDeclaration *td; - FuncDeclaration *fd; - - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - bool checkType(); - bool checkValue(); - void accept(Visitor *v) { v->visit(this); } -}; - -class NewExp : public Expression -{ -public: - /* thisexp.new(newargs) newtype(arguments) - */ - Expression *thisexp; // if !NULL, 'this' for class being allocated - Expressions *newargs; // Array of Expression's to call new operator - Type *newtype; - Expressions *arguments; // Array of Expression's - - Expression *argprefix; // expression to be evaluated just before arguments[] - - CtorDeclaration *member; // constructor function - NewDeclaration *allocator; // allocator function - bool onstack; // allocate on stack - bool thrownew; // this NewExp is the expression of a ThrowStatement - - static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments); - Expression *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class NewAnonClassExp : public Expression -{ -public: - /* thisexp.new(newargs) class baseclasses { } (arguments) - */ - Expression *thisexp; // if !NULL, 'this' for class being allocated - Expressions *newargs; // Array of Expression's to call new operator - ClassDeclaration *cd; // class being instantiated - Expressions *arguments; // Array of Expression's to call class constructor - - Expression *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class SymbolExp : public Expression -{ -public: - Declaration *var; - bool hasOverloads; - Dsymbol *originalScope; - - void accept(Visitor *v) { v->visit(this); } -}; - -// Offset from symbol - -class SymOffExp : public SymbolExp -{ -public: - dinteger_t offset; - - bool isBool(bool result); - - void accept(Visitor *v) { v->visit(this); } -}; - -// Variable - -class VarExp : public SymbolExp -{ -public: - bool delegateWasExtracted; - static VarExp *create(Loc loc, Declaration *var, bool hasOverloads = true); - bool equals(const RootObject *o) const; - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - - void accept(Visitor *v) { v->visit(this); } -}; - -// Overload Set - -class OverExp : public Expression -{ -public: - OverloadSet *vars; - - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -// Function/Delegate literal - -class FuncExp : public Expression -{ -public: - FuncLiteralDeclaration *fd; - TemplateDeclaration *td; - TOK tok; - - bool equals(const RootObject *o) const; - Expression *syntaxCopy(); - const char *toChars() const; - bool checkType(); - bool checkValue(); - - void accept(Visitor *v) { v->visit(this); } -}; - -// Declaration of a symbol - -// D grammar allows declarations only as statements. However in AST representation -// it can be part of any expression. This is used, for example, during internal -// syntax re-writes to inject hidden symbols. -class DeclarationExp : public Expression -{ -public: - Dsymbol *declaration; - - Expression *syntaxCopy(); - - bool hasCode(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeidExp : public Expression -{ -public: - RootObject *obj; - - Expression *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class TraitsExp : public Expression -{ -public: - Identifier *ident; - Objects *args; - - Expression *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class HaltExp : public Expression -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class IsExp : public Expression -{ -public: - /* is(targ id tok tspec) - * is(targ id == tok2) - */ - Type *targ; - Identifier *id; // can be NULL - Type *tspec; // can be NULL - TemplateParameters *parameters; - TOK tok; // ':' or '==' - TOK tok2; // 'struct', 'union', etc. - - Expression *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -class UnaExp : public Expression -{ -public: - Expression *e1; - Type *att1; // Save alias this type to detect recursion - - Expression *syntaxCopy(); - Expression *incompatibleTypes(); - Expression *resolveLoc(const Loc &loc, Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class BinExp : public Expression -{ -public: - Expression *e1; - Expression *e2; - - Type *att1; // Save alias this type to detect recursion - Type *att2; // Save alias this type to detect recursion - - Expression *syntaxCopy(); - Expression *incompatibleTypes(); - - Expression *reorderSettingAAElem(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class BinAssignExp : public BinExp -{ -public: - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *ex); - Expression *modifiableLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -class CompileExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ImportExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class AssertExp : public UnaExp -{ -public: - Expression *msg; - - Expression *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class DotIdExp : public UnaExp -{ -public: - Identifier *ident; - bool noderef; // true if the result of the expression will never be dereferenced - bool wantsym; // do not replace Symbol with its initializer during semantic() - - static DotIdExp *create(Loc loc, Expression *e, Identifier *ident); - void accept(Visitor *v) { v->visit(this); } -}; - -class DotTemplateExp : public UnaExp -{ -public: - TemplateDeclaration *td; - - void accept(Visitor *v) { v->visit(this); } -}; - -class DotVarExp : public UnaExp -{ -public: - Declaration *var; - bool hasOverloads; - - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -class DotTemplateInstanceExp : public UnaExp -{ -public: - TemplateInstance *ti; - - Expression *syntaxCopy(); - bool findTempDecl(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class DelegateExp : public UnaExp -{ -public: - FuncDeclaration *func; - bool hasOverloads; - VarDeclaration *vthis2; // container for multi-context - - - void accept(Visitor *v) { v->visit(this); } -}; - -class DotTypeExp : public UnaExp -{ -public: - Dsymbol *sym; // symbol that represents a type - - void accept(Visitor *v) { v->visit(this); } -}; - -class CallExp : public UnaExp -{ -public: - Expressions *arguments; // function arguments - FuncDeclaration *f; // symbol to call - bool directcall; // true if a virtual call is devirtualized - VarDeclaration *vthis2; // container for multi-context - - static CallExp *create(Loc loc, Expression *e, Expressions *exps); - static CallExp *create(Loc loc, Expression *e); - static CallExp *create(Loc loc, Expression *e, Expression *earg1); - static CallExp *create(Loc loc, FuncDeclaration *fd, Expression *earg1); - - Expression *syntaxCopy(); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *addDtorHook(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class AddrExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class PtrExp : public UnaExp -{ -public: - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - - void accept(Visitor *v) { v->visit(this); } -}; - -class NegExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class UAddExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ComExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class NotExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class DeleteExp : public UnaExp -{ -public: - bool isRAII; - Expression *toBoolean(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class CastExp : public UnaExp -{ -public: - // Possible to cast to one type while painting to another type - Type *to; // type to cast to - unsigned char mod; // MODxxxxx - - Expression *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class VectorExp : public UnaExp -{ -public: - TypeVector *to; // the target vector type before semantic() - unsigned dim; // number of elements in the vector - OwnedBy ownedByCtfe; - - static VectorExp *create(Loc loc, Expression *e, Type *t); - static void emplace(UnionExp *pue, Loc loc, Expression *e, Type *t); - Expression *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class VectorArrayExp : public UnaExp -{ -public: - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -class SliceExp : public UnaExp -{ -public: - Expression *upr; // NULL if implicit 0 - Expression *lwr; // NULL if implicit [length - 1] - VarDeclaration *lengthVar; - bool upperIsInBounds; // true if upr <= e1.length - bool lowerIsLessThanUpper; // true if lwr <= upr - bool arrayop; // an array operation, rather than a slice - - Expression *syntaxCopy(); - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - bool isBool(bool result); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ArrayLengthExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class IntervalExp : public Expression -{ -public: - Expression *lwr; - Expression *upr; - - Expression *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class DelegatePtrExp : public UnaExp -{ -public: - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -class DelegateFuncptrExp : public UnaExp -{ -public: - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - void accept(Visitor *v) { v->visit(this); } -}; - -// e1[a0,a1,a2,a3,...] - -class ArrayExp : public UnaExp -{ -public: - Expressions *arguments; // Array of Expression's - size_t currentDimension; // for opDollar - VarDeclaration *lengthVar; - - Expression *syntaxCopy(); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -class DotExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class CommaExp : public BinExp -{ -public: - bool isGenerated; - bool allowCommaExp; - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - bool isBool(bool result); - Expression *toBoolean(Scope *sc); - Expression *addDtorHook(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class IndexExp : public BinExp -{ -public: - VarDeclaration *lengthVar; - bool modifiable; - bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1 - - Expression *syntaxCopy(); - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - - void accept(Visitor *v) { v->visit(this); } -}; - -/* For both i++ and i-- - */ -class PostExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -/* For both ++i and --i - */ -class PreExp : public UnaExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -enum MemorySet -{ - blockAssign = 1, // setting the contents of an array - referenceInit = 2 // setting the reference of STCref variable -}; - -class AssignExp : public BinExp -{ -public: - int memset; // combination of MemorySet flags - - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *ex); - Expression *toBoolean(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ConstructExp : public AssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class BlitExp : public AssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class AddAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class MinAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class MulAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class DivAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ModAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class AndAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class OrAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class XorAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class PowAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ShlAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ShrAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class UshrAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class CatAssignExp : public BinAssignExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class AddExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class MinExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class CatExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class MulExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class DivExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ModExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class PowExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ShlExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class ShrExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class UshrExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class AndExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class OrExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class XorExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class LogicalExp : public BinExp -{ -public: - Expression *toBoolean(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class CmpExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class InExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class RemoveExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -// == and != - -class EqualExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -// is and !is - -class IdentityExp : public BinExp -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -class CondExp : public BinExp -{ -public: - Expression *econd; - - Expression *syntaxCopy(); - int checkModifiable(Scope *sc, int flag); - bool isLvalue(); - Expression *toLvalue(Scope *sc, Expression *e); - Expression *modifiableLvalue(Scope *sc, Expression *e); - Expression *toBoolean(Scope *sc); - void hookDtors(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -class DefaultInitExp : public Expression -{ -public: - TOK subop; // which of the derived classes this is - - void accept(Visitor *v) { v->visit(this); } -}; - -class FileInitExp : public DefaultInitExp -{ -public: - Expression *resolveLoc(const Loc &loc, Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class LineInitExp : public DefaultInitExp -{ -public: - Expression *resolveLoc(const Loc &loc, Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class ModuleInitExp : public DefaultInitExp -{ -public: - Expression *resolveLoc(const Loc &loc, Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class FuncInitExp : public DefaultInitExp -{ -public: - Expression *resolveLoc(const Loc &loc, Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class PrettyFuncInitExp : public DefaultInitExp -{ -public: - Expression *resolveLoc(const Loc &loc, Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -/****************************************************************/ - -/* A type meant as a union of all the Expression types, - * to serve essentially as a Variant that will sit on the stack - * during CTFE to reduce memory consumption. - */ -struct UnionExp -{ - UnionExp() { } // yes, default constructor does nothing - - UnionExp(Expression *e) - { - memcpy(this, (void *)e, e->size); - } - - /* Extract pointer to Expression - */ - Expression *exp() { return (Expression *)&u; } - - /* Convert to an allocated Expression - */ - Expression *copy(); - -private: - // Ensure that the union is suitably aligned. -#if defined(__GNUC__) || defined(__clang__) - __attribute__((aligned(8))) -#elif defined(_MSC_VER) - __declspec(align(8)) -#elif defined(__DMC__) - #pragma pack(8) -#endif - union - { - char exp [sizeof(Expression)]; - char integerexp[sizeof(IntegerExp)]; - char errorexp [sizeof(ErrorExp)]; - char realexp [sizeof(RealExp)]; - char complexexp[sizeof(ComplexExp)]; - char symoffexp [sizeof(SymOffExp)]; - char stringexp [sizeof(StringExp)]; - char arrayliteralexp [sizeof(ArrayLiteralExp)]; - char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)]; - char structliteralexp [sizeof(StructLiteralExp)]; - char nullexp [sizeof(NullExp)]; - char dotvarexp [sizeof(DotVarExp)]; - char addrexp [sizeof(AddrExp)]; - char indexexp [sizeof(IndexExp)]; - char sliceexp [sizeof(SliceExp)]; - char vectorexp [sizeof(VectorExp)]; - } u; -#if defined(__DMC__) - #pragma pack() -#endif -}; - -/****************************************************************/ - -class ObjcClassReferenceExp : public Expression -{ - ClassDeclaration* classDeclaration; - - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/hdrgen.h b/src/dmd/hdrgen.h deleted file mode 100644 index 0ab9fd9286c1..000000000000 --- a/src/dmd/hdrgen.h +++ /dev/null @@ -1,18 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Dave Fladebo - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/hdrgen.h - */ - -#pragma once - -#include "globals.h" - -class Module; - -void genhdrfile(Module *m); -void moduleToBuffer(OutBuffer *buf, Module *m); diff --git a/src/dmd/id.h b/src/dmd/id.h deleted file mode 100644 index d7ee43b25e3a..000000000000 --- a/src/dmd/id.h +++ /dev/null @@ -1,16 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 2017-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/id.h - */ - -#pragma once - -struct Id -{ - static void initialize(); -}; diff --git a/src/dmd/identifier.h b/src/dmd/identifier.h deleted file mode 100644 index 30787d5fee78..000000000000 --- a/src/dmd/identifier.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/identifier.h - */ - -#pragma once - -#include "root/dcompat.h" -#include "root/root.h" - -class Identifier : public RootObject -{ -private: - int value; - DString string; - -public: - static Identifier* anonymous(); - static Identifier* create(const char *string); - bool equals(const RootObject *o) const; - const char *toChars() const; - int getValue() const; - const char *toHChars2() const; - DYNCAST dyncast() const; - - static Identifier *idPool(const char *s, unsigned len); - - static inline Identifier *idPool(const char *s) - { - return idPool(s, static_cast(strlen(s))); - } - - static bool isValidIdentifier(const char *p); -}; diff --git a/src/dmd/import.h b/src/dmd/import.h deleted file mode 100644 index cc5472fcbe9c..000000000000 --- a/src/dmd/import.h +++ /dev/null @@ -1,54 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/import.h - */ - -#pragma once - -#include "dsymbol.h" - -class Identifier; -struct Scope; -class Module; -class Package; - -class Import : public Dsymbol -{ -public: - /* static import aliasId = pkg1.pkg2.id : alias1 = name1, alias2 = name2; - */ - - Identifiers *packages; // array of Identifier's representing packages - Identifier *id; // module Identifier - Identifier *aliasId; - int isstatic; // !=0 if static import - Prot protection; - - // Pairs of alias=name to bind into current namespace - Identifiers names; - Identifiers aliases; - - Module *mod; - Package *pkg; // leftmost package/module - - AliasDeclarations aliasdecls; // corresponding AliasDeclarations for alias=name pairs - - const char *kind() const; - Prot prot(); - Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees - void load(Scope *sc); - void importAll(Scope *sc); - Dsymbol *toAlias(); - void addMember(Scope *sc, ScopeDsymbol *sds); - void setScope(Scope* sc); - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - bool overloadInsert(Dsymbol *s); - - Import *isImport() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/init.h b/src/dmd/init.h deleted file mode 100644 index a6f1d620c8c9..000000000000 --- a/src/dmd/init.h +++ /dev/null @@ -1,93 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/init.h - */ - -#pragma once - -#include "ast_node.h" -#include "globals.h" -#include "arraytypes.h" -#include "visitor.h" - -class Identifier; -class Expression; -class Type; -class ErrorInitializer; -class VoidInitializer; -class StructInitializer; -class ArrayInitializer; -class ExpInitializer; - -enum NeedInterpret { INITnointerpret, INITinterpret }; - -class Initializer : public ASTNode -{ -public: - Loc loc; - unsigned char kind; - - const char *toChars() const; - - ErrorInitializer *isErrorInitializer(); - VoidInitializer *isVoidInitializer(); - StructInitializer *isStructInitializer(); - ArrayInitializer *isArrayInitializer(); - ExpInitializer *isExpInitializer(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class VoidInitializer : public Initializer -{ -public: - Type *type; // type that this will initialize to - - void accept(Visitor *v) { v->visit(this); } -}; - -class ErrorInitializer : public Initializer -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -class StructInitializer : public Initializer -{ -public: - Identifiers field; // of Identifier *'s - Initializers value; // parallel array of Initializer *'s - - void accept(Visitor *v) { v->visit(this); } -}; - -class ArrayInitializer : public Initializer -{ -public: - Expressions index; // indices - Initializers value; // of Initializer *'s - unsigned dim; // length of array being initialized - Type *type; // type that array will be used to initialize - bool sem; // true if semantic() is run - - bool isAssociativeArray() const; - Expression *toAssocArrayLiteral(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ExpInitializer : public Initializer -{ -public: - bool expandTuples; - Expression *exp; - - void accept(Visitor *v) { v->visit(this); } -}; - -Expression *initializerToExpression(Initializer *init, Type *t = NULL); diff --git a/src/dmd/json.h b/src/dmd/json.h deleted file mode 100644 index a831e461cb55..000000000000 --- a/src/dmd/json.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/json.h - */ - -#pragma once - -#include "arraytypes.h" -#include "globals.h" - -struct OutBuffer; - -void json_generate(OutBuffer *, Modules *); -JsonFieldFlags tryParseJsonField(const char *fieldName); diff --git a/src/dmd/module.h b/src/dmd/module.h deleted file mode 100644 index f4943d14f9e6..000000000000 --- a/src/dmd/module.h +++ /dev/null @@ -1,166 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/module.h - */ - -#pragma once - -#include "dsymbol.h" - -struct ModuleDeclaration; -struct Escape; -struct FileBuffer; - -struct MacroTable -{ - void* internal; // PIMPL -}; - -enum PKG -{ - PKGunknown, // not yet determined whether it's a package.d or not - PKGmodule, // already determined that's an actual package.d - PKGpackage // already determined that's an actual package -}; - -class Package : public ScopeDsymbol -{ -public: - PKG isPkgMod; - unsigned tag; // auto incremented tag, used to mask package tree in scopes - Module *mod; // != NULL if isPkgMod == PKGmodule - - const char *kind() const; - - Package *isPackage() { return this; } - - bool isAncestorPackageOf(const Package * const pkg) const; - - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - void accept(Visitor *v) { v->visit(this); } - - Module *isPackageMod(); -}; - -class Module : public Package -{ -public: - static Module *rootModule; - static DsymbolTable *modules; // symbol table of all modules - static Modules amodules; // array of all modules - static Dsymbols deferred; // deferred Dsymbol's needing semantic() run on them - static Dsymbols deferred2; // deferred Dsymbol's needing semantic2() run on them - static Dsymbols deferred3; // deferred Dsymbol's needing semantic3() run on them - static unsigned dprogress; // progress resolving the deferred list - - static void _init(); - - static AggregateDeclaration *moduleinfo; - - - DString arg; // original argument name - ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration - FileName srcfile; // input source file - FileName objfile; // output .obj file - FileName hdrfile; // 'header' file - FileName docfile; // output documentation file - FileBuffer *srcBuffer; // set during load(), free'd in parse() - unsigned errors; // if any errors in file - unsigned numlines; // number of lines in source file - bool isHdrFile; // if it is a header (.di) file - bool isDocFile; // if it is a documentation input file, not D source - bool isPackageFile; // if it is a package.d - Strings contentImportedFiles; // array of files whose content was imported - int needmoduleinfo; - int selfimports; // 0: don't know, 1: does not, 2: does - bool selfImports(); // returns true if module imports itself - - int rootimports; // 0: don't know, 1: does not, 2: does - bool rootImports(); // returns true if module imports root module - - int insearch; - Identifier *searchCacheIdent; - Dsymbol *searchCacheSymbol; // cached value of search - int searchCacheFlags; // cached flags - - // module from command line we're imported from, - // i.e. a module that will be taken all the - // way to an object file - Module *importedFrom; - - Dsymbols *decldefs; // top level declarations for this Module - - Modules aimports; // all imported modules - - unsigned debuglevel; // debug level - Strings *debugids; // debug identifiers - Strings *debugidsNot; // forward referenced debug identifiers - - unsigned versionlevel; // version level - Strings *versionids; // version identifiers - Strings *versionidsNot; // forward referenced version identifiers - - MacroTable macrotable; // document comment macros - Escape *escapetable; // document comment escapes - - size_t nameoffset; // offset of module name from start of ModuleInfo - size_t namelen; // length of module name in characters - - static Module* create(const char *arg, Identifier *ident, int doDocComment, int doHdrGen); - - static Module *load(Loc loc, Identifiers *packages, Identifier *ident); - - const char *kind() const; - bool read(const Loc &loc); // read file, returns 'true' if succeed, 'false' otherwise. - Module *parse(); // syntactic parse - void importAll(Scope *sc); - int needModuleInfo(); - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - bool isPackageAccessible(Package *p, Prot protection, int flags = 0); - Dsymbol *symtabInsert(Dsymbol *s); - void deleteObjFile(); - static void runDeferredSemantic(); - static void runDeferredSemantic2(); - static void runDeferredSemantic3(); - int imports(Module *m); - - bool isRoot() { return this->importedFrom == this; } - // true if the module source file is directly - // listed in command line. - bool isCoreModule(Identifier *ident); - - // Back end - - int doppelganger; // sub-module - Symbol *cov; // private uint[] __coverage; - unsigned *covb; // bit array of valid code line numbers - - Symbol *sictor; // module order independent constructor - Symbol *sctor; // module constructor - Symbol *sdtor; // module destructor - Symbol *ssharedctor; // module shared constructor - Symbol *sshareddtor; // module shared destructor - Symbol *stest; // module unit test - - Symbol *sfilename; // symbol for filename - - Module *isModule() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - - -struct ModuleDeclaration -{ - Loc loc; - Identifier *id; - Identifiers *packages; // array of Identifier's representing packages - bool isdeprecated; // if it is a deprecated module - Expression *msg; - - const char *toChars() const; -}; diff --git a/src/dmd/mtype.h b/src/dmd/mtype.h deleted file mode 100644 index 461b686361f6..000000000000 --- a/src/dmd/mtype.h +++ /dev/null @@ -1,859 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/mtype.h - */ - -#pragma once - -#include "root/dcompat.h" // for d_size_t - -#include "arraytypes.h" -#include "ast_node.h" -#include "globals.h" -#include "visitor.h" - -struct Scope; -class AggregateDeclaration; -class Identifier; -class Expression; -class StructDeclaration; -class ClassDeclaration; -class EnumDeclaration; -class TypeInfoDeclaration; -class Dsymbol; -class TemplateInstance; -class TemplateDeclaration; - -class TypeBasic; -class Parameter; - -// Back end -#ifdef IN_GCC -typedef union tree_node type; -#else -typedef struct TYPE type; -#endif - -void semanticTypeInfo(Scope *sc, Type *t); - -enum ENUMTY -{ - Tarray, // slice array, aka T[] - Tsarray, // static array, aka T[dimension] - Taarray, // associative array, aka T[type] - Tpointer, - Treference, - Tfunction, - Tident, - Tclass, - Tstruct, - Tenum, - - Tdelegate, - Tnone, - Tvoid, - Tint8, - Tuns8, - Tint16, - Tuns16, - Tint32, - Tuns32, - Tint64, - - Tuns64, - Tfloat32, - Tfloat64, - Tfloat80, - Timaginary32, - Timaginary64, - Timaginary80, - Tcomplex32, - Tcomplex64, - Tcomplex80, - - Tbool, - Tchar, - Twchar, - Tdchar, - Terror, - Tinstance, - Ttypeof, - Ttuple, - Tslice, - Treturn, - - Tnull, - Tvector, - Tint128, - Tuns128, - TTraits, - TMAX -}; -typedef unsigned char TY; // ENUMTY - -#define SIZE_INVALID (~(d_uns64)0) // error return from size() functions - - -/** - * type modifiers - * pick this order of numbers so switch statements work better - */ -enum MODFlags -{ - MODconst = 1, // type is const - MODimmutable = 4, // type is immutable - MODshared = 2, // type is shared - MODwild = 8, // type is wild - MODwildconst = (MODwild | MODconst), // type is wild const - MODmutable = 0x10 // type is mutable (only used in wildcard matching) -}; -typedef unsigned char MOD; - -enum VarArg -{ - VARARGnone = 0, /// fixed number of arguments - VARARGvariadic = 1, /// T t, ...) can be C-style (core.stdc.stdarg) or D-style (core.vararg) - VARARGtypesafe = 2 /// T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions - /// or https://dlang.org/spec/function.html#typesafe_variadic_functions -}; - -class Type : public ASTNode -{ -public: - TY ty; - MOD mod; // modifiers MODxxxx - char *deco; - - /* These are cached values that are lazily evaluated by constOf(), immutableOf(), etc. - * They should not be referenced by anybody but mtype.c. - * They can be NULL if not lazily evaluated yet. - * Note that there is no "shared immutable", because that is just immutable - * Naked == no MOD bits - */ - - Type *cto; // MODconst ? naked version of this type : const version - Type *ito; // MODimmutable ? naked version of this type : immutable version - Type *sto; // MODshared ? naked version of this type : shared mutable version - Type *scto; // MODshared | MODconst ? naked version of this type : shared const version - Type *wto; // MODwild ? naked version of this type : wild version - Type *wcto; // MODwildconst ? naked version of this type : wild const version - Type *swto; // MODshared | MODwild ? naked version of this type : shared wild version - Type *swcto; // MODshared | MODwildconst ? naked version of this type : shared wild const version - - Type *pto; // merged pointer to this type - Type *rto; // reference to this type - Type *arrayof; // array of this type - TypeInfoDeclaration *vtinfo; // TypeInfo object for this Type - - type *ctype; // for back end - - static Type *tvoid; - static Type *tint8; - static Type *tuns8; - static Type *tint16; - static Type *tuns16; - static Type *tint32; - static Type *tuns32; - static Type *tint64; - static Type *tuns64; - static Type *tint128; - static Type *tuns128; - static Type *tfloat32; - static Type *tfloat64; - static Type *tfloat80; - - static Type *timaginary32; - static Type *timaginary64; - static Type *timaginary80; - - static Type *tcomplex32; - static Type *tcomplex64; - static Type *tcomplex80; - - static Type *tbool; - static Type *tchar; - static Type *twchar; - static Type *tdchar; - - // Some special types - static Type *tshiftcnt; - static Type *tvoidptr; // void* - static Type *tstring; // immutable(char)[] - static Type *twstring; // immutable(wchar)[] - static Type *tdstring; // immutable(dchar)[] - static Type *tvalist; // va_list alias - static Type *terror; // for error recovery - static Type *tnull; // for null type - - static Type *tsize_t; // matches size_t alias - static Type *tptrdiff_t; // matches ptrdiff_t alias - static Type *thash_t; // matches hash_t alias - - static ClassDeclaration *dtypeinfo; - static ClassDeclaration *typeinfoclass; - static ClassDeclaration *typeinfointerface; - static ClassDeclaration *typeinfostruct; - static ClassDeclaration *typeinfopointer; - static ClassDeclaration *typeinfoarray; - static ClassDeclaration *typeinfostaticarray; - static ClassDeclaration *typeinfoassociativearray; - static ClassDeclaration *typeinfovector; - static ClassDeclaration *typeinfoenum; - static ClassDeclaration *typeinfofunction; - static ClassDeclaration *typeinfodelegate; - static ClassDeclaration *typeinfotypelist; - static ClassDeclaration *typeinfoconst; - static ClassDeclaration *typeinfoinvariant; - static ClassDeclaration *typeinfoshared; - static ClassDeclaration *typeinfowild; - - static TemplateDeclaration *rtinfo; - - static Type *basic[TMAX]; - - virtual const char *kind(); - Type *copy() const; - virtual Type *syntaxCopy(); - bool equals(const RootObject *o) const; - bool equivalent(Type *t); - // kludge for template.isType() - DYNCAST dyncast() const { return DYNCAST_TYPE; } - int covariant(Type *t, StorageClass *pstc = NULL, bool fix17349 = true); - const char *toChars() const; - char *toPrettyChars(bool QualifyTypes = false); - static void _init(); - - d_uns64 size(); - virtual d_uns64 size(const Loc &loc); - virtual unsigned alignsize(); - Type *trySemantic(const Loc &loc, Scope *sc); - Type *merge2(); - void modToBuffer(OutBuffer *buf) const; - char *modToChars() const; - - virtual bool isintegral(); - virtual bool isfloating(); // real, imaginary, or complex - virtual bool isreal(); - virtual bool isimaginary(); - virtual bool iscomplex(); - virtual bool isscalar(); - virtual bool isunsigned(); - virtual bool ischar(); - virtual bool isscope(); - virtual bool isString(); - virtual bool isAssignable(); - virtual bool isBoolean(); - virtual void checkDeprecated(const Loc &loc, Scope *sc); - bool isConst() const { return (mod & MODconst) != 0; } - bool isImmutable() const { return (mod & MODimmutable) != 0; } - bool isMutable() const { return (mod & (MODconst | MODimmutable | MODwild)) == 0; } - bool isShared() const { return (mod & MODshared) != 0; } - bool isSharedConst() const { return (mod & (MODshared | MODconst)) == (MODshared | MODconst); } - bool isWild() const { return (mod & MODwild) != 0; } - bool isWildConst() const { return (mod & MODwildconst) == MODwildconst; } - bool isSharedWild() const { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); } - bool isNaked() const { return mod == 0; } - Type *nullAttributes() const; - Type *constOf(); - Type *immutableOf(); - Type *mutableOf(); - Type *sharedOf(); - Type *sharedConstOf(); - Type *unSharedOf(); - Type *wildOf(); - Type *wildConstOf(); - Type *sharedWildOf(); - Type *sharedWildConstOf(); - void fixTo(Type *t); - void check(); - Type *addSTC(StorageClass stc); - Type *castMod(MOD mod); - Type *addMod(MOD mod); - virtual Type *addStorageClass(StorageClass stc); - Type *pointerTo(); - Type *referenceTo(); - Type *arrayOf(); - Type *sarrayOf(dinteger_t dim); - Type *aliasthisOf(); - virtual Type *makeConst(); - virtual Type *makeImmutable(); - virtual Type *makeShared(); - virtual Type *makeSharedConst(); - virtual Type *makeWild(); - virtual Type *makeWildConst(); - virtual Type *makeSharedWild(); - virtual Type *makeSharedWildConst(); - virtual Type *makeMutable(); - virtual Dsymbol *toDsymbol(Scope *sc); - virtual Type *toBasetype(); - virtual bool isBaseOf(Type *t, int *poffset); - virtual MATCH implicitConvTo(Type *to); - virtual MATCH constConv(Type *to); - virtual unsigned char deduceWild(Type *t, bool isRef); - virtual Type *substWildTo(unsigned mod); - - Type *unqualify(unsigned m); - - virtual Type *toHeadMutable(); - virtual ClassDeclaration *isClassHandle(); - virtual structalign_t alignment(); - virtual Expression *defaultInitLiteral(const Loc &loc); - virtual bool isZeroInit(const Loc &loc = Loc()); // if initializer is 0 - Identifier *getTypeInfoIdent(); - virtual int hasWild() const; - virtual bool hasPointers(); - virtual bool hasVoidInitPointers(); - virtual Type *nextOf(); - Type *baseElemOf(); - uinteger_t sizemask(); - virtual bool needsDestruction(); - virtual bool needsNested(); - - // For eliminating dynamic_cast - virtual TypeBasic *isTypeBasic(); - TypeError *isTypeError(); - TypeVector *isTypeVector(); - TypeSArray *isTypeSArray(); - TypeDArray *isTypeDArray(); - TypeAArray *isTypeAArray(); - TypePointer *isTypePointer(); - TypeReference *isTypeReference(); - TypeFunction *isTypeFunction(); - TypeDelegate *isTypeDelegate(); - TypeIdentifier *isTypeIdentifier(); - TypeInstance *isTypeInstance(); - TypeTypeof *isTypeTypeof(); - TypeReturn *isTypeReturn(); - TypeStruct *isTypeStruct(); - TypeEnum *isTypeEnum(); - TypeClass *isTypeClass(); - TypeTuple *isTypeTuple(); - TypeSlice *isTypeSlice(); - TypeNull *isTypeNull(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeError : public Type -{ -public: - Type *syntaxCopy(); - - d_uns64 size(const Loc &loc); - Expression *defaultInitLiteral(const Loc &loc); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeNext : public Type -{ -public: - Type *next; - - void checkDeprecated(const Loc &loc, Scope *sc); - int hasWild() const; - Type *nextOf(); - Type *makeConst(); - Type *makeImmutable(); - Type *makeShared(); - Type *makeSharedConst(); - Type *makeWild(); - Type *makeWildConst(); - Type *makeSharedWild(); - Type *makeSharedWildConst(); - Type *makeMutable(); - MATCH constConv(Type *to); - unsigned char deduceWild(Type *t, bool isRef); - void transitive(); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeBasic : public Type -{ -public: - const char *dstring; - unsigned flags; - - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc) /*const*/; - unsigned alignsize(); - bool isintegral(); - bool isfloating() /*const*/; - bool isreal() /*const*/; - bool isimaginary() /*const*/; - bool iscomplex() /*const*/; - bool isscalar() /*const*/; - bool isunsigned() /*const*/; - bool ischar() /*const*/; - MATCH implicitConvTo(Type *to); - bool isZeroInit(const Loc &loc) /*const*/; - - // For eliminating dynamic_cast - TypeBasic *isTypeBasic(); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeVector : public Type -{ -public: - Type *basetype; - - static TypeVector *create(Type *basetype); - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc); - unsigned alignsize(); - bool isintegral(); - bool isfloating(); - bool isscalar(); - bool isunsigned(); - bool isBoolean() /*const*/; - MATCH implicitConvTo(Type *to); - Expression *defaultInitLiteral(const Loc &loc); - TypeBasic *elementType(); - bool isZeroInit(const Loc &loc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeArray : public TypeNext -{ -public: - void accept(Visitor *v) { v->visit(this); } -}; - -// Static array, one with a fixed dimension -class TypeSArray : public TypeArray -{ -public: - Expression *dim; - - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc); - unsigned alignsize(); - bool isString(); - bool isZeroInit(const Loc &loc); - structalign_t alignment(); - MATCH constConv(Type *to); - MATCH implicitConvTo(Type *to); - Expression *defaultInitLiteral(const Loc &loc); - bool hasPointers(); - bool needsDestruction(); - bool needsNested(); - - void accept(Visitor *v) { v->visit(this); } -}; - -// Dynamic array, no dimension -class TypeDArray : public TypeArray -{ -public: - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc) /*const*/; - unsigned alignsize() /*const*/; - bool isString(); - bool isZeroInit(const Loc &loc) /*const*/; - bool isBoolean() /*const*/; - MATCH implicitConvTo(Type *to); - bool hasPointers() /*const*/; - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeAArray : public TypeArray -{ -public: - Type *index; // key type - Loc loc; - Scope *sc; - - static TypeAArray *create(Type *t, Type *index); - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc); - bool isZeroInit(const Loc &loc) /*const*/; - bool isBoolean() /*const*/; - bool hasPointers() /*const*/; - MATCH implicitConvTo(Type *to); - MATCH constConv(Type *to); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypePointer : public TypeNext -{ -public: - static TypePointer *create(Type *t); - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc) /*const*/; - MATCH implicitConvTo(Type *to); - MATCH constConv(Type *to); - bool isscalar() /*const*/; - bool isZeroInit(const Loc &loc) /*const*/; - bool hasPointers() /*const*/; - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeReference : public TypeNext -{ -public: - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc) /*const*/; - bool isZeroInit(const Loc &loc) /*const*/; - void accept(Visitor *v) { v->visit(this); } -}; - -enum RET -{ - RETregs = 1, // returned in registers - RETstack = 2 // returned on stack -}; - -enum TRUST -{ - TRUSTdefault = 0, - TRUSTsystem = 1, // @system (same as TRUSTdefault) - TRUSTtrusted = 2, // @trusted - TRUSTsafe = 3 // @safe -}; - -enum TRUSTformat -{ - TRUSTformatDefault, // do not emit @system when trust == TRUSTdefault - TRUSTformatSystem // emit @system when trust == TRUSTdefault -}; - -enum PURE -{ - PUREimpure = 0, // not pure at all - PUREfwdref = 1, // it's pure, but not known which level yet - PUREweak = 2, // no mutable globals are read or written - PUREconst = 3, // parameters are values or const - PUREstrong = 4 // parameters are values or immutable -}; - -class Parameter : public ASTNode -{ -public: - StorageClass storageClass; - Type *type; - Identifier *ident; - Expression *defaultArg; - UserAttributeDeclaration *userAttribDecl; // user defined attributes - - static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident, - Expression *defaultArg, UserAttributeDeclaration *userAttribDecl); - Parameter *syntaxCopy(); - Type *isLazyArray(); - // kludge for template.isType() - DYNCAST dyncast() const { return DYNCAST_PARAMETER; } - void accept(Visitor *v) { v->visit(this); } - - static size_t dim(Parameters *parameters); - static Parameter *getNth(Parameters *parameters, d_size_t nth, d_size_t *pn = NULL); - const char *toChars() const; - bool isCovariant(bool returnByRef, const Parameter *p) const; -}; - -struct ParameterList -{ - Parameters* parameters; - VarArg varargs; - - size_t length(); - Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); } -}; - -class TypeFunction : public TypeNext -{ -public: - // .next is the return type - - ParameterList parameterList; // function parameters - - bool isnothrow; // true: nothrow - bool isnogc; // true: is @nogc - bool isproperty; // can be called without parentheses - bool isref; // true: returns a reference - bool isreturn; // true: 'this' is returned by ref - bool isscope; // true: 'this' is scope - bool isreturninferred; // true: 'this' is return from inference - bool isscopeinferred; // true: 'this' is scope from inference - LINK linkage; // calling convention - TRUST trust; // level of trust - PURE purity; // PURExxxx - unsigned char iswild; // bit0: inout on params, bit1: inout on qualifier - Expressions *fargs; // function arguments - - int inuse; - bool incomplete; - - static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0); - const char *kind(); - Type *syntaxCopy(); - void purityLevel(); - bool hasLazyParameters(); - bool isDstyleVariadic(); - bool parameterEscapes(Parameter *p); - StorageClass parameterStorageClass(Parameter *p); - Type *addStorageClass(StorageClass stc); - - Type *substWildTo(unsigned mod); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeDelegate : public TypeNext -{ -public: - // .next is a TypeFunction - - static TypeDelegate *create(Type *t); - const char *kind(); - Type *syntaxCopy(); - Type *addStorageClass(StorageClass stc); - d_uns64 size(const Loc &loc) /*const*/; - unsigned alignsize() /*const*/; - MATCH implicitConvTo(Type *to); - bool isZeroInit(const Loc &loc) /*const*/; - bool isBoolean() /*const*/; - bool hasPointers() /*const*/; - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeTraits : public Type -{ - Loc loc; - /// The expression to resolve as type or symbol. - TraitsExp *exp; - /// The symbol when exp doesn't represent a type. - Dsymbol *sym; - - Type *syntaxCopy(); - d_uns64 size(const Loc &loc); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeQualified : public Type -{ -public: - Loc loc; - // array of Identifier and TypeInstance, - // representing ident.ident!tiargs.ident. ... etc. - Objects idents; - - void syntaxCopyHelper(TypeQualified *t); - void addIdent(Identifier *ident); - void addInst(TemplateInstance *inst); - void addIndex(RootObject *expr); - d_uns64 size(const Loc &loc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeIdentifier : public TypeQualified -{ -public: - Identifier *ident; - Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution - - const char *kind(); - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -/* Similar to TypeIdentifier, but with a TemplateInstance as the root - */ -class TypeInstance : public TypeQualified -{ -public: - TemplateInstance *tempinst; - - const char *kind(); - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeTypeof : public TypeQualified -{ -public: - Expression *exp; - int inuse; - - const char *kind(); - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); - d_uns64 size(const Loc &loc); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeReturn : public TypeQualified -{ -public: - const char *kind(); - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -// Whether alias this dependency is recursive or not. -enum AliasThisRec -{ - RECno = 0, // no alias this recursion - RECyes = 1, // alias this has recursive dependency - RECfwdref = 2, // not yet known - RECtypeMask = 3,// mask to read no/yes/fwdref - - RECtracing = 0x4, // mark in progress of implicitConvTo/deduceWild - RECtracingDT = 0x8 // mark in progress of deduceType -}; - -class TypeStruct : public Type -{ -public: - StructDeclaration *sym; - AliasThisRec att; - CPPMANGLE cppmangle; - - static TypeStruct *create(StructDeclaration *sym); - const char *kind(); - d_uns64 size(const Loc &loc); - unsigned alignsize(); - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); - structalign_t alignment(); - Expression *defaultInitLiteral(const Loc &loc); - bool isZeroInit(const Loc &loc) /*const*/; - bool isAssignable(); - bool isBoolean() /*const*/; - bool needsDestruction() /*const*/; - bool needsNested(); - bool hasPointers(); - bool hasVoidInitPointers(); - MATCH implicitConvTo(Type *to); - MATCH constConv(Type *to); - unsigned char deduceWild(Type *t, bool isRef); - Type *toHeadMutable(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeEnum : public Type -{ -public: - EnumDeclaration *sym; - - const char *kind(); - Type *syntaxCopy(); - d_uns64 size(const Loc &loc); - unsigned alignsize(); - Type *memType(const Loc &loc = Loc()); - Dsymbol *toDsymbol(Scope *sc); - bool isintegral(); - bool isfloating(); - bool isreal(); - bool isimaginary(); - bool iscomplex(); - bool isscalar(); - bool isunsigned(); - bool ischar(); - bool isBoolean(); - bool isString(); - bool isAssignable(); - bool needsDestruction(); - bool needsNested(); - MATCH implicitConvTo(Type *to); - MATCH constConv(Type *to); - Type *toBasetype(); - bool isZeroInit(const Loc &loc); - bool hasPointers(); - bool hasVoidInitPointers(); - Type *nextOf(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeClass : public Type -{ -public: - ClassDeclaration *sym; - AliasThisRec att; - CPPMANGLE cppmangle; - - const char *kind(); - d_uns64 size(const Loc &loc) /*const*/; - Type *syntaxCopy(); - Dsymbol *toDsymbol(Scope *sc); - ClassDeclaration *isClassHandle(); - bool isBaseOf(Type *t, int *poffset); - MATCH implicitConvTo(Type *to); - MATCH constConv(Type *to); - unsigned char deduceWild(Type *t, bool isRef); - Type *toHeadMutable(); - bool isZeroInit(const Loc &loc) /*const*/; - bool isscope() /*const*/; - bool isBoolean() /*const*/; - bool hasPointers() /*const*/; - - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeTuple : public Type -{ -public: - Parameters *arguments; // types making up the tuple - - static TypeTuple *create(Parameters *arguments); - static TypeTuple *create(); - static TypeTuple *create(Type *t1); - static TypeTuple *create(Type *t1, Type *t2); - const char *kind(); - Type *syntaxCopy(); - bool equals(const RootObject *o) const; - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeSlice : public TypeNext -{ -public: - Expression *lwr; - Expression *upr; - - const char *kind(); - Type *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class TypeNull : public Type -{ -public: - const char *kind(); - - Type *syntaxCopy(); - MATCH implicitConvTo(Type *to); - bool isBoolean() /*const*/; - - d_uns64 size(const Loc &loc) /*const*/; - void accept(Visitor *v) { v->visit(this); } -}; - -/**************************************************************/ - -bool arrayTypeCompatible(Loc loc, Type *t1, Type *t2); -bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2); - -// If the type is a class or struct, returns the symbol for it, else null. -AggregateDeclaration *isAggregate(Type *t); diff --git a/src/dmd/nspace.h b/src/dmd/nspace.h deleted file mode 100644 index c79a0df44bab..000000000000 --- a/src/dmd/nspace.h +++ /dev/null @@ -1,34 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/nspace.h - */ - -#pragma once - -#include "dsymbol.h" - -/* A namespace corresponding to a C++ namespace. - * Implies extern(C++). - */ - -class Nspace : public ScopeDsymbol -{ - public: - Expression *identExp; - Dsymbol *syntaxCopy(Dsymbol *s); - void addMember(Scope *sc, ScopeDsymbol *sds); - void setScope(Scope *sc); - bool oneMember(Dsymbol **ps, Identifier *ident); - Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); - int apply(Dsymbol_apply_ft_t fp, void *param); - bool hasPointers(); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - const char *kind() const; - Nspace *isNspace() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/objc.h b/src/dmd/objc.h deleted file mode 100644 index e328ebd24a6d..000000000000 --- a/src/dmd/objc.h +++ /dev/null @@ -1,75 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 2015-2019 by The D Language Foundation, All Rights Reserved - * written by Michel Fortin - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/objc.h - */ - -#pragma once - -#include "root/dsystem.h" -#include "arraytypes.h" - -class AggregateDeclaration; -class AttribDeclaration; -class ClassDeclaration; -class FuncDeclaration; -class Identifier; -class InterfaceDeclaration; - -struct Scope; - -struct ObjcSelector -{ - const char *stringvalue; - size_t stringlen; - size_t paramCount; - - static void _init(); - - ObjcSelector(const char *sv, size_t len, size_t pcount); - - static ObjcSelector *create(FuncDeclaration *fdecl); -}; - -struct ObjcClassDeclaration -{ - bool isMeta; - bool isExtern; - - Identifier* identifier; - ClassDeclaration* classDeclaration; - ClassDeclaration* metaclass; - Dsymbols* methodList; - - bool isRootClass() const; -}; - -class Objc -{ -public: - static void _init(); - - virtual void setObjc(ClassDeclaration* cd) = 0; - virtual void setObjc(InterfaceDeclaration*) = 0; - virtual void deprecate(InterfaceDeclaration*) const = 0; - - virtual void setSelector(FuncDeclaration*, Scope* sc) = 0; - virtual void validateSelector(FuncDeclaration* fd) = 0; - virtual void checkLinkage(FuncDeclaration* fd) = 0; - virtual bool isVirtual(const FuncDeclaration*) const = 0; - virtual ClassDeclaration* getParent(FuncDeclaration*, ClassDeclaration*) const = 0; - virtual void addToClassMethodList(FuncDeclaration*, ClassDeclaration*) const = 0; - virtual AggregateDeclaration* isThis(FuncDeclaration* fd) = 0; - virtual VarDeclaration* createSelectorParameter(FuncDeclaration*, Scope*) const = 0; - - virtual void setMetaclass(InterfaceDeclaration* id, Scope*) const = 0; - virtual void setMetaclass(ClassDeclaration* id, Scope*) const = 0; - virtual ClassDeclaration* getRuntimeMetaclass(ClassDeclaration* cd) = 0; - - virtual void addSymbols(AttribDeclaration*, ClassDeclarations*, ClassDeclarations*) const = 0; - virtual void addSymbols(ClassDeclaration*, ClassDeclarations*, ClassDeclarations*) const = 0; -}; diff --git a/src/dmd/scope.h b/src/dmd/scope.h deleted file mode 100644 index 94cb47fd83cf..000000000000 --- a/src/dmd/scope.h +++ /dev/null @@ -1,139 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/scope.h - */ - -#pragma once - -class Identifier; -class Module; -class Statement; -class SwitchStatement; -class TryFinallyStatement; -class LabelStatement; -class ForeachStatement; -class ClassDeclaration; -class AggregateDeclaration; -class FuncDeclaration; -class UserAttributeDeclaration; -struct DocComment; -struct AA; -class TemplateInstance; -class CPPNamespaceDeclaration; - -#include "dsymbol.h" - -#define CSXthis_ctor 1 // called this() -#define CSXsuper_ctor 2 // called super() -#define CSXthis 4 // referenced this -#define CSXsuper 8 // referenced super -#define CSXlabel 0x10 // seen a label -#define CSXreturn 0x20 // seen a return statement -#define CSXany_ctor 0x40 // either this() or super() was called -#define CSXhalt 0x80 // assert(0) - -// Flags that would not be inherited beyond scope nesting -#define SCOPEctor 0x0001 // constructor type -#define SCOPEcondition 0x0004 // inside static if/assert condition -#define SCOPEdebug 0x0008 // inside debug conditional - -// Flags that would be inherited beyond scope nesting -#define SCOPEnoaccesscheck 0x0002 // don't do access checks -#define SCOPEconstraint 0x0010 // inside template constraint -#define SCOPEinvariant 0x0020 // inside invariant code -#define SCOPErequire 0x0040 // inside in contract code -#define SCOPEensure 0x0060 // inside out contract code -#define SCOPEcontract 0x0060 // [mask] we're inside contract code -#define SCOPEctfe 0x0080 // inside a ctfe-only expression -#define SCOPEcompile 0x0100 // inside __traits(compile) -#define SCOPEignoresymbolvisibility 0x0200 // ignore symbol visibility (Bugzilla 15907) -#define SCOPEfullinst 0x1000 // fully instantiate templates - -#define SCOPEfree 0x8000 // is on free list - -struct Scope -{ - Scope *enclosing; // enclosing Scope - - Module *_module; // Root module - ScopeDsymbol *scopesym; // current symbol - FuncDeclaration *func; // function we are in - Dsymbol *parent; // parent to use - LabelStatement *slabel; // enclosing labelled statement - SwitchStatement *sw; // enclosing switch statement - Statement *tryBody; // enclosing _body of TryCatchStatement or TryFinallyStatement - TryFinallyStatement *tf; // enclosing try finally statement - ScopeGuardStatement *os; // enclosing scope(xxx) statement - Statement *sbreak; // enclosing statement that supports "break" - Statement *scontinue; // enclosing statement that supports "continue" - ForeachStatement *fes; // if nested function for ForeachStatement, this is it - Scope *callsc; // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__ - Dsymbol *inunion; // !=null if processing members of a union - bool nofree; // true if shouldn't free it - bool inLoop; // true if inside a loop (where constructor calls aren't allowed) - int intypeof; // in typeof(exp) - VarDeclaration *lastVar; // Previous symbol used to prevent goto-skips-init - - /* If minst && !tinst, it's in definitely non-speculative scope (eg. module member scope). - * If !minst && !tinst, it's in definitely speculative scope (eg. template constraint). - * If minst && tinst, it's in instantiated code scope without speculation. - * If !minst && tinst, it's in instantiated code scope with speculation. - */ - Module *minst; // root module where the instantiated templates should belong to - TemplateInstance *tinst; // enclosing template instance - - unsigned char callSuper; // primitive flow analysis for constructors - unsigned char *fieldinit; - size_t fieldinit_dim; - - AlignDeclaration *aligndecl; // alignment for struct members - - /// C++ namespace this symbol belongs to - CPPNamespaceDeclaration *namespace_; - - LINK linkage; // linkage for external functions - CPPMANGLE cppmangle; // C++ mangle type - PINLINE inlining; // inlining strategy for functions - - Prot protection; // protection for class members - int explicitProtection; // set if in an explicit protection attribute - - StorageClass stc; // storage class - - DeprecatedDeclaration *depdecl; // customized deprecation message - - unsigned flags; - - UserAttributeDeclaration *userAttribDecl; // user defined attributes - - DocComment *lastdc; // documentation comment for last symbol at this scope - AA *anchorCounts; // lookup duplicate anchor name count - Identifier *prevAnchor; // qualified symbol name of last doc anchor - - Scope(); - - Scope *copy(); - - Scope *push(); - Scope *push(ScopeDsymbol *ss); - Scope *pop(); - - Scope *startCTFE(); - Scope *endCTFE(); - - Module *instantiatingModule(); - - Dsymbol *search(const Loc &loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone); - - ClassDeclaration *getClassScope(); - AggregateDeclaration *getStructClassScope(); - - structalign_t alignment(); - - bool isDeprecated() const; -}; diff --git a/src/dmd/statement.h b/src/dmd/statement.h deleted file mode 100644 index 87778f457dd5..000000000000 --- a/src/dmd/statement.h +++ /dev/null @@ -1,773 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/statement.h - */ - -#pragma once - -#include "arraytypes.h" -#include "ast_node.h" -#include "dsymbol.h" -#include "visitor.h" -#include "tokens.h" - -struct Scope; -class Expression; -class LabelDsymbol; -class Identifier; -class IfStatement; -class ExpStatement; -class DefaultStatement; -class VarDeclaration; -class Condition; -class ErrorStatement; -class ReturnStatement; -class CompoundStatement; -class Parameter; -class StaticAssert; -class AsmStatement; -class GotoStatement; -class ScopeStatement; -class TryCatchStatement; -class TryFinallyStatement; -class CaseStatement; -class DefaultStatement; -class LabelStatement; -class StaticForeach; - -// Back end -struct code; - -/* How a statement exits; this is returned by blockExit() - */ -enum BE -{ - BEnone = 0, - BEfallthru = 1, - BEthrow = 2, - BEreturn = 4, - BEgoto = 8, - BEhalt = 0x10, - BEbreak = 0x20, - BEcontinue = 0x40, - BEerrthrow = 0x80, - BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt) -}; - -typedef unsigned char STMT; -enum -{ - STMTerror, - STMTpeel, - STMTexp, STMTdtorExp, - STMTcompile, - STMTcompound, STMTcompoundDeclaration, STMTcompoundAsm, - STMTunrolledLoop, - STMTscope, - STMTforwarding, - STMTwhile, - STMTdo, - STMTfor, - STMTforeach, - STMTforeachRange, - STMTif, - STMTconditional, - STMTstaticForeach, - STMTpragma, - STMTstaticAssert, - STMTswitch, - STMTcase, - STMTcaseRange, - STMTdefault, - STMTgotoDefault, - STMTgotoCase, - STMTswitchError, - STMTreturn, - STMTbreak, - STMTcontinue, - STMTsynchronized, - STMTwith, - STMTtryCatch, - STMTtryFinally, - STMTscopeGuard, - STMTthrow, - STMTdebug, - STMTgoto, - STMTlabel, - STMTasm, STMTinlineAsm, STMTgccAsm, - STMTimport -}; - -class Statement : public ASTNode -{ -public: - Loc loc; - STMT stmt; - - virtual Statement *syntaxCopy(); - - const char *toChars() const; - - void error(const char *format, ...); - void warning(const char *format, ...); - void deprecation(const char *format, ...); - virtual Statement *getRelatedLabeled() { return this; } - virtual bool hasBreak() const; - virtual bool hasContinue() const; - bool usesEH(); - bool comeFrom(); - bool hasCode(); - virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - virtual Statements *flatten(Scope *sc); - virtual Statement *last(); - - virtual ReturnStatement *endsWithReturnStatement() { return NULL; } - - ErrorStatement *isErrorStatement() { return stmt == STMTerror ? (ErrorStatement*)this : NULL; } - ScopeStatement *isScopeStatement() { return stmt == STMTscope ? (ScopeStatement*)this : NULL; } - ExpStatement *isExpStatement() { return stmt == STMTexp ? (ExpStatement*)this : NULL; } - CompoundStatement *isCompoundStatement() { return stmt == STMTcompound ? (CompoundStatement*)this : NULL; } - ReturnStatement *isReturnStatement() { return stmt == STMTreturn ? (ReturnStatement*)this : NULL; } - IfStatement *isIfStatement() { return stmt == STMTif ? (IfStatement*)this : NULL; } - CaseStatement *isCaseStatement() { return stmt == STMTcase ? (CaseStatement*)this : NULL; } - DefaultStatement *isDefaultStatement() { return stmt == STMTdefault ? (DefaultStatement*)this : NULL; } - LabelStatement *isLabelStatement() { return stmt == STMTlabel ? (LabelStatement*)this : NULL; } - GotoDefaultStatement *isGotoDefaultStatement() { return stmt == STMTgotoDefault ? (GotoDefaultStatement*)this : NULL; } - GotoCaseStatement *isGotoCaseStatement() { return stmt == STMTgotoCase ? (GotoCaseStatement*)this : NULL; } - BreakStatement *isBreakStatement() { return stmt == STMTbreak ? (BreakStatement*)this : NULL; } - DtorExpStatement *isDtorExpStatement() { return stmt == STMTdtorExp ? (DtorExpStatement*)this : NULL; } - ForwardingStatement *isForwardingStatement() { return stmt == STMTforwarding ? (ForwardingStatement*)this : NULL; } - DoStatement *isDoStatement() { return stmt == STMTdo ? (DoStatement*)this : NULL; } - ForStatement *isForStatement() { return stmt == STMTfor ? (ForStatement*)this : NULL; } - ForeachStatement *isForeachStatement() { return stmt == STMTforeach ? (ForeachStatement*)this : NULL; } - SwitchStatement *isSwitchStatement() { return stmt == STMTswitch ? (SwitchStatement*)this : NULL; } - ContinueStatement *isContinueStatement() { return stmt == STMTcontinue ? (ContinueStatement*)this : NULL; } - WithStatement *isWithStatement() { return stmt == STMTwith ? (WithStatement*)this : NULL; } - TryCatchStatement *isTryCatchStatement() { return stmt == STMTtryCatch ? (TryCatchStatement*)this : NULL; } - ThrowStatement *isThrowStatement() { return stmt == STMTthrow ? (ThrowStatement*)this : NULL; } - TryFinallyStatement *isTryFinallyStatement() { return stmt == STMTtryFinally ? (TryFinallyStatement*)this : NULL; } - SwitchErrorStatement *isSwitchErrorStatement() { return stmt == STMTswitchError ? (SwitchErrorStatement*)this : NULL; } - UnrolledLoopStatement *isUnrolledLoopStatement() { return stmt == STMTunrolledLoop ? (UnrolledLoopStatement*)this : NULL; } - ForeachRangeStatement *isForeachRangeStatement() { return stmt == STMTforeachRange ? (ForeachRangeStatement*)this : NULL; } - CompoundDeclarationStatement *isCompoundDeclarationStatement() { return stmt == STMTcompoundDeclaration ? (CompoundDeclarationStatement*)this : NULL; } - - void accept(Visitor *v) { v->visit(this); } -}; - -/** Any Statement that fails semantic() or has a component that is an ErrorExp or - * a TypeError should return an ErrorStatement from semantic(). - */ -class ErrorStatement : public Statement -{ -public: - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class PeelStatement : public Statement -{ -public: - Statement *s; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ExpStatement : public Statement -{ -public: - Expression *exp; - - static ExpStatement *create(Loc loc, Expression *exp); - Statement *syntaxCopy(); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - Statements *flatten(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class DtorExpStatement : public ExpStatement -{ -public: - /* Wraps an expression that is the destruction of 'var' - */ - - VarDeclaration *var; - - Statement *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class CompileStatement : public Statement -{ -public: - Expressions *exps; - - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class CompoundStatement : public Statement -{ -public: - Statements *statements; - - static CompoundStatement *create(Loc loc, Statement *s1, Statement *s2); - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - ReturnStatement *endsWithReturnStatement(); - Statement *last(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class CompoundDeclarationStatement : public CompoundStatement -{ -public: - Statement *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -/* The purpose of this is so that continue will go to the next - * of the statements, and break will go to the end of the statements. - */ -class UnrolledLoopStatement : public Statement -{ -public: - Statements *statements; - - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ScopeStatement : public Statement -{ -public: - Statement *statement; - Loc endloc; // location of closing curly bracket - - Statement *syntaxCopy(); - ReturnStatement *endsWithReturnStatement(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ForwardingStatement : public Statement -{ - ForwardingScopeDsymbol *sym; - Statement *statement; - - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class WhileStatement : public Statement -{ -public: - Expression *condition; - Statement *_body; - Loc endloc; // location of closing curly bracket - - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class DoStatement : public Statement -{ -public: - Statement *_body; - Expression *condition; - Loc endloc; // location of ';' after while - - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ForStatement : public Statement -{ -public: - Statement *_init; - Expression *condition; - Expression *increment; - Statement *_body; - Loc endloc; // location of closing curly bracket - - // When wrapped in try/finally clauses, this points to the outermost one, - // which may have an associated label. Internal break/continue statements - // treat that label as referring to this loop. - Statement *relatedLabeled; - - Statement *syntaxCopy(); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; } - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ForeachStatement : public Statement -{ -public: - TOK op; // TOKforeach or TOKforeach_reverse - Parameters *parameters; // array of Parameter*'s - Expression *aggr; - Statement *_body; - Loc endloc; // location of closing curly bracket - - VarDeclaration *key; - VarDeclaration *value; - - FuncDeclaration *func; // function we're lexically in - - Statements *cases; // put breaks, continues, gotos and returns here - ScopeStatements *gotos; // forward referenced goto's go here - - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ForeachRangeStatement : public Statement -{ -public: - TOK op; // TOKforeach or TOKforeach_reverse - Parameter *prm; // loop index variable - Expression *lwr; - Expression *upr; - Statement *_body; - Loc endloc; // location of closing curly bracket - - VarDeclaration *key; - - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class IfStatement : public Statement -{ -public: - Parameter *prm; - Expression *condition; - Statement *ifbody; - Statement *elsebody; - VarDeclaration *match; // for MatchExpression results - Loc endloc; // location of closing curly bracket - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ConditionalStatement : public Statement -{ -public: - Condition *condition; - Statement *ifbody; - Statement *elsebody; - - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticForeachStatement : public Statement -{ -public: - StaticForeach *sfe; - - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class PragmaStatement : public Statement -{ -public: - Identifier *ident; - Expressions *args; // array of Expression's - Statement *_body; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class StaticAssertStatement : public Statement -{ -public: - StaticAssert *sa; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class SwitchStatement : public Statement -{ -public: - Expression *condition; - Statement *_body; - bool isFinal; - - DefaultStatement *sdefault; - Statement *tryBody; // set to TryCatchStatement or TryFinallyStatement if in _body portion - TryFinallyStatement *tf; - GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's - CaseStatements *cases; // array of CaseStatement's - int hasNoDefault; // !=0 if no default statement - int hasVars; // !=0 if has variable case values - VarDeclaration *lastVar; - - Statement *syntaxCopy(); - bool hasBreak() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class CaseStatement : public Statement -{ -public: - Expression *exp; - Statement *statement; - - int index; // which case it is (since we sort this) - VarDeclaration *lastVar; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - - -class CaseRangeStatement : public Statement -{ -public: - Expression *first; - Expression *last; - Statement *statement; - - Statement *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - - -class DefaultStatement : public Statement -{ -public: - Statement *statement; - VarDeclaration *lastVar; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class GotoDefaultStatement : public Statement -{ -public: - SwitchStatement *sw; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class GotoCaseStatement : public Statement -{ -public: - Expression *exp; // NULL, or which case to goto - CaseStatement *cs; // case statement it resolves to - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class SwitchErrorStatement : public Statement -{ -public: - Expression *exp; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ReturnStatement : public Statement -{ -public: - Expression *exp; - size_t caseDim; - - Statement *syntaxCopy(); - - ReturnStatement *endsWithReturnStatement() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class BreakStatement : public Statement -{ -public: - Identifier *ident; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ContinueStatement : public Statement -{ -public: - Identifier *ident; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class SynchronizedStatement : public Statement -{ -public: - Expression *exp; - Statement *_body; - - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class WithStatement : public Statement -{ -public: - Expression *exp; - Statement *_body; - VarDeclaration *wthis; - Loc endloc; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class TryCatchStatement : public Statement -{ -public: - Statement *_body; - Catches *catches; - - Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion - - Statement *syntaxCopy(); - bool hasBreak() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class Catch : public RootObject -{ -public: - Loc loc; - Type *type; - Identifier *ident; - Statement *handler; - - VarDeclaration *var; - // set if semantic processing errors - bool errors; - - // was generated by the compiler, - // wasn't present in source code - bool internalCatch; - - Catch *syntaxCopy(); -}; - -class TryFinallyStatement : public Statement -{ -public: - Statement *_body; - Statement *finalbody; - - Statement *tryBody; // set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion - bool bodyFallsThru; // true if _body falls through to finally - - static TryFinallyStatement *create(Loc loc, Statement *body, Statement *finalbody); - Statement *syntaxCopy(); - bool hasBreak() const; - bool hasContinue() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -class ScopeGuardStatement : public Statement -{ -public: - TOK tok; - Statement *statement; - - Statement *syntaxCopy(); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ThrowStatement : public Statement -{ -public: - Expression *exp; - // was generated by the compiler, - // wasn't present in source code - bool internalThrow; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class DebugStatement : public Statement -{ -public: - Statement *statement; - - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class GotoStatement : public Statement -{ -public: - Identifier *ident; - LabelDsymbol *label; - Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion - TryFinallyStatement *tf; - ScopeGuardStatement *os; - VarDeclaration *lastVar; - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; - -class LabelStatement : public Statement -{ -public: - Identifier *ident; - Statement *statement; - Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion - TryFinallyStatement *tf; - ScopeGuardStatement *os; - VarDeclaration *lastVar; - Statement *gotoTarget; // interpret - void* extra; // used by Statement_toIR() - bool breaks; // someone did a 'break ident' - - Statement *syntaxCopy(); - Statements *flatten(Scope *sc); - Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); - - void accept(Visitor *v) { v->visit(this); } -}; - -class LabelDsymbol : public Dsymbol -{ -public: - LabelStatement *statement; - - bool deleted; // set if rewritten to return in foreach delegate - bool iasm; // set if used by inline assembler - - static LabelDsymbol *create(Identifier *ident); - LabelDsymbol *isLabel(); - void accept(Visitor *v) { v->visit(this); } -}; - -Statement* asmSemantic(AsmStatement *s, Scope *sc); - -class AsmStatement : public Statement -{ -public: - Token *tokens; - - Statement *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -class InlineAsmStatement : public AsmStatement -{ -public: - code *asmcode; - unsigned asmalign; // alignment of this statement - unsigned regs; // mask of registers modified (must match regm_t in back end) - bool refparam; // true if function parameter is referenced - bool naked; // true if function is to be naked - - Statement *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -// A GCC asm statement - assembler instructions with D expression operands -class GccAsmStatement : public AsmStatement -{ -public: - StorageClass stc; // attributes of the asm {} block - Expression *insn; // string expression that is the template for assembler code - Expressions *args; // input and output operands of the statement - unsigned outputargs; // of the operands in 'args', the number of output operands - Identifiers *names; // list of symbolic names for the operands - Expressions *constraints; // list of string constants specifying constraints on operands - Expressions *clobbers; // list of string constants specifying clobbers and scratch registers - Identifiers *labels; // list of goto labels - GotoStatements *gotos; // of the goto labels, the equivalent statements they represent - - Statement *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -// a complete asm {} block -class CompoundAsmStatement : public CompoundStatement -{ -public: - StorageClass stc; // postfix attributes like nothrow/pure/@trusted - - CompoundAsmStatement *syntaxCopy(); - Statements *flatten(Scope *sc); - - void accept(Visitor *v) { v->visit(this); } -}; - -class ImportStatement : public Statement -{ -public: - Dsymbols *imports; // Array of Import's - - Statement *syntaxCopy(); - - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/staticassert.h b/src/dmd/staticassert.h deleted file mode 100644 index e5e55aeb9746..000000000000 --- a/src/dmd/staticassert.h +++ /dev/null @@ -1,28 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/staticassert.h - */ - -#pragma once - -#include "dsymbol.h" - -class Expression; - -class StaticAssert : public Dsymbol -{ -public: - Expression *exp; - Expression *msg; - - Dsymbol *syntaxCopy(Dsymbol *s); - void addMember(Scope *sc, ScopeDsymbol *sds); - bool oneMember(Dsymbol **ps, Identifier *ident); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; diff --git a/src/dmd/target.h b/src/dmd/target.h deleted file mode 100644 index 2b04c1f60e4b..000000000000 --- a/src/dmd/target.h +++ /dev/null @@ -1,108 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 2013-2019 by The D Language Foundation, All Rights Reserved - * written by Iain Buclaw - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/target.h - */ - -#pragma once - -// This file contains a data structure that describes a back-end target. -// At present it is incomplete, but in future it should grow to contain -// most or all target machine and target O/S specific information. -#include "globals.h" -#include "tokens.h" - -class ClassDeclaration; -class Dsymbol; -class Expression; -class Parameter; -class Type; -class TypeTuple; -class TypeFunction; - -struct TargetC -{ - unsigned longsize; // size of a C 'long' or 'unsigned long' type - unsigned long_doublesize; // size of a C 'long double' - unsigned criticalSectionSize; // size of os critical section -}; - -struct TargetCPP -{ - bool reverseOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order - bool exceptions; // set if catching C++ exceptions is supported - bool twoDtorInVtable; // target C++ ABI puts deleting and non-deleting destructor into vtable - - const char *toMangle(Dsymbol *s); - const char *typeInfoMangle(ClassDeclaration *cd); - const char *typeMangle(Type *t); - Type *parameterType(Parameter *p); - bool fundamentalType(const Type *t, bool& isFundamental); -}; - -struct TargetObjC -{ - bool supported; // set if compiler can interface with Objective-C -}; - -struct Target -{ - // D ABI - unsigned ptrsize; - unsigned realsize; // size a real consumes in memory - unsigned realpad; // 'padding' added to the CPU real size to bring it up to realsize - unsigned realalignsize; // alignment for reals - unsigned classinfosize; // size of 'ClassInfo' - unsigned long long maxStaticDataSize; // maximum size of static data - - // C ABI - TargetC c; - - // C++ ABI - TargetCPP cpp; - - // Objective-C ABI - TargetObjC objc; - - template - struct FPTypeProperties - { - real_t max; - real_t min_normal; - real_t nan; - real_t infinity; - real_t epsilon; - - d_int64 dig; - d_int64 mant_dig; - d_int64 max_exp; - d_int64 min_exp; - d_int64 max_10_exp; - d_int64 min_10_exp; - }; - - FPTypeProperties FloatProperties; - FPTypeProperties DoubleProperties; - FPTypeProperties RealProperties; - - void _init(const Param& params); - // Type sizes and support. - unsigned alignsize(Type *type); - unsigned fieldalign(Type *type); - unsigned critsecsize(); - Type *va_listType(); // get type of va_list - int isVectorTypeSupported(int sz, Type *type); - bool isVectorOpSupported(Type *type, TOK op, Type *t2 = NULL); - // ABI and backend. - LINK systemLinkage(); - TypeTuple *toArgTypes(Type *t); - bool isReturnOnStack(TypeFunction *tf, bool needsThis); - d_uns64 parameterSize(const Loc& loc, Type *t); - Expression *getTargetInfo(const char* name, const Loc& loc); -}; - -extern Target target; diff --git a/src/dmd/template.h b/src/dmd/template.h deleted file mode 100644 index c0582f1d61e9..000000000000 --- a/src/dmd/template.h +++ /dev/null @@ -1,313 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/template.h - */ - -#pragma once - -#include "arraytypes.h" -#include "dsymbol.h" - -class Identifier; -class TemplateInstance; -class TemplateParameter; -class TemplateTypeParameter; -class TemplateThisParameter; -class TemplateValueParameter; -class TemplateAliasParameter; -class TemplateTupleParameter; -class Type; -class TypeQualified; -struct Scope; -class Expression; -class FuncDeclaration; -class Parameter; - -class Tuple : public RootObject -{ -public: - Objects objects; - - // kludge for template.isType() - DYNCAST dyncast() const { return DYNCAST_TUPLE; } - - const char *toChars() const { return objects.toChars(); } -}; - -struct TemplatePrevious -{ - TemplatePrevious *prev; - Scope *sc; - Objects *dedargs; -}; - -class TemplateDeclaration : public ScopeDsymbol -{ -public: - TemplateParameters *parameters; // array of TemplateParameter's - - TemplateParameters *origParameters; // originals for Ddoc - Expression *constraint; - - // Hash table to look up TemplateInstance's of this TemplateDeclaration - void *instances; - - TemplateDeclaration *overnext; // next overloaded TemplateDeclaration - TemplateDeclaration *overroot; // first in overnext list - FuncDeclaration *funcroot; // first function in unified overload list - - Dsymbol *onemember; // if !=NULL then one member of this template - - bool literal; // this template declaration is a literal - bool ismixin; // template declaration is only to be used as a mixin - bool isstatic; // this is static template declaration - Prot protection; - int inuse; // for recursive expansion detection - - TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack - - Dsymbol *syntaxCopy(Dsymbol *); - bool overloadInsert(Dsymbol *s); - bool hasStaticCtorOrDtor(); - const char *kind() const; - const char *toChars() const; - - Prot prot(); - - MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs); - RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o); - - TemplateDeclaration *isTemplateDeclaration() { return this; } - - TemplateTupleParameter *isVariadic(); - bool isOverloadable() const; - - void accept(Visitor *v) { v->visit(this); } -}; - -/* For type-parameter: - * template Foo(ident) // specType is set to NULL - * template Foo(ident : specType) - * For value-parameter: - * template Foo(valType ident) // specValue is set to NULL - * template Foo(valType ident : specValue) - * For alias-parameter: - * template Foo(alias ident) - * For this-parameter: - * template Foo(this ident) - */ -class TemplateParameter : public ASTNode -{ -public: - Loc loc; - Identifier *ident; - - /* True if this is a part of precedent parameter specialization pattern. - * - * template A(T : X!TL, alias X, TL...) {} - * // X and TL are dependent template parameter - * - * A dependent template parameter should return MATCHexact in matchArg() - * to respect the match level of the corresponding precedent parameter. - */ - bool dependent; - - virtual TemplateTypeParameter *isTemplateTypeParameter(); - virtual TemplateValueParameter *isTemplateValueParameter(); - virtual TemplateAliasParameter *isTemplateAliasParameter(); - virtual TemplateThisParameter *isTemplateThisParameter(); - virtual TemplateTupleParameter *isTemplateTupleParameter(); - - virtual TemplateParameter *syntaxCopy() = 0; - virtual bool declareParameter(Scope *sc) = 0; - virtual void print(RootObject *oarg, RootObject *oded) = 0; - virtual RootObject *specialization() = 0; - virtual RootObject *defaultArg(Loc instLoc, Scope *sc) = 0; - virtual bool hasDefaultArg() = 0; - - /* Create dummy argument based on parameter. - */ - virtual void *dummyArg() = 0; - void accept(Visitor *v) { v->visit(this); } -}; - -/* Syntax: - * ident : specType = defaultType - */ -class TemplateTypeParameter : public TemplateParameter -{ -public: - Type *specType; // type parameter: if !=NULL, this is the type specialization - Type *defaultType; - - TemplateTypeParameter *isTemplateTypeParameter(); - TemplateParameter *syntaxCopy(); - bool declareParameter(Scope *sc); - void print(RootObject *oarg, RootObject *oded); - RootObject *specialization(); - RootObject *defaultArg(Loc instLoc, Scope *sc); - bool hasDefaultArg(); - void *dummyArg(); - void accept(Visitor *v) { v->visit(this); } -}; - -/* Syntax: - * this ident : specType = defaultType - */ -class TemplateThisParameter : public TemplateTypeParameter -{ -public: - TemplateThisParameter *isTemplateThisParameter(); - TemplateParameter *syntaxCopy(); - void accept(Visitor *v) { v->visit(this); } -}; - -/* Syntax: - * valType ident : specValue = defaultValue - */ -class TemplateValueParameter : public TemplateParameter -{ -public: - Type *valType; - Expression *specValue; - Expression *defaultValue; - - TemplateValueParameter *isTemplateValueParameter(); - TemplateParameter *syntaxCopy(); - bool declareParameter(Scope *sc); - void print(RootObject *oarg, RootObject *oded); - RootObject *specialization(); - RootObject *defaultArg(Loc instLoc, Scope *sc); - bool hasDefaultArg(); - void *dummyArg(); - void accept(Visitor *v) { v->visit(this); } -}; - -/* Syntax: - * specType ident : specAlias = defaultAlias - */ -class TemplateAliasParameter : public TemplateParameter -{ -public: - Type *specType; - RootObject *specAlias; - RootObject *defaultAlias; - - TemplateAliasParameter *isTemplateAliasParameter(); - TemplateParameter *syntaxCopy(); - bool declareParameter(Scope *sc); - void print(RootObject *oarg, RootObject *oded); - RootObject *specialization(); - RootObject *defaultArg(Loc instLoc, Scope *sc); - bool hasDefaultArg(); - void *dummyArg(); - void accept(Visitor *v) { v->visit(this); } -}; - -/* Syntax: - * ident ... - */ -class TemplateTupleParameter : public TemplateParameter -{ -public: - TemplateTupleParameter *isTemplateTupleParameter(); - TemplateParameter *syntaxCopy(); - bool declareParameter(Scope *sc); - void print(RootObject *oarg, RootObject *oded); - RootObject *specialization(); - RootObject *defaultArg(Loc instLoc, Scope *sc); - bool hasDefaultArg(); - void *dummyArg(); - void accept(Visitor *v) { v->visit(this); } -}; - -/* Given: - * foo!(args) => - * name = foo - * tiargs = args - */ -class TemplateInstance : public ScopeDsymbol -{ -public: - Identifier *name; - - // Array of Types/Expressions of template - // instance arguments [int*, char, 10*10] - Objects *tiargs; - - // Array of Types/Expressions corresponding - // to TemplateDeclaration.parameters - // [int, char, 100] - Objects tdtypes; - - // Modules imported by this template instance - Modules importedModules; - - Dsymbol *tempdecl; // referenced by foo.bar.abc - Dsymbol *enclosing; // if referencing local symbols, this is the context - Dsymbol *aliasdecl; // !=NULL if instance is an alias for its sole member - TemplateInstance *inst; // refer to existing instance - ScopeDsymbol *argsym; // argument symbol table - int inuse; // for recursive expansion detection - int nest; // for recursive pretty printing detection - bool semantictiargsdone; // has semanticTiargs() been done? - bool havetempdecl; // if used second constructor - bool gagged; // if the instantiation is done with error gagging - hash_t hash; // cached result of toHash() - Expressions *fargs; // for function template, these are the function arguments - - TemplateInstances* deferred; - - Module *memberOf; // if !null, then this TemplateInstance appears in memberOf.members[] - - // Used to determine the instance needs code generation. - // Note that these are inaccurate until semantic analysis phase completed. - TemplateInstance *tinst; // enclosing template instance - TemplateInstance *tnext; // non-first instantiated instances - Module *minst; // the top module that instantiated this instance - - Dsymbol *syntaxCopy(Dsymbol *); - Dsymbol *toAlias(); // resolve real symbol - const char *kind() const; - bool oneMember(Dsymbol **ps, Identifier *ident); - const char *toChars() const; - const char* toPrettyCharsHelper(); - void printInstantiationTrace(); - Identifier *getIdent(); - hash_t toHash(); - - bool needsCodegen(); - - TemplateInstance *isTemplateInstance() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -class TemplateMixin : public TemplateInstance -{ -public: - TypeQualified *tqual; - - Dsymbol *syntaxCopy(Dsymbol *s); - const char *kind() const; - bool oneMember(Dsymbol **ps, Identifier *ident); - int apply(Dsymbol_apply_ft_t fp, void *param); - bool hasPointers(); - void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); - const char *toChars() const; - - TemplateMixin *isTemplateMixin() { return this; } - void accept(Visitor *v) { v->visit(this); } -}; - -Expression *isExpression(RootObject *o); -Dsymbol *isDsymbol(RootObject *o); -Type *isType(RootObject *o); -Tuple *isTuple(RootObject *o); -Parameter *isParameter(RootObject *o); -TemplateParameter *isTemplateParameter(RootObject *o); -bool isError(const RootObject *const o); diff --git a/src/dmd/tokens.h b/src/dmd/tokens.h deleted file mode 100644 index 71c9b7f45b27..000000000000 --- a/src/dmd/tokens.h +++ /dev/null @@ -1,235 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/tokens.h - */ - -#pragma once - -#include "root/dcompat.h" -#include "root/port.h" -#include "globals.h" - -class Identifier; - -/* Tokens: - ( ) - [ ] - { } - < > <= >= == != === !== - << >> <<= >>= >>> >>>= - + - += -= - * / % *= /= %= - & | ^ &= |= ^= - = ! ~ @ - ^^ ^^= - ++ -- - . -> : , => - ? && || - */ - -typedef unsigned char TOK; -enum -{ - TOKreserved, - - // Other - TOKlparen, TOKrparen, - TOKlbracket, TOKrbracket, - TOKlcurly, TOKrcurly, - TOKcolon, TOKneg, - TOKsemicolon, TOKdotdotdot, - TOKeof, TOKcast, - TOKnull, TOKassert, - TOKtrue, TOKfalse, - TOKarray, TOKcall, - TOKaddress, - TOKtype, TOKthrow, - TOKnew, TOKdelete, - TOKstar, TOKsymoff, - TOKvar, TOKdotvar, - TOKdotid, TOKdotti, - TOKdottype, TOKslice, - TOKarraylength, TOKversion, - TOKmodule, TOKdollar, - TOKtemplate, TOKdottd, - TOKdeclaration, TOKtypeof, - TOKpragma, TOKdsymbol, - TOKtypeid, TOKuadd, - TOKremove, - TOKnewanonclass, TOKcomment, - TOKarrayliteral, TOKassocarrayliteral, - TOKstructliteral, - TOKclassreference, - TOKthrownexception, - TOKdelegateptr, - TOKdelegatefuncptr, - -// 54 - // Operators - TOKlt, TOKgt, - TOKle, TOKge, - TOKequal, TOKnotequal, - TOKidentity, TOKnotidentity, - TOKindex, TOKis, - -// 64 - TOKshl, TOKshr, - TOKshlass, TOKshrass, - TOKushr, TOKushrass, - TOKcat, TOKcatass, TOKcatelemass, TOKcatdcharass, // ~ ~= - TOKadd, TOKmin, TOKaddass, TOKminass, - TOKmul, TOKdiv, TOKmod, - TOKmulass, TOKdivass, TOKmodass, - TOKand, TOKor, TOKxor, - TOKandass, TOKorass, TOKxorass, - TOKassign, TOKnot, TOKtilde, - TOKplusplus, TOKminusminus, TOKconstruct, TOKblit, - TOKdot, TOKarrow, TOKcomma, - TOKquestion, TOKandand, TOKoror, - TOKpreplusplus, TOKpreminusminus, - -// 105 - // Numeric literals - TOKint32v, TOKuns32v, - TOKint64v, TOKuns64v, - TOKint128v, TOKuns128v, - TOKfloat32v, TOKfloat64v, TOKfloat80v, - TOKimaginary32v, TOKimaginary64v, TOKimaginary80v, - - // Char constants - TOKcharv, TOKwcharv, TOKdcharv, - - // Leaf operators - TOKidentifier, TOKstring, TOKxstring, - TOKthis, TOKsuper, - TOKhalt, TOKtuple, - TOKerror, - - // Basic types - TOKvoid, - TOKint8, TOKuns8, - TOKint16, TOKuns16, - TOKint32, TOKuns32, - TOKint64, TOKuns64, - TOKint128, TOKuns128, - TOKfloat32, TOKfloat64, TOKfloat80, - TOKimaginary32, TOKimaginary64, TOKimaginary80, - TOKcomplex32, TOKcomplex64, TOKcomplex80, - TOKchar, TOKwchar, TOKdchar, TOKbool, - -// 152 - // Aggregates - TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport, - TOKalias, TOKoverride, TOKdelegate, TOKfunction, - TOKmixin, - - TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport, - TOKstatic, TOKfinal, TOKconst, TOKabstract, - TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy, - TOKauto, TOKpackage, TOKimmutable, - -// 182 - // Statements - TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch, - TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith, - TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally, - TOKasm, TOKforeach, TOKforeach_reverse, - TOKscope, - TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success, - -// 206 - // Contracts - TOKinvariant, - - // Testing - TOKunittest, - - // Added after 1.0 - TOKargTypes, - TOKref, - TOKmacro, - -// 211 - TOKparameters, - TOKtraits, - TOKoverloadset, - TOKpure, - TOKnothrow, - TOKgshared, - TOKline, - TOKfile, - TOKfilefullpath, - TOKmodulestring, - TOKfuncstring, - TOKprettyfunc, - TOKshared, - TOKat, - TOKpow, - TOKpowass, - TOKgoesto, - TOKvector, - TOKpound, - -// 230 - TOKinterval, - TOKvoidexp, - TOKcantexp, - TOKshowctfecontext, - - TOKobjc_class_reference, - TOKvectorarray, - - TOKMAX -}; - -#define TOKwild TOKinout - -// Token has an anonymous struct, which is not strict ISO C++. -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#endif - -struct Token -{ - Token *next; - Loc loc; - const utf8_t *ptr; // pointer to first character of this token within buffer - TOK value; - DString blockComment; // doc comment string prior to this token - DString lineComment; // doc comment for previous token - union - { - // Integers - sinteger_t intvalue; - uinteger_t unsvalue; - - // Floats - real_t floatvalue; - - struct - { utf8_t *ustring; // UTF8 string - unsigned len; - unsigned char postfix; // 'c', 'w', 'd' - }; - - Identifier *ident; - }; - - void free(); - - Token() : next(NULL) {} - int isKeyword(); - const char *toChars() const; - - static const char *toChars(unsigned char value); -}; - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif diff --git a/src/dmd/version.h b/src/dmd/version.h deleted file mode 100644 index 6e2466854291..000000000000 --- a/src/dmd/version.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved - * written by Walter Bright - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * http://www.boost.org/LICENSE_1_0.txt - * https://github.com/dlang/dmd/blob/master/src/dmd/version.h - */ - -#pragma once - -#include "dsymbol.h" - -class DebugSymbol : public Dsymbol -{ -public: - unsigned level; - - Dsymbol *syntaxCopy(Dsymbol *); - - const char *toChars() const; - void addMember(Scope *sc, ScopeDsymbol *sds); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; - -class VersionSymbol : public Dsymbol -{ -public: - unsigned level; - - Dsymbol *syntaxCopy(Dsymbol *); - - const char *toChars() const; - void addMember(Scope *sc, ScopeDsymbol *sds); - const char *kind() const; - void accept(Visitor *v) { v->visit(this); } -}; From 2f3cdf7918bf758042d88f1f732e2e3955f83786 Mon Sep 17 00:00:00 2001 From: Nicholas Lindsay Wilson Date: Sun, 18 Nov 2018 13:54:44 +0800 Subject: [PATCH 04/44] Improve dtoh Factor out compiler specific parts Attempt to make cross platform --- src/dmd/dtoh.d | 2135 ++++++++++++++++++++++++++---------------------- src/posix.mak | 16 - 2 files changed, 1180 insertions(+), 971 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 1eaf4ddea043..a9cafc0fb8e5 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -1,11 +1,14 @@ -// Compiler implementation of the D programming language -// Copyright (c) 1999-2015 by Digital Mars -// All Rights Reserved -// written by Walter Bright -// http://www.digitalmars.com -// Distributed under the Boost Software License, Version 1.0. -// http://www.boost.org/LICENSE_1_0.txt - +/** + * Compiler implementation of the + * $(LINK2 http://www.dlang.org, D programming language). + * + * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved + * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtohd, _dtoh.d) + * Documentation: https://dlang.org/phobos/dmd_dtoh.html + * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dtoh.d + */ module dmd.dtoh; import core.stdc.stdio; @@ -16,643 +19,947 @@ import dmd.astcodegen; import dmd.arraytypes; import dmd.globals; import dmd.identifier; +import dmd.json; +import dmd.mars; +import dmd.root.array; +import dmd.root.file; +import dmd.root.filename; +import dmd.root.rmem; import dmd.visitor; import dmd.root.outbuffer; - -immutable string[] frontendSources = [ - "access.d", "aggregate.d", "aliasthis.d", "apply.d", "argtypes.d", "arrayop.d", "arraytypes.d", "attrib.d", - "blockexit.d", "builtin.d", - "canthrow.d", "clone.d", "compiler.d", "complex.d", "cond.d", "console.d", "constfold.d", "cppmangle.d", "cppmanglewin.d", "ctfeexpr.d", "ctorflow.d", - "dcast.d", "dclass.d", "declaration.d", "delegatize.d", "denum.d", "dimport.d", "dinterpret.d", - "dmacro.d", "dmangle.d", "dmodule.d", "doc.d", "dscope.d", "dstruct.d", "dsymbol.d", "dsymbolsem.d", "dtemplate.d", "dversion.d", - "entity.d", "errors.d", "escape.d", "expression.d", "expressionsem.d", - "func.d", - "globals.d", "gluelayer.d", - "hdrgen.d", - "iasm.d", "id.d", "identifier.d", "impcnvtab.d", "imphint.d", "init.d", "initsem.d", "inline.d", "inlinecost.d", "intrange.d", - "json.d", - "lambdacomp.d", "lexer.d", - "mtype.d", - "nogc.d", "nspace.d", - "objc.d", "opover.d", "optimize.d", - "parse.d", "printast.d", - "safe.d", "sapply.d", "semantic2.d", "semantic3.d", "sideeffect.d", "statement.d", - "statementsem.d", "staticassert.d", "staticcond.d", - "target.d", "templateparamsem.d", "tokens.d", "traits.d", "typesem.d", "typinf.d", - "utf.d", "utils.d", -]; - -private bool isIdentifierClass(ASTCodegen.ClassDeclaration cd) +version(BUILD_COMPILER) { - return (cd.ident == Identifier.idPool("Identifier") && - cd.parent !is null && - cd.parent.ident == Identifier.idPool("identifier") && - cd.parent.parent && cd.parent.parent.ident == Identifier.idPool("dmd") && - !cd.parent.parent.parent); + immutable string[] sources = [ + "access.d", "aggregate.d", "aliasthis.d", "apply.d", "argtypes.d", "arrayop.d", "arraytypes.d", "attrib.d", + "blockexit.d", "builtin.d", + "canthrow.d", "clone.d", "compiler.d", "complex.d", "cond.d", "console.d", "constfold.d", "cppmangle.d", "cppmanglewin.d", "ctfeexpr.d", "ctorflow.d", + "dcast.d", "dclass.d", "declaration.d", "delegatize.d", "denum.d", "dimport.d", "dinterpret.d", + "dmacro.d", "dmangle.d", "dmodule.d", "doc.d", "dscope.d", "dstruct.d", "dsymbol.d", "dsymbolsem.d", "dtemplate.d", "dversion.d", + "entity.d", "errors.d", "escape.d", "expression.d", "expressionsem.d", + "func.d", + "globals.d", "gluelayer.d", + "hdrgen.d", + "iasm.d", "id.d", "identifier.d", "impcnvtab.d", "imphint.d", "init.d", "initsem.d", "inline.d", "inlinecost.d", "intrange.d", + "json.d", + "lambdacomp.d", "lexer.d", + "mtype.d", + "nogc.d", "nspace.d", + "objc.d", "opover.d", "optimize.d", + "parse.d", "printast.d", + "safe.d", "sapply.d", "semantic2.d", "semantic3.d", "sideeffect.d", "statement.d", + "statementsem.d", "staticassert.d", "staticcond.d", + "target.d", "templateparamsem.d", "tokens.d", "traits.d", "typesem.d", "typinf.d", + "utf.d", "utils.d", + ]; } -private bool isVisitorClass(ASTCodegen.ClassDeclaration cd) +int main(string[] args) { - for (auto cdb = cd; cdb; cdb = cdb.baseClass) + import std.algorithm.sorting : sort; + import std.array : array; + import std.file : readText; + import std.path : baseName, buildPath, dirName; + import std.string : toStringz; + + import dmd.dsymbolsem; + import dmd.errors; + import dmd.id; + import dmd.dinifile; + import dmd.parse; + + import dmd.semantic2; + import dmd.semantic3; + import dmd.builtin : builtin_init; + import dmd.dmodule : Module; + import dmd.expression : Expression; + import dmd.frontend; + import dmd.objc : Objc; + import dmd.root.response; + import dmd.root.stringtable; + import dmd.target : Target; + + import core.memory; + import core.stdc.stdio : printf; + + GC.disable(); + initDMD(); + + Strings arguments = Strings(args.length); + for (size_t i = 0; i < args.length; i++) { - if (cdb.ident == Identifier.idPool("Visitor") || - cdb.ident == Identifier.idPool("ParseTimeVisitor")) - return true; + arguments[i] = args[i].ptr; } - return false; -} - -private bool isFrontendModule(ASTCodegen.Module m) -{ - if (!m || !m.parent) - return false; + if (response_expand(&arguments)) // expand response files + error(Loc.initial, "can't open response file"); + auto files = Strings(arguments.dim - 1); + global.params.argv0 = args[0]; + + + global.inifilename = parse_conf_arg(&arguments); + if (global.inifilename) + { + // can be empty as in -conf= + if (strlen(global.inifilename) && !FileName.exists(global.inifilename)) + error(Loc.initial, "Config file '%s' does not exist.", global.inifilename); + } + else + { + version (Windows) + { + global.inifilename = findConfFile(global.params.argv0, "sc.ini").ptr; + } + else version (Posix) + { + global.inifilename = findConfFile(global.params.argv0, "dmd.conf").ptr; + } + else + { + static assert(0, "fix this"); + } + } + // Read the configurarion file + auto inifile = File(global.inifilename); + inifile.read(); + /* Need path of configuration file, for use in expanding @P macro + */ + const(char)* inifilepath = FileName.path(global.inifilename); + Strings sections; + StringTable environment; + environment._init(7); + /* Read the [Environment] section, so we can later + * pick up any DFLAGS settings. + */ + sections.push("Environment"); + parseConfFile(&environment, global.inifilename, inifilepath, inifile.len, inifile.buffer, §ions); + + const(char)* arch = global.params.is64bit ? "64" : "32"; // use default + arch = parse_arch_arg(&arguments, arch); + + // parse architecture from DFLAGS read from [Environment] section + { + Strings dflags; + getenv_setargv(readFromEnv(&environment, "DFLAGS"), &dflags); + environment.reset(7); // erase cached environment updates + arch = parse_arch_arg(&dflags, arch); + } + + bool is64bit = arch[0] == '6'; + + version(Windows) // delete LIB entry in [Environment] (necessary for optlink) to allow inheriting environment for MS-COFF + if (is64bit || strcmp(arch, "32mscoff") == 0) + environment.update("LIB", 3).ptrvalue = null; + + // read from DFLAGS in [Environment{arch}] section + char[80] envsection = void; + sprintf(envsection.ptr, "Environment%s", arch); + sections.push(envsection.ptr); + parseConfFile(&environment, global.inifilename, inifilepath, inifile.len, inifile.buffer, §ions); + getenv_setargv(readFromEnv(&environment, "DFLAGS"), &arguments); + updateRealEnvironment(&environment); + environment.reset(1); // don't need environment cache any more + + if (parseCommandLine(arguments, args.length, global.params, files)) + { + Loc loc; + errorSupplemental(loc, "run 'dmd -man' to open browser on manual"); + return 1; + } + - // Ignore dmd.root - if (m.parent.ident == Identifier.idPool("root") && - m.parent.parent && m.parent.parent.ident == Identifier.idPool("dmd") && - !m.parent.parent.parent) + version(BUILD_COMPILER) { - return false; + global.path.push(druntimeFullPath.toStringz()); + //TODO: fixme for LDC + global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../").toStringz()); + global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../res/").toStringz()); + } + + DMDType._init(); + version(BUILD_COMPILER) + { + DMDModule._init(); + DMDClass._init(); } - // Ignore dmd.visitor and derivatives - if ((m.ident == Identifier.idPool("visitor") || - m.ident == Identifier.idPool("parsetimevisitor") || - m.ident == Identifier.idPool("permissivevisitor") || - m.ident == Identifier.idPool("strictvisitor") || - m.ident == Identifier.idPool("transitivevisitor")) && - m.parent && m.parent.ident == Identifier.idPool("dmd") && - !m.parent.parent) + setVersions(); + + Modules modules; + + string path = __FILE_FULL_PATH__.dirName.buildPath("../dmd/"); + version (BUILD_COMPILER) + auto srcs = sources; + else + auto srcs = args [1 .. $]; + foreach (f; srcs) { - return false; + string fn = buildPath(path, f); + + auto id = Identifier.idPool(baseName(fn, ".d")); + auto m = new Module(fn.toStringz(), id, false, false); + auto input = readText(fn); + + if (!Module.rootModule) + Module.rootModule = m; + + m.importedFrom = m; + m.srcfile.setbuffer(cast(void*)input.ptr, input.length); + m.srcfile._ref = 1; + m.parse(); + modules.push(m); } + + foreach (m; modules) + m.importAll(null); + foreach (m; modules) + m.dsymbolSemantic(null); + + Module.dprogress = 1; + Module.runDeferredSemantic(); + + foreach (m; modules) + m.semantic2(null); + Module.runDeferredSemantic2(); - return ((m.parent.ident == Identifier.idPool("dmd") && !m.parent.parent) || - (m.parent.parent.ident == Identifier.idPool("dmd") && !m.parent.parent.parent)); + foreach (m; modules) + m.semantic3(null); + Module.runDeferredSemantic3(); + + OutBuffer buf; + genCppFiles(&buf, &modules); + + printf("%s\n", buf.peekString()); + return 0; } -/**************************************************** - */ -void genCppFiles(OutBuffer* buf, Modules *ms) +void setVersions() { - import dmd.tokens; - - extern(C++) final class ToCppBuffer(AST) : Visitor - { - alias visit = super.visit; - public: - bool[void*] visited; - bool[void*] forwarded; - OutBuffer *fwdbuf; - OutBuffer *checkbuf; - OutBuffer *donebuf; - OutBuffer *buf; - AST.AggregateDeclaration adparent; - AST.ClassDeclaration cdparent; - AST.TemplateDeclaration tdparent; - Identifier ident; - LINK linkage = LINK.d; + import dmd.cond : VersionCondition; + version(BUILD_COMPILER) + { + VersionCondition.addPredefinedGlobalIdent("NoBackend"); + VersionCondition.addPredefinedGlobalIdent("NoMain"); + } +} - this(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf) +struct DMDType +{ + static Identifier c_long; + static Identifier c_ulong; + static Identifier c_longlong; + static Identifier c_ulonglong; + static Identifier c_long_double; + version(BUILD_COMPILER) + { + static Identifier AssocArray; + static Identifier Array; + } + static void _init() + { + c_long = Identifier.idPool("__c_long"); + c_ulong = Identifier.idPool("__c_ulong"); + c_longlong = Identifier.idPool("__c_longlong"); + c_ulonglong = Identifier.idPool("__c_ulonglong"); + c_long_double = Identifier.idPool("__c_long_double"); + version(BUILD_COMPILER) { - this.checkbuf = checkbuf; - this.fwdbuf = fwdbuf; - this.donebuf = donebuf; - this.buf = buf; + AssocArray = Identifier.idPool("AssocArray"); + Array = Identifier.idPool("Array"); } - private void indent() + } +} +version(BUILD_COMPILER) +{ + struct DMDModule + { + static Identifier identifier; + static Identifier root; + static Identifier visitor; + static Identifier parsetimevisitor; + static Identifier permissivevisitor; + static Identifier strictvisitor; + static Identifier transitivevisitor; + static Identifier dmd; + static void _init() { - if (adparent) - buf.writestring(" "); + identifier = Identifier.idPool("identifier"); + root = Identifier.idPool("root"); + visitor = Identifier.idPool("visitor"); + parsetimevisitor = Identifier.idPool("parsetimevisitor"); + permissivevisitor = Identifier.idPool("permissivevisitor"); + strictvisitor = Identifier.idPool("strictvisitor"); + transitivevisitor = Identifier.idPool("transitivevisitor"); + dmd = Identifier.idPool("dmd"); } - - override void visit(AST.Dsymbol s) + } + struct DMDClass + { + static Identifier ID; ////Identifier + static Identifier Visitor; + static Identifier ParseTimeVisitor; + static void _init() { - if (s.getModule() && s.getModule().isFrontendModule()) - { - indent(); - buf.printf("// ignored %s %s\n", s.kind(), s.toPrettyChars()); - } + ID = Identifier.idPool("Identifier"); + Visitor = Identifier.idPool("Visitor"); + ParseTimeVisitor = Identifier.idPool("ParseTimeVisitor"); } - - override void visit(AST.Import) + + } + + private bool isIdentifierClass(ASTCodegen.ClassDeclaration cd) + { + return (cd.ident == DMDClass.ID && + cd.parent !is null && + cd.parent.ident == DMDModule.identifier && + cd.parent.parent && cd.parent.parent.ident == DMDModule.dmd && + !cd.parent.parent.parent); + } + + private bool isVisitorClass(ASTCodegen.ClassDeclaration cd) + { + for (auto cdb = cd; cdb; cdb = cdb.baseClass) { + if (cdb.ident == DMClass.Visitor || + cdb.ident == DMClass.ParseTimeVisitor) + return true; } - - override void visit(AST.AttribDeclaration pd) + return false; + } + + private bool isFrontendModule(ASTCodegen.Module m) + { + if (!m || !m.parent) + return false; + + // Ignore dmd.root + if (m.parent.ident == DMDModule.root && + m.parent.parent && m.parent.parent.ident == DMDModule.dmd && + !m.parent.parent.parent) { - Dsymbols* decl = pd.include(null); - if (decl) - { - foreach (s; *decl) - { - if (!adparent && s.prot().kind < AST.Prot.Kind.public_) - continue; - s.accept(this); - } - } + return false; } + + // Ignore dmd.visitor and derivatives + if ((m.ident == DMDModule.visitor || + m.ident == DMDModule.parsetimevisitor || + m.ident == DMDModule.permissivevisitor || + m.ident == DMDModule.strictvisitor || + m.ident == DMDModule.transitivevisitor) && + m.parent && m.parent.ident == DMDModule.dmd && + !m.parent.parent) + { + return false; + } + + return ((m.parent.ident == DMDModule.dmd && !m.parent.parent) || + (m.parent.parent.ident == DMDModule.dmd && !m.parent.parent.parent)); + } + + string druntimeFullPath() + { + version (IN_LLVM) + string path = "../runtime/druntime/src"; + else + string path = "../../../druntime/src/"; + + return __FILE_FULL_PATH__.dirName.buildPath(path); + } +} - override void visit(AST.LinkDeclaration ld) +/**************************************************** + */ +extern(C++) final class ToCppBuffer(AST) : Visitor +{ + alias visit = Visitor.visit; +public: + bool[void*] visited; + bool[void*] forwarded; + OutBuffer *fwdbuf; + OutBuffer *checkbuf; + OutBuffer *donebuf; + OutBuffer *buf; + AST.AggregateDeclaration adparent; + AST.ClassDeclaration cdparent; + AST.TemplateDeclaration tdparent; + Identifier ident; + LINK linkage = LINK.d; + + this(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf) + { + this.checkbuf = checkbuf; + this.fwdbuf = fwdbuf; + this.donebuf = donebuf; + this.buf = buf; + } + + private void indent() + { + if (adparent) + buf.writestring(" "); + } + + override void visit(AST.Dsymbol s) + { + version(BUILD_COMPILER) { - auto save = linkage; - linkage = ld.linkage; - if (ld.linkage != LINK.c && ld.linkage != LINK.cpp) + if (s.getModule() && s.getModule().isFrontendModule()) { indent(); - buf.printf("// ignoring %s block because of linkage\n", ld.toPrettyChars()); + buf.printf("// ignored %s %s\n", s.kind(), s.toPrettyChars()); } - else - visit(cast(AST.AttribDeclaration)ld); - linkage = save; } - - override void visit(AST.Module m) + + } + + override void visit(AST.Import) + { + } + + override void visit(AST.AttribDeclaration pd) + { + Dsymbols* decl = pd.include(null); + if (decl) { - foreach (s; *m.members) + foreach (s; *decl) { - if (s.prot().kind < AST.Prot.Kind.public_) + if (!adparent && s.prot().kind < AST.Prot.Kind.public_) continue; s.accept(this); } } - - override void visit(AST.FuncDeclaration fd) + } + + override void visit(AST.LinkDeclaration ld) + { + auto save = linkage; + linkage = ld.linkage; + if (ld.linkage != LINK.c && ld.linkage != LINK.cpp) + { + indent(); + buf.printf("// ignoring %s block because of linkage\n", ld.toPrettyChars()); + } + else + visit(cast(AST.AttribDeclaration)ld); + linkage = save; + } + + override void visit(AST.Module m) + { + foreach (s; *m.members) + { + if (s.prot().kind < AST.Prot.Kind.public_) + continue; + s.accept(this); + } + } + + override void visit(AST.FuncDeclaration fd) + { + if (cast(void*)fd in visited) + return; + version(BUILD_COMPILER) { - if (cast(void*)fd in visited) - return; if (fd.getModule() && !fd.getModule().isFrontendModule()) + return; + } + + // printf("FuncDeclaration %s %s\n", fd.toPrettyChars(), fd.type.toChars()); + visited[cast(void*)fd] = true; + + auto tf = cast(AST.TypeFunction)fd.type; + indent(); + if (!tf || !tf.deco) + { + buf.printf("// ignoring function %s because semantic hasn't been run\n", fd.toPrettyChars()); + return; + } + if (tf.linkage != LINK.c && tf.linkage != LINK.cpp) + { + buf.printf("// ignoring function %s because of linkage\n", fd.toPrettyChars()); + return; + } + if (!adparent && !fd.fbody) + { + buf.printf("// ignoring function %s because it's extern\n", fd.toPrettyChars()); + return; + } + + if (tf.linkage == LINK.c) + buf.writestring("extern \"C\" "); + else if (!adparent) + buf.writestring("extern "); + if (adparent && fd.isStatic()) + buf.writestring("static "); + if (adparent && fd.vtblIndex != -1) + { + if (!fd.isOverride()) + buf.writestring("virtual "); + + auto s = adparent.search(Loc.initial, fd.ident); + if (!(adparent.storage_class & AST.STC.abstract_) && + !(cast(AST.ClassDeclaration)adparent).isAbstract() && + s is fd && !fd.overnext) + { + auto save = buf; + buf = checkbuf; + buf.writestring(" assert(getSlotNumber<"); + buf.writestring(adparent.ident.toChars()); + buf.writestring(">(0, &"); + buf.writestring(adparent.ident.toChars()); + buf.writestring("::"); + buf.writestring(fd.ident.toChars()); + buf.printf(") == %d);\n", fd.vtblIndex); + buf = save; + } + } + funcToBuffer(tf, fd.ident); + if (adparent && tf.isConst()) + buf.writestring(" const"); + if (adparent && fd.isAbstract()) + buf.writestring(" = 0"); + buf.printf(";\n"); + if (!adparent) + buf.printf("\n"); + } + + override void visit(AST.UnitTestDeclaration fd) + { + } + + override void visit(AST.VarDeclaration vd) + { + if (cast(void*)vd in visited) + return; + version(BUILD_COMPILER) + { + if (vd.getModule() && !vd.getModule().isFrontendModule()) return; - // printf("FuncDeclaration %s %s\n", fd.toPrettyChars(), fd.type.toChars()); - visited[cast(void*)fd] = true; - - auto tf = cast(AST.TypeFunction)fd.type; + } + + visited[cast(void*)vd] = true; + + if (vd.storage_class & AST.STC.manifest && + vd.type.isintegral() && + vd._init && vd._init.isExpInitializer()) + { indent(); - if (!tf || !tf.deco) + buf.writestring("#define "); + buf.writestring(vd.ident.toChars()); + buf.writestring(" "); + auto e = AST.initializerToExpression(vd._init); + if (e.type.ty == AST.Tbool) + buf.printf("%d", e.toInteger()); + else + AST.initializerToExpression(vd._init).accept(this); + buf.writestring("\n"); + if (!adparent) + buf.printf("\n"); + return; + } + + if (tdparent && vd.type && !vd.type.deco) + { + indent(); + if (linkage != LINK.c && linkage != LINK.cpp) { - buf.printf("// ignoring function %s because semantic hasn't been run\n", fd.toPrettyChars()); + buf.printf("// ignoring variable %s because of linkage\n", vd.toPrettyChars()); return; } - if (tf.linkage != LINK.c && tf.linkage != LINK.cpp) + typeToBuffer(vd.type, vd.ident); + buf.writestring(";\n"); + return; + } + + if (vd.storage_class & (AST.STC.static_ | AST.STC.extern_ | AST.STC.tls | AST.STC.gshared) || + vd.parent && vd.parent.isModule()) + { + indent(); + if (vd.linkage != LINK.c && vd.linkage != LINK.cpp) { - buf.printf("// ignoring function %s because of linkage\n", fd.toPrettyChars()); + buf.printf("// ignoring variable %s because of linkage\n", vd.toPrettyChars()); return; } - if (!adparent && !fd.fbody) + if (vd.storage_class & AST.STC.tls) { - buf.printf("// ignoring function %s because it's extern\n", fd.toPrettyChars()); + buf.printf("// ignoring variable %s because of thread-local storage\n", vd.toPrettyChars()); return; } - - if (tf.linkage == LINK.c) + if (vd.linkage == LINK.c) buf.writestring("extern \"C\" "); else if (!adparent) buf.writestring("extern "); - if (adparent && fd.isStatic()) + if (adparent) buf.writestring("static "); - if (adparent && fd.vtblIndex != -1) - { - if (!fd.isOverride()) - buf.writestring("virtual "); - - auto s = adparent.search(Loc.initial, fd.ident); - if (!(adparent.storage_class & AST.STC.abstract_) && - !(cast(AST.ClassDeclaration)adparent).isAbstract() && - s is fd && !fd.overnext) - { - auto save = buf; - buf = checkbuf; - buf.writestring(" assert(getSlotNumber<"); - buf.writestring(adparent.ident.toChars()); - buf.writestring(">(0, &"); - buf.writestring(adparent.ident.toChars()); - buf.writestring("::"); - buf.writestring(fd.ident.toChars()); - buf.printf(") == %d);\n", fd.vtblIndex); - buf = save; - } - } - funcToBuffer(tf, fd.ident); - if (adparent && tf.isConst()) - buf.writestring(" const"); - if (adparent && fd.isAbstract()) - buf.writestring(" = 0"); - buf.printf(";\n"); + typeToBuffer(vd.type, vd.ident); + buf.writestring(";\n"); if (!adparent) buf.printf("\n"); + return; } - - override void visit(AST.UnitTestDeclaration fd) - { - } - - override void visit(AST.VarDeclaration vd) + + if (adparent && vd.type && vd.type.deco) { - if (cast(void*)vd in visited) - return; - if (vd.getModule() && !vd.getModule().isFrontendModule()) - return; - visited[cast(void*)vd] = true; - - if (vd.storage_class & AST.STC.manifest && - vd.type.isintegral() && - vd._init && vd._init.isExpInitializer()) - { - indent(); - buf.writestring("#define "); - buf.writestring(vd.ident.toChars()); - buf.writestring(" "); - auto e = AST.initializerToExpression(vd._init); - if (e.type.ty == AST.Tbool) - buf.printf("%d", e.toInteger()); - else - AST.initializerToExpression(vd._init).accept(this); - buf.writestring("\n"); - if (!adparent) - buf.printf("\n"); - return; - } - - if (tdparent && vd.type && !vd.type.deco) - { - indent(); - if (linkage != LINK.c && linkage != LINK.cpp) - { - buf.printf("// ignoring variable %s because of linkage\n", vd.toPrettyChars()); - return; - } - typeToBuffer(vd.type, vd.ident); - buf.writestring(";\n"); - return; - } - - if (vd.storage_class & (AST.STC.static_ | AST.STC.extern_ | AST.STC.tls | AST.STC.gshared) || - vd.parent && vd.parent.isModule()) - { - indent(); - if (vd.linkage != LINK.c && vd.linkage != LINK.cpp) - { - buf.printf("// ignoring variable %s because of linkage\n", vd.toPrettyChars()); - return; - } - if (vd.storage_class & AST.STC.tls) - { - buf.printf("// ignoring variable %s because of thread-local storage\n", vd.toPrettyChars()); - return; - } - if (vd.linkage == LINK.c) - buf.writestring("extern \"C\" "); - else if (!adparent) - buf.writestring("extern "); - if (adparent) - buf.writestring("static "); - typeToBuffer(vd.type, vd.ident); - buf.writestring(";\n"); - if (!adparent) - buf.printf("\n"); - return; - } - - if (adparent && vd.type && vd.type.deco) + indent(); + auto save = cdparent; + cdparent = vd.isField() ? adparent.isClassDeclaration() : null; + typeToBuffer(vd.type, vd.ident); + cdparent = save; + buf.writestring(";\n"); + if (vd.type.ty == AST.Tstruct) { - indent(); - auto save = cdparent; - cdparent = vd.isField() ? adparent.isClassDeclaration() : null; - typeToBuffer(vd.type, vd.ident); - cdparent = save; - buf.writestring(";\n"); - if (vd.type.ty == AST.Tstruct) - { - auto t = cast(AST.TypeStruct)vd.type; - includeSymbol(t.sym); - } - auto savex = buf; - buf = checkbuf; - buf.writestring(" assert(offsetof("); - buf.writestring(adparent.ident.toChars()); - buf.writestring(", "); - buf.writestring(vd.ident.toChars()); - buf.printf(") == %d);\n", vd.offset); - buf = savex; - return; + auto t = cast(AST.TypeStruct)vd.type; + includeSymbol(t.sym); } - - visit(cast(AST.Dsymbol)vd); + auto savex = buf; + buf = checkbuf; + buf.writestring(" assert(offsetof("); + buf.writestring(adparent.ident.toChars()); + buf.writestring(", "); + buf.writestring(vd.ident.toChars()); + buf.printf(") == %d);\n", vd.offset); + buf = savex; + return; } - - override void visit(AST.TypeInfoDeclaration) + + visit(cast(AST.Dsymbol)vd); + } + + override void visit(AST.TypeInfoDeclaration) + { + } + + override void visit(AST.AliasDeclaration ad) + { + version(BUILD_COMPILER) { + if (ad.getModule() && !ad.getModule().isFrontendModule()) + return; } - - override void visit(AST.AliasDeclaration ad) + + if (auto t = ad.type) { - if (ad.getModule() && !ad.getModule().isFrontendModule()) - return; - if (auto t = ad.type) + if (t.ty == AST.Tdelegate) { - if (t.ty == AST.Tdelegate) - { - visit(cast(AST.Dsymbol)ad); - return; - } - buf.writestring("typedef "); - typeToBuffer(t, ad.ident); - buf.writestring(";\n"); - if (!adparent) - buf.printf("\n"); + visit(cast(AST.Dsymbol)ad); return; } - if (!ad.aliassym) - { - ad.print(); - assert(0); - } - if (auto ti = ad.aliassym.isTemplateInstance()) - { - visitTi(ti); - return; - } - if (auto sd = ad.aliassym.isStructDeclaration()) - { - buf.writestring("typedef "); - sd.type.accept(this); - buf.writestring(" "); - buf.writestring(ad.ident.toChars()); - buf.writestring(";\n"); - if (!adparent) - buf.printf("\n"); - return; - } - indent(); - buf.printf("// ignored %s %s\n", ad.aliassym.kind(), ad.aliassym.toPrettyChars()); + buf.writestring("typedef "); + typeToBuffer(t, ad.ident); + buf.writestring(";\n"); + if (!adparent) + buf.printf("\n"); + return; } - - override void visit(AST.AnonDeclaration ad) + if (!ad.aliassym) { - buf.writestring(ad.isunion ? "union" : "struct"); - buf.writestring("\n{\n"); - foreach (s; *ad.decl) - { - s.accept(this); - } - buf.writestring("};\n"); + //ad.print(); + assert(0); } - - private bool memberField(AST.VarDeclaration vd) - { - if (!vd.type || !vd.type.deco || !vd.ident) - return false; - if (!vd.isField()) - return false; - if (vd.type.ty == AST.Tfunction) - return false; - if (vd.type.ty == AST.Tsarray) - return false; - return true; + if (auto ti = ad.aliassym.isTemplateInstance()) + { + visitTi(ti); + return; } - - override void visit(AST.StructDeclaration sd) + if (auto sd = ad.aliassym.isStructDeclaration()) + { + buf.writestring("typedef "); + sd.type.accept(this); + buf.writestring(" "); + buf.writestring(ad.ident.toChars()); + buf.writestring(";\n"); + if (!adparent) + buf.printf("\n"); + return; + } + indent(); + buf.printf("// ignored %s %s\n", ad.aliassym.kind(), ad.aliassym.toPrettyChars()); + } + + override void visit(AST.AnonDeclaration ad) + { + buf.writestring(ad.isunion ? "union" : "struct"); + buf.writestring("\n{\n"); + foreach (s; *ad.decl) + { + s.accept(this); + } + buf.writestring("};\n"); + } + + private bool memberField(AST.VarDeclaration vd) + { + if (!vd.type || !vd.type.deco || !vd.ident) + return false; + if (!vd.isField()) + return false; + if (vd.type.ty == AST.Tfunction) + return false; + if (vd.type.ty == AST.Tsarray) + return false; + return true; + } + + override void visit(AST.StructDeclaration sd) + { + if (sd.isInstantiated()) + return; + if (cast(void*)sd in visited) + return; + if (!sd.type || !sd.type.deco) + return; + version(BUILD_COMPILER) { - if (sd.isInstantiated()) - return; - if (cast(void*)sd in visited) - return; - if (!sd.type || !sd.type.deco) - return; if (sd.getModule() && !sd.getModule().isFrontendModule()) - return; - visited[cast(void*)sd] = true; - - if (sd.alignment == 1) - buf.writestring("#pragma pack(push, 1)\n"); - buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); - buf.writestring(sd.ident.toChars()); - if (sd.members) + return; + } + + visited[cast(void*)sd] = true; + + if (sd.alignment == 1) + buf.writestring("#pragma pack(push, 1)\n"); + buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); + buf.writestring(sd.ident.toChars()); + if (sd.members) + { + buf.writestring("\n{\n"); + auto save = adparent; + adparent = sd; + foreach (m; *sd.members) { - buf.writestring("\n{\n"); - auto save = adparent; - adparent = sd; - foreach (m; *sd.members) + m.accept(this); + } + adparent = save; + // Generate default ctor + buf.printf(" %s(", sd.ident.toChars()); + buf.printf(") {"); + size_t varCount; + foreach (m; *sd.members) + { + if (auto vd = m.isVarDeclaration()) { - m.accept(this); + if (!memberField(vd)) + continue; + varCount++; + if (!vd._init && !vd.type.isTypeBasic()) + continue; + buf.printf(" this->%s = ", vd.ident.toChars()); + if (vd._init) + AST.initializerToExpression(vd._init).accept(this); + else if (vd.type.isTypeBasic()) + vd.type.defaultInitLiteral(Loc.initial).accept(this); + buf.printf(";"); } - adparent = save; - // Generate default ctor + } + buf.printf(" }\n"); + + if (varCount) + { buf.printf(" %s(", sd.ident.toChars()); - buf.printf(") {"); - size_t varCount; + bool first = true; foreach (m; *sd.members) { if (auto vd = m.isVarDeclaration()) { if (!memberField(vd)) continue; - varCount++; - if (!vd._init && !vd.type.isTypeBasic()) - continue; - buf.printf(" this->%s = ", vd.ident.toChars()); - if (vd._init) - AST.initializerToExpression(vd._init).accept(this); - else if (vd.type.isTypeBasic()) - vd.type.defaultInitLiteral(Loc.initial).accept(this); - buf.printf(";"); + if (first) + first = false; + else + buf.writestring(", "); + assert(vd.type); + assert(vd.ident); + typeToBuffer(vd.type, vd.ident); } } - buf.printf(" }\n"); - - if (varCount) + buf.printf(") {"); + foreach (m; *sd.members) { - buf.printf(" %s(", sd.ident.toChars()); - bool first = true; - foreach (m; *sd.members) - { - if (auto vd = m.isVarDeclaration()) - { - if (!memberField(vd)) - continue; - if (first) - first = false; - else - buf.writestring(", "); - assert(vd.type); - assert(vd.ident); - typeToBuffer(vd.type, vd.ident); - } - } - buf.printf(") {"); - foreach (m; *sd.members) + if (auto vd = m.isVarDeclaration()) { - if (auto vd = m.isVarDeclaration()) - { - if (!memberField(vd)) - continue; - buf.printf(" this->%s = %s;", vd.ident.toChars(), vd.ident.toChars()); - } + if (!memberField(vd)) + continue; + buf.printf(" this->%s = %s;", vd.ident.toChars(), vd.ident.toChars()); } - buf.printf(" }\n"); } - - buf.writestring("};\n\n"); - - if (sd.alignment == 1) - buf.writestring("#pragma pack(pop)\n"); - - auto savex = buf; - buf = checkbuf; - buf.writestring(" assert(sizeof("); - buf.writestring(sd.ident.toChars()); - buf.printf(") == %d);\n", sd.size(Loc.initial)); - buf = savex; + buf.printf(" }\n"); } - else - buf.writestring(";\n\n"); + + buf.writestring("};\n\n"); + + if (sd.alignment == 1) + buf.writestring("#pragma pack(pop)\n"); + + auto savex = buf; + buf = checkbuf; + buf.writestring(" assert(sizeof("); + buf.writestring(sd.ident.toChars()); + buf.printf(") == %d);\n", sd.size(Loc.initial)); + buf = savex; } - - private void includeSymbol(AST.Dsymbol ds) + else + buf.writestring(";\n\n"); + } + + private void includeSymbol(AST.Dsymbol ds) + { + // printf("Forward declaring %s %d\n", ds.toChars(), level); + if (cast(void*)ds !in visited) { - // printf("Forward declaring %s %d\n", ds.toChars(), level); - if (cast(void*)ds !in visited) - { - OutBuffer decl; - auto save = buf; - buf = &decl; - ds.accept(this); - buf = save; - donebuf.writestring(decl.peekString()); - } + OutBuffer decl; + auto save = buf; + buf = &decl; + ds.accept(this); + buf = save; + donebuf.writestring(decl.peekString()); } - - override void visit(AST.ClassDeclaration cd) + } + + override void visit(AST.ClassDeclaration cd) + { + if (cast(void*)cd in visited) + return; + version(BUILD_COMPILER) { - if (cast(void*)cd in visited) - return; if (cd.getModule() && !cd.getModule().isFrontendModule()) - return; + return; if (cd.isVisitorClass()) - return; - visited[cast(void*)cd] = true; - if (!cd.isCPPclass()) - { - buf.printf("// ignoring non-cpp class %s\n", cd.toChars()); - return; - } - - buf.writestring("class "); - buf.writestring(cd.ident.toChars()); - if (cd.baseClass) + return; + } + + visited[cast(void*)cd] = true; + if (!cd.isCPPclass()) + { + buf.printf("// ignoring non-cpp class %s\n", cd.toChars()); + return; + } + + buf.writestring("class "); + buf.writestring(cd.ident.toChars()); + if (cd.baseClass) + { + buf.writestring(" : public "); + buf.writestring(cd.baseClass.ident.toChars()); + + includeSymbol(cd.baseClass); + } + if (cd.members) + { + buf.writestring("\n{\npublic:\n"); + auto save = adparent; + adparent = cd; + foreach (m; *cd.members) { - buf.writestring(" : public "); - buf.writestring(cd.baseClass.ident.toChars()); - - includeSymbol(cd.baseClass); + m.accept(this); } - if (cd.members) + adparent = save; + version(BUILD_COMPILER) { - buf.writestring("\n{\npublic:\n"); - auto save = adparent; - adparent = cd; - foreach (m; *cd.members) - { - m.accept(this); - } - adparent = save; // Generate special static inline function. if (cd.isIdentifierClass()) { buf.writestring(" static inline Identifier *idPool(const char *s) { return idPool(s, strlen(s)); }\n"); } - buf.writestring("};\n\n"); } - else - buf.writestring(";\n\n"); + + buf.writestring("};\n\n"); } - - override void visit(AST.EnumDeclaration ed) + else + buf.writestring(";\n\n"); + } + + override void visit(AST.EnumDeclaration ed) + { + if (cast(void*)ed in visited) + return; + version(BUILD_COMPILER) { - if (cast(void*)ed in visited) - return; if (ed.getModule() && !ed.getModule().isFrontendModule()) - return; - visited[cast(void*)ed] = true; - if (ed.isSpecial()) - return; - buf.writestring("enum"); - const(char)* ident = null; - if (ed.ident) - ident = ed.ident.toChars(); - if (ident) - { - buf.writeByte(' '); - buf.writestring(ident); - } - if (ed.members) - { - buf.writestring("\n{\n"); - foreach (i, m; *ed.members) - { - if (i) - buf.writestring(",\n"); - buf.writestring(" "); - if (ident) - { - foreach (c; ident[0 .. strlen(ident)]) - buf.writeByte(toupper(c)); - } - m.accept(this); - } - buf.writestring("\n};\n\n"); - } - else - buf.writestring(";\n\n"); + return; } - - override void visit(AST.EnumMember em) + + visited[cast(void*)ed] = true; + if (ed.isSpecial()) + return; + buf.writestring("enum"); + const(char)* ident = null; + if (ed.ident) + ident = ed.ident.toChars(); + if (ident) { - buf.writestring(em.ident.toChars()); - buf.writestring(" = "); - assert(em.value.op == TOK.int64); - auto ie = cast(AST.IntegerExp)em.value; - visitInteger(ie.toInteger(), em.ed.memtype); + buf.writeByte(' '); + buf.writestring(ident); } - - private void typeToBuffer(AST.Type t, Identifier ident) + if (ed.members) { - this.ident = ident; - t.accept(this); - if (this.ident) - { - buf.writeByte(' '); - buf.writestring(ident.toChars()); - } - this.ident = null; - if (t.ty == AST.Tsarray) + buf.writestring("\n{\n"); + foreach (i, m; *ed.members) { - auto tsa = cast(AST.TypeSArray)t; - buf.writeByte('['); - tsa.dim.accept(this); - buf.writeByte(']'); + if (i) + buf.writestring(",\n"); + buf.writestring(" "); + if (ident) + { + foreach (c; ident[0 .. strlen(ident)]) + buf.writeByte(toupper(c)); + } + m.accept(this); } + buf.writestring("\n};\n\n"); } - - override void visit(AST.Type t) + else + buf.writestring(";\n\n"); + } + + override void visit(AST.EnumMember em) + { + buf.writestring(em.ident.toChars()); + buf.writestring(" = "); + if (cast(AST.StringExp)em.value) { - printf("Invalid type: %s\n", t.toPrettyChars()); - assert(0); + em.value.error("cannot convert string enum"); + return ; } - - override void visit(AST.TypeIdentifier t) + auto ie = cast(AST.IntegerExp)em.value; + visitInteger(ie.toInteger(), em.ed.memtype); + } + + private void typeToBuffer(AST.Type t, Identifier ident) + { + this.ident = ident; + t.accept(this); + if (this.ident) { - buf.writestring(t.ident.toChars()); + buf.writeByte(' '); + buf.writestring(ident.toChars()); } - - override void visit(AST.TypeBasic t) + this.ident = null; + if (t.ty == AST.Tsarray) + { + auto tsa = cast(AST.TypeSArray)t; + buf.writeByte('['); + tsa.dim.accept(this); + buf.writeByte(']'); + } + } + + override void visit(AST.Type t) + { + printf("Invalid type: %s\n", t.toPrettyChars()); + assert(0); + } + + override void visit(AST.TypeIdentifier t) + { + buf.writestring(t.ident.toChars()); + } + + override void visit(AST.TypeBasic t) + { + if (!cdparent && t.isConst()) + buf.writestring("const "); + switch (t.ty) { - if (!cdparent && t.isConst()) - buf.writestring("const "); - switch (t.ty) - { case AST.Tbool, AST.Tvoid: case AST.Tchar, AST.Twchar, AST.Tdchar: case AST.Tint8, AST.Tuns8: @@ -664,361 +971,376 @@ void genCppFiles(OutBuffer* buf, Modules *ms) buf.writestring(t.dstring); break; default: - t.print(); + //t.print(); assert(0); - } - } - - override void visit(AST.TypePointer t) - { - if (t.next.ty == AST.Tstruct && - !strcmp((cast(AST.TypeStruct)t.next).sym.ident.toChars(), "__va_list_tag")) - { - buf.writestring("va_list"); - return; - } - t.next.accept(this); - if (t.next.ty != AST.Tfunction) - buf.writeByte('*'); - if (!cdparent && t.isConst()) - buf.writestring(" const"); } - - override void visit(AST.TypeSArray t) + } + + override void visit(AST.TypePointer t) + { + if (t.next.ty == AST.Tstruct && + !strcmp((cast(AST.TypeStruct)t.next).sym.ident.toChars(), "__va_list_tag")) { - t.next.accept(this); + buf.writestring("va_list"); + return; } - - override void visit(AST.TypeAArray t) + t.next.accept(this); + if (t.next.ty != AST.Tfunction) + buf.writeByte('*'); + if (!cdparent && t.isConst()) + buf.writestring(" const"); + } + + override void visit(AST.TypeSArray t) + { + t.next.accept(this); + } + + override void visit(AST.TypeAArray t) + { + AST.Type.tvoidptr.accept(this); + } + + override void visit(AST.TypeFunction tf) + { + tf.next.accept(this); + buf.writeByte('('); + buf.writeByte('*'); + if (ident) + buf.writestring(ident.toChars()); + ident = null; + buf.writeByte(')'); + buf.writeByte('('); + foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) { - AST.Type.tvoidptr.accept(this); + if (i) + buf.writestring(", "); + auto fparam = AST.Parameter.getNth(tf.parameters, i); + fparam.accept(this); } - - override void visit(AST.TypeFunction tf) - { - tf.next.accept(this); - buf.writeByte('('); - buf.writeByte('*'); - if (ident) - buf.writestring(ident.toChars()); - ident = null; - buf.writeByte(')'); - buf.writeByte('('); - foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) - { - if (i) - buf.writestring(", "); - auto fparam = AST.Parameter.getNth(tf.parameters, i); - fparam.accept(this); - } - if (tf.varargs) - { - if (tf.parameters.dim && tf.varargs == 1) - buf.writestring(", "); - buf.writestring("..."); - } - buf.writeByte(')'); + if (tf.varargs) + { + if (tf.parameters.dim && tf.varargs == 1) + buf.writestring(", "); + buf.writestring("..."); } - - private void enumToBuffer(AST.EnumDeclaration ed) + buf.writeByte(')'); + } + + private void enumToBuffer(AST.EnumDeclaration ed) + { + if (ed.isSpecial()) { - if (ed.isSpecial()) + if (ed.ident == DMDType.c_long) + buf.writestring("long"); + else if (ed.ident == DMDType.c_ulong) + buf.writestring("unsigned long"); + else if (ed.ident == DMDType.c_longlong) + buf.writestring("long long"); + else if (ed.ident == DMDType.c_ulonglong) + buf.writestring("unsigned long long"); + else if (ed.ident == DMDType.c_long_double) + buf.writestring("long double"); + else { - if (ed.ident == Identifier.idPool("__c_long")) - buf.writestring("long"); - else if (ed.ident == Identifier.idPool("__c_ulong")) - buf.writestring("unsigned long"); - else if (ed.ident == Identifier.idPool("__c_longlong")) - buf.writestring("long long"); - else if (ed.ident == Identifier.idPool("__c_ulonglong")) - buf.writestring("unsigned long long"); - else if (ed.ident == Identifier.idPool("__c_long_double")) - buf.writestring("long double"); - else - { - ed.print(); - assert(0); - } + //ed.print(); + assert(0); } - else - buf.writestring(ed.toChars()); } - - override void visit(AST.TypeEnum t) + else + buf.writestring(ed.toChars()); + } + + override void visit(AST.TypeEnum t) + { + if (cast(void*)t.sym !in forwarded) { - if (cast(void*)t.sym !in forwarded) - { - forwarded[cast(void*)t.sym] = true; - auto save = buf; - buf = fwdbuf; - t.sym.accept(this); - buf = save; - } - if (!cdparent && t.isConst()) - buf.writestring("const "); - enumToBuffer(t.sym); + forwarded[cast(void*)t.sym] = true; + auto save = buf; + buf = fwdbuf; + t.sym.accept(this); + buf = save; } - - override void visit(AST.TypeStruct t) + if (!cdparent && t.isConst()) + buf.writestring("const "); + enumToBuffer(t.sym); + } + + override void visit(AST.TypeStruct t) + { + if (cast(void*)t.sym !in forwarded && + !t.sym.parent.isTemplateInstance()) { - if (cast(void*)t.sym !in forwarded && - !t.sym.parent.isTemplateInstance()) - { - forwarded[cast(void*)t.sym] = true; - fwdbuf.writestring(t.sym.isUnionDeclaration() ? "union " : "struct "); - fwdbuf.writestring(t.sym.toChars()); - fwdbuf.writestring(";\n"); - } - - if (!cdparent && t.isConst()) - buf.writestring("const "); - if (auto ti = t.sym.parent.isTemplateInstance()) - { - visitTi(ti); - return; - } - buf.writestring(t.sym.toChars()); + forwarded[cast(void*)t.sym] = true; + fwdbuf.writestring(t.sym.isUnionDeclaration() ? "union " : "struct "); + fwdbuf.writestring(t.sym.toChars()); + fwdbuf.writestring(";\n"); } - - override void visit(AST.TypeDArray t) + + if (!cdparent && t.isConst()) + buf.writestring("const "); + if (auto ti = t.sym.parent.isTemplateInstance()) { - if (!cdparent && t.isConst()) - buf.writestring("const "); - buf.writestring("DArray<"); - t.next.accept(this); - buf.writestring(">"); + visitTi(ti); + return; } - - private void visitTi(AST.TemplateInstance ti) + buf.writestring(t.sym.toChars()); + } + + override void visit(AST.TypeDArray t) + { + if (!cdparent && t.isConst()) + buf.writestring("const "); + buf.writestring("DArray<"); + t.next.accept(this); + buf.writestring(">"); + } + + private void visitTi(AST.TemplateInstance ti) + { + version(BUILD_COMPILER) { - if (ti.tempdecl.ident == Identifier.idPool("AssocArray")) + if (ti.tempdecl.ident == DMDType.AssocArray) { buf.writestring("AA*"); return; } - if (ti.tempdecl.ident == Identifier.idPool("Array")) + if (ti.tempdecl.ident == DMDType.Array) buf.writestring("Array"); else { foreach (o; *ti.tiargs) { if (!AST.isType(o)) - return; + return; } buf.writestring(ti.tempdecl.ident.toChars()); } - buf.writeByte('<'); - foreach (i, o; *ti.tiargs) - { - if (i) - buf.writestring(", "); - if (auto tt = AST.isType(o)) - { - tt.accept(this); - } - else - { - ti.print(); - o.print(); - assert(0); - } - } - buf.writeByte('>'); } - - override void visit(AST.TemplateDeclaration td) + else { - if (cast(void*)td in visited) - return; - visited[cast(void*)td] = true; - - if (td.getModule() && !td.getModule().isFrontendModule()) - return; - if (!td.parameters || !td.onemember || !td.onemember.isStructDeclaration()) - { - visit(cast(AST.Dsymbol)td); - return; - } - - // Explcitly disallow templates with non-type parameters or specialization. - foreach (p; *td.parameters) - { - if (!p.isTemplateTypeParameter() || p.specialization()) - { - visit(cast(AST.Dsymbol)td); - return; - } - } - - if (linkage != LINK.c && linkage != LINK.cpp) + foreach (o; *ti.tiargs) { - buf.printf("// ignoring template %s because of linkage\n", td.toPrettyChars()); + if (!AST.isType(o)) return; } - - auto sd = td.onemember.isStructDeclaration(); - auto save = tdparent; - tdparent = td; - indent(); - buf.writestring("template <"); - bool first = true; - foreach (p; *td.parameters) + buf.writestring(ti.tempdecl.ident.toChars()); + } + buf.writeByte('<'); + foreach (i, o; *ti.tiargs) + { + if (i) + buf.writestring(", "); + if (auto tt = AST.isType(o)) { - if (first) - first = false; - else - buf.writestring(", "); - buf.writestring("typename "); - buf.writestring(p.ident.toChars()); + tt.accept(this); } - buf.writestring(">\n"); - buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); - buf.writestring(sd.ident.toChars()); - if (sd.members) + else { - buf.writestring("\n{\n"); - auto savex = adparent; - adparent = sd; - foreach (m; *sd.members) - { - m.accept(this); - } - adparent = savex; - buf.writestring("};\n\n"); + //ti.print(); + //o.print(); + assert(0); } - else - buf.writestring(";\n\n"); - tdparent = save; } - - override void visit(AST.TypeClass t) + buf.writeByte('>'); + } + + override void visit(AST.TemplateDeclaration td) + { + if (cast(void*)td in visited) + return; + visited[cast(void*)td] = true; + version(BUILD_COMPILER) { - if (cast(void*)t.sym !in forwarded) - { - forwarded[cast(void*)t.sym] = true; - fwdbuf.writestring("class "); - fwdbuf.writestring(t.sym.toChars()); - fwdbuf.writestring(";\n"); - } - - if (!cdparent && t.isConst()) - buf.writestring("const "); - buf.writestring(t.sym.toChars()); - buf.writeByte('*'); - if (!cdparent && t.isConst()) - buf.writestring(" const"); + if (td.getModule() && !td.getModule().isFrontendModule()) + return; } - - private void funcToBuffer(AST.TypeFunction tf, Identifier ident) + + if (!td.parameters || !td.onemember || !td.onemember.isStructDeclaration()) { - assert(tf.next); - tf.next.accept(this); - if (tf.isref) - buf.writeByte('&'); - buf.writeByte(' '); - buf.writestring(ident.toChars()); - - buf.writeByte('('); - foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) - { - if (i) - buf.writestring(", "); - auto fparam = AST.Parameter.getNth(tf.parameters, i); - fparam.accept(this); - } - if (tf.varargs) + visit(cast(AST.Dsymbol)td); + return; + } + + // Explicitly disallow templates with non-type parameters or specialization. + foreach (p; *td.parameters) + { + if (!p.isTemplateTypeParameter() || p.specialization()) { - if (tf.parameters.dim && tf.varargs == 1) - buf.writestring(", "); - buf.writestring("..."); + visit(cast(AST.Dsymbol)td); + return; } - buf.writeByte(')'); } - - override void visit(AST.Parameter p) + + if (linkage != LINK.c && linkage != LINK.cpp) { - ident = p.ident; - p.type.accept(this); - assert(!(p.storageClass & ~(AST.STC.ref_))); - if (p.storageClass & AST.STC.ref_) - buf.writeByte('&'); - buf.writeByte(' '); - if (ident) - buf.writestring(ident.toChars()); - ident = null; - if (p.defaultArg) + buf.printf("// ignoring template %s because of linkage\n", td.toPrettyChars()); + return; + } + + auto sd = td.onemember.isStructDeclaration(); + auto save = tdparent; + tdparent = td; + indent(); + buf.writestring("template <"); + bool first = true; + foreach (p; *td.parameters) + { + if (first) + first = false; + else + buf.writestring(", "); + buf.writestring("typename "); + buf.writestring(p.ident.toChars()); + } + buf.writestring(">\n"); + buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); + buf.writestring(sd.ident.toChars()); + if (sd.members) + { + buf.writestring("\n{\n"); + auto savex = adparent; + adparent = sd; + foreach (m; *sd.members) { - // buf.writestring("/*"); - buf.writestring(" = "); - p.defaultArg.accept(this); - // buf.writestring("*/"); + m.accept(this); } + adparent = savex; + buf.writestring("};\n\n"); } - - override void visit(AST.Expression e) + else + buf.writestring(";\n\n"); + tdparent = save; + } + + override void visit(AST.TypeClass t) + { + if (cast(void*)t.sym !in forwarded) { - e.print(); - assert(0); + forwarded[cast(void*)t.sym] = true; + fwdbuf.writestring("class "); + fwdbuf.writestring(t.sym.toChars()); + fwdbuf.writestring(";\n"); } - - override void visit(AST.NullExp e) + + if (!cdparent && t.isConst()) + buf.writestring("const "); + buf.writestring(t.sym.toChars()); + buf.writeByte('*'); + if (!cdparent && t.isConst()) + buf.writestring(" const"); + } + + private void funcToBuffer(AST.TypeFunction tf, Identifier ident) + { + assert(tf.next); + tf.next.accept(this); + if (tf.isref) + buf.writeByte('&'); + buf.writeByte(' '); + buf.writestring(ident.toChars()); + + buf.writeByte('('); + foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) { - buf.writestring("_d_null"); + if (i) + buf.writestring(", "); + auto fparam = AST.Parameter.getNth(tf.parameters, i); + fparam.accept(this); } - - override void visit(AST.ArrayLiteralExp e) + if (tf.varargs) { - buf.writestring("arrayliteral"); + if (tf.parameters.dim && tf.varargs == 1) + buf.writestring(", "); + buf.writestring("..."); } - - override void visit(AST.StringExp e) - { - assert(e.sz == 1 || e.sz == 2); - if (e.sz == 2) - buf.writeByte('L'); - buf.writeByte('"'); - size_t o = buf.offset; - for (size_t i = 0; i < e.len; i++) + buf.writeByte(')'); + } + + override void visit(AST.Parameter p) + { + ident = p.ident; + p.type.accept(this); + assert(!(p.storageClass & ~(AST.STC.ref_))); + if (p.storageClass & AST.STC.ref_) + buf.writeByte('&'); + buf.writeByte(' '); + if (ident) + buf.writestring(ident.toChars()); + ident = null; + if (p.defaultArg) + { + // buf.writestring("/*"); + buf.writestring(" = "); + p.defaultArg.accept(this); + // buf.writestring("*/"); + } + } + + override void visit(AST.Expression e) + { + //e.print(); + assert(0); + } + + override void visit(AST.NullExp e) + { + buf.writestring("_d_null"); + } + + override void visit(AST.ArrayLiteralExp e) + { + buf.writestring("arrayliteral"); + } + + override void visit(AST.StringExp e) + { + assert(e.sz == 1 || e.sz == 2); + if (e.sz == 2) + buf.writeByte('L'); + buf.writeByte('"'); + size_t o = buf.offset; + for (size_t i = 0; i < e.len; i++) + { + uint c = e.charAt(i); + switch (c) { - uint c = e.charAt(i); - switch (c) - { case '"': case '\\': - buf.writeByte('\\'); - goto default; + buf.writeByte('\\'); + goto default; default: - if (c <= 0xFF) - { - if (c <= 0x7F && isprint(c)) - buf.writeByte(c); - else - buf.printf("\\x%02x", c); - } - else if (c <= 0xFFFF) - buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8); + if (c <= 0xFF) + { + if (c <= 0x7F && isprint(c)) + buf.writeByte(c); else - buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24); - break; + buf.printf("\\x%02x", c); } + else if (c <= 0xFFFF) + buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8); + else + buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24); + break; } - buf.writeByte('"'); - } - - override void visit(AST.RealExp e) - { - buf.writestring("0"); - } - - override void visit(AST.IntegerExp e) - { - visitInteger(e.toInteger, e.type); } - - private void visitInteger(dinteger_t v, AST.Type t) + buf.writeByte('"'); + } + + override void visit(AST.RealExp e) + { + buf.writestring("0"); + } + + override void visit(AST.IntegerExp e) + { + visitInteger(e.toInteger, e.type); + } + + private void visitInteger(dinteger_t v, AST.Type t) + { + switch (t.ty) { - switch (t.ty) - { case AST.Tenum: auto te = cast(AST.TypeEnum)t; buf.writestring("("); @@ -1055,24 +1377,27 @@ void genCppFiles(OutBuffer* buf, Modules *ms) buf.printf("%lluLLU", v); break; default: - t.print(); + //t.print(); assert(0); - } } - - override void visit(AST.StructLiteralExp sle) + } + + override void visit(AST.StructLiteralExp sle) + { + buf.writestring(sle.sd.ident.toChars()); + buf.writeByte('('); + foreach(i, e; *sle.elements) { - buf.writestring(sle.sd.ident.toChars()); - buf.writeByte('('); - foreach(i, e; *sle.elements) - { - if (i) - buf.writestring(", "); - e.accept(this); - } - buf.writeByte(')'); + if (i) + buf.writestring(", "); + e.accept(this); } + buf.writeByte(')'); } +} +void genCppFiles(OutBuffer* buf, Modules *ms) +{ + import dmd.tokens; buf.writeByte('\n'); buf.printf("// Automatically generated by dtoh\n"); @@ -1109,148 +1434,48 @@ void genCppFiles(OutBuffer* buf, Modules *ms) buf.writestring("\n"); buf.writestring("#define _d_null NULL\n"); buf.writestring("\n"); - buf.writestring("struct AA;\n"); + version(BUILD_COMPILER) + buf.writestring("struct AA;\n"); buf.writestring("\n"); - + OutBuffer check; check.writestring(` -#if OFFSETS - -template -size_t getSlotNumber(int dummy, ...) -{ - T c; - va_list ap; - va_start(ap, dummy); - void *f = va_arg(ap, void*); - for (size_t i = 0; ; i++) + #if OFFSETS + + template + size_t getSlotNumber(int dummy, ...) { - if ( (*(void***)&c)[i] == f) + T c; + va_list ap; + va_start(ap, dummy); + void *f = va_arg(ap, void*); + for (size_t i = 0; ; i++) + { + if ( (*(void***)&c)[i] == f) return i; + } + va_end(ap); } - va_end(ap); -} - -void testOffsets() -{ - `); - - OutBuffer done; - OutBuffer decl; - scope v = new ToCppBuffer!ASTCodegen(&check, buf, &done, &decl); - foreach (m; *ms) + + void testOffsets() { - buf.printf("// Parsing module %s\n", m.toPrettyChars()); - m.accept(v); + `); + + OutBuffer done; + OutBuffer decl; + scope v = new ToCppBuffer!ASTCodegen(&check, buf, &done, &decl); + foreach (m; *ms) + { + buf.printf("// Parsing module %s\n", m.toPrettyChars()); + m.accept(v); + } + buf.write(&done); + buf.write(&decl); + + check.writestring(` } - buf.write(&done); - buf.write(&decl); - - check.writestring(` -} -#endif + #endif `); - + debug buf.write(&check); } - -void main() -{ - import std.stdio; - import std.algorithm.sorting : sort; - import std.array : array; - import std.file : readText; - import std.path : baseName, buildPath, dirName; - import std.string : toStringz; - - import dmd.id; - import dmd.parse; - import dmd.dsymbolsem; - import dmd.semantic2; - import dmd.semantic3; - import dmd.builtin : builtin_init; - import dmd.dmodule : Module; - import dmd.cond : VersionCondition; - import dmd.expression : Expression; - import dmd.objc : Objc; - import dmd.target : Target; - - import core.memory; - - GC.disable(); - - global._init(); - global.params.isLinux = true; - global.params.is64bit = (size_t.sizeof == 8); - global.params.isLP64 = global.params.is64bit; - - global.path = new Strings(); - global.path.push(__FILE_FULL_PATH__.dirName.buildPath("../../../druntime/src/").toStringz()); - - global.filePath = new Strings(); - global.params.fileImppath = global.filePath; - global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../").toStringz()); - global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../res/").toStringz()); - - ASTCodegen.Type._init(); - Id.initialize(); - Module._init(); - Target._init(); - Expression._init(); - Objc._init(); - builtin_init(); - - VersionCondition.addPredefinedGlobalIdent("all"); - VersionCondition.addPredefinedGlobalIdent("DigitalMars"); - VersionCondition.addPredefinedGlobalIdent("Posix"); - VersionCondition.addPredefinedGlobalIdent("linux"); - VersionCondition.addPredefinedGlobalIdent("CRuntime_Glibc"); - VersionCondition.addPredefinedGlobalIdent("NoBackend"); - VersionCondition.addPredefinedGlobalIdent("NoMain"); - if (global.params.is64bit) - VersionCondition.addPredefinedGlobalIdent("X86_64"); - else - VersionCondition.addPredefinedGlobalIdent("X86"); - if (global.params.isLP64) - VersionCondition.addPredefinedGlobalIdent("D_LP64"); - - Modules modules; - - string path = __FILE_FULL_PATH__.dirName.buildPath("../dmd/"); - - foreach (f; frontendSources) - { - string fn = buildPath(path, f); - - auto id = Identifier.idPool(baseName(fn, ".d")); - auto m = new Module(fn.toStringz(), id, false, false); - auto input = readText(fn); - - if (!Module.rootModule) - Module.rootModule = m; - - m.importedFrom = m; - m.srcfile.setbuffer(cast(void*)input.ptr, input.length); - m.srcfile._ref = 1; - m.parse(); - modules.push(m); - } - - foreach (m; modules) - m.importAll(null); - foreach (m; modules) - m.dsymbolSemantic(null); - Module.dprogress = 1; - Module.runDeferredSemantic(); - foreach (m; modules) - m.semantic2(null); - Module.runDeferredSemantic2(); - foreach (m; modules) - m.semantic3(null); - Module.runDeferredSemantic3(); - - OutBuffer buf; - genCppFiles(&buf, &modules); - - writeln(buf.peekSlice()); -} diff --git a/src/posix.mak b/src/posix.mak index 07c743f6afcb..bafee93dc418 100644 --- a/src/posix.mak +++ b/src/posix.mak @@ -435,22 +435,6 @@ style: $(GENERATED)/build cxx-unittest: $(GENERATED)/build $(RUN_BUILD) $@ -#======= -#$G/dtoh: $D/dtoh.d $(FRONT_SRCS) $D/gluelayer.d $(ROOT_SRCS) $G/newdelete.o $G/lexer.a $(STRING_IMPORT_FILES) $(HOST_DMD_PATH) - #CC="$(HOST_CXX)" $(HOST_DMD_RUN) -of$@ $(MODEL_FLAG) -vtls -J$G -J../res -L-lstdc++ $(DFLAGS) -version=NoBackend -version=NoMain $(filter-out $(STRING_IMPORT_FILES) $(HOST_DMD_PATH),$^) - -#$D/frontend.h: $G/dtoh - #$G/dtoh > $D/frontend.h - -#$G/cxxfrontend.o: $G/%.o: tests/%.c $D/frontend.h $(SRC) $(ROOT_SRC) - #$(CXX) -c -o$@ $(CXXFLAGS) $(DMD_FLAGS) $(MMD) $< - -#$G/cxx-unittest: $G/cxxfrontend.o $(DMD_SRCS) $(ROOT_SRCS) $G/lexer.a $G/backend.o $(STRING_IMPORT_FILES) $(HOST_DMD_PATH) - #CC=$(HOST_CXX) $(HOST_DMD_RUN) -of$@ $(MODEL_FLAG) -vtls -J$G -J$(RES) -L-lstdc++ $(DFLAGS) -version=NoMain $(filter-out $(STRING_IMPORT_FILES) $(HOST_DMD_PATH),$^) - -#cxx-unittest: $G/cxx-unittest - #$< -#>>>>>>> Use generated frontend.h in C++ test ###################################################### From 638e18601b7baaa5ba6b1f1a7628f4a7fe0f59b2 Mon Sep 17 00:00:00 2001 From: Nicholas Lindsay Wilson Date: Sun, 18 Nov 2018 15:58:21 +0800 Subject: [PATCH 05/44] Fix stuff --- src/dmd/dtoh.d | 67 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index a9cafc0fb8e5..f3000dc121e8 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -148,7 +148,7 @@ int main(string[] args) version(Windows) // delete LIB entry in [Environment] (necessary for optlink) to allow inheriting environment for MS-COFF if (is64bit || strcmp(arch, "32mscoff") == 0) - environment.update("LIB", 3).ptrvalue = null; + environment.update("LIB", 3).ptrvalue = null; // read from DFLAGS in [Environment{arch}] section char[80] envsection = void; @@ -167,13 +167,13 @@ int main(string[] args) } - version(BUILD_COMPILER) + /*version(BUILD_COMPILER) { global.path.push(druntimeFullPath.toStringz()); //TODO: fixme for LDC global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../").toStringz()); global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../res/").toStringz()); - } + }*/ DMDType._init(); version(BUILD_COMPILER) @@ -242,17 +242,32 @@ void setVersions() } } +string dirName(string path) +{ + version (Windows) + enum char separator = '\\'; + else + enum char separator = '/'; + + for (size_t i = path.length - 1; i > 0; i--) + { + if (path[i] == separator) + return path[0..i]; + } + return path; +} + struct DMDType { - static Identifier c_long; - static Identifier c_ulong; - static Identifier c_longlong; - static Identifier c_ulonglong; - static Identifier c_long_double; + __gshared static Identifier c_long; + __gshared static Identifier c_ulong; + __gshared static Identifier c_longlong; + __gshared static Identifier c_ulonglong; + __gshared static Identifier c_long_double; version(BUILD_COMPILER) { - static Identifier AssocArray; - static Identifier Array; + __gshared static Identifier AssocArray; + __gshared static Identifier Array; } static void _init() { @@ -273,14 +288,14 @@ version(BUILD_COMPILER) { struct DMDModule { - static Identifier identifier; - static Identifier root; - static Identifier visitor; - static Identifier parsetimevisitor; - static Identifier permissivevisitor; - static Identifier strictvisitor; - static Identifier transitivevisitor; - static Identifier dmd; + __gshared static Identifier identifier; + __gshared static Identifier root; + __gshared static Identifier visitor; + __gshared static Identifier parsetimevisitor; + __gshared static Identifier permissivevisitor; + __gshared static Identifier strictvisitor; + __gshared static Identifier transitivevisitor; + __gshared static Identifier dmd; static void _init() { identifier = Identifier.idPool("identifier"); @@ -295,10 +310,10 @@ version(BUILD_COMPILER) } struct DMDClass { - static Identifier ID; ////Identifier - static Identifier Visitor; - static Identifier ParseTimeVisitor; - static void _init() + __gshared static Identifier ID; ////Identifier + __gshared static Identifier Visitor; + __gshared static Identifier ParseTimeVisitor; + __gshared static void _init() { ID = Identifier.idPool("Identifier"); Visitor = Identifier.idPool("Visitor"); @@ -320,8 +335,8 @@ version(BUILD_COMPILER) { for (auto cdb = cd; cdb; cdb = cdb.baseClass) { - if (cdb.ident == DMClass.Visitor || - cdb.ident == DMClass.ParseTimeVisitor) + if (cdb.ident == DMDClass.Visitor || + cdb.ident == DMDClass.ParseTimeVisitor) return true; } return false; @@ -356,7 +371,7 @@ version(BUILD_COMPILER) (m.parent.parent.ident == DMDModule.dmd && !m.parent.parent.parent)); } - string druntimeFullPath() + /*string druntimeFullPath() { version (IN_LLVM) string path = "../runtime/druntime/src"; @@ -364,7 +379,7 @@ version(BUILD_COMPILER) string path = "../../../druntime/src/"; return __FILE_FULL_PATH__.dirName.buildPath(path); - } + }*/ } /**************************************************** From e5375195b59ffccd06a2620aefcfcb08497f5eb7 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 4 Jun 2019 18:37:11 +0300 Subject: [PATCH 06/44] Add dtoh as a compiler switch --- src/dmd/dtoh.d | 90 +++++++++++++++++++++++++++++++++++++++++++++++ src/dmd/globals.d | 1 + src/dmd/mars.d | 30 ++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index f3000dc121e8..b87284270f1f 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -54,6 +54,8 @@ version(BUILD_COMPILER) ]; } +version(none) +{ int main(string[] args) { import std.algorithm.sorting : sort; @@ -231,6 +233,7 @@ int main(string[] args) printf("%s\n", buf.peekString()); return 0; } +} void setVersions() { @@ -1494,3 +1497,90 @@ void genCppFiles(OutBuffer* buf, Modules *ms) debug buf.write(&check); } + +void gencpphdrfiles(Modules *ms) +{ + import dmd.tokens; + + OutBuffer buf; + buf.writeByte('\n'); + buf.printf("// Automatically generated by dtoh\n"); + buf.writeByte('\n'); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writeByte('\n'); + buf.writestring("#define _d_void void\n"); + buf.writestring("#define _d_bool bool\n"); + buf.writestring("#define _d_byte signed char\n"); + buf.writestring("#define _d_ubyte unsigned char\n"); + buf.writestring("#define _d_short short\n"); + buf.writestring("#define _d_ushort unsigned short\n"); + buf.writestring("#define _d_int int\n"); + buf.writestring("#define _d_uint unsigned\n"); + if (global.params.isLP64) + { + buf.writestring("#define _d_long long\n"); + buf.writestring("#define _d_ulong unsigned long\n"); + } + else + { + buf.writestring("#define _d_long long long\n"); + buf.writestring("#define _d_ulong unsigned long long\n"); + } + buf.writestring("#define _d_float float\n"); + buf.writestring("#define _d_double double\n"); + buf.writestring("#define _d_real long double\n"); + buf.writestring("#define _d_char char\n"); + buf.writestring("#define _d_wchar wchar_t\n"); + buf.writestring("#define _d_dchar unsigned\n"); + buf.writestring("\n"); + buf.writestring("#define _d_null NULL\n"); + buf.writestring("\n"); + version(BUILD_COMPILER) + buf.writestring("struct AA;\n"); + buf.writestring("\n"); + + OutBuffer check; + check.writestring(` + #if OFFSETS + + template + size_t getSlotNumber(int dummy, ...) + { + T c; + va_list ap; + va_start(ap, dummy); + void *f = va_arg(ap, void*); + for (size_t i = 0; ; i++) + { + if ( (*(void***)&c)[i] == f) + return i; + } + va_end(ap); + } + + void testOffsets() + { + `); + + OutBuffer done; + OutBuffer decl; + scope v = new ToCppBuffer!ASTCodegen(&check, &buf, &done, &decl); + foreach (m; *ms) + { + buf.printf("// Parsing module %s\n", m.toPrettyChars()); + m.accept(v); + } + buf.write(&done); + buf.write(&decl); + + check.writestring(` + } + #endif + `); + + debug buf.write(&check); + printf("%s\n", buf.peekString()); +} diff --git a/src/dmd/globals.d b/src/dmd/globals.d index 7b74cc6992b0..aa70bbcd1675 100644 --- a/src/dmd/globals.d +++ b/src/dmd/globals.d @@ -225,6 +225,7 @@ extern (C++) struct Param Array!(const(char)*) ddocfiles; // macro include files for Ddoc bool doHdrGeneration; // process embedded documentation comments + bool doCxxHdrGeneration; // write 'Cxx header' file const(char)[] hdrdir; // write 'header' file to docdir directory const(char)[] hdrname; // write 'header' file to docname bool hdrStripPlainFunctions = true; // strip the bodies of plain (non-template) functions diff --git a/src/dmd/mars.d b/src/dmd/mars.d index abda308571fd..2993927725f9 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -64,6 +64,8 @@ import dmd.semantic3; import dmd.target; import dmd.utils; +import dmd.dtoh; + /** * Print DMD's logo on stdout */ @@ -595,6 +597,13 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) if (global.errors) fatal(); + if (global.params.doCxxHdrGeneration) + { + gencpphdrfiles(&modules); + } + if (global.errors) + fatal(); + // Scan for functions to inline if (params.useInline) { @@ -2103,6 +2112,27 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param goto Lerror; } } + else if (p[1] == 'H' && p[2] == 'C') + { + params.doCxxHdrGeneration = true; + switch (p[3]) + { + case 'd': // https://dlang.org/dmd.html#switch-Hd + if (!p[4]) + goto Lnoarg; + params.hdrdir = p + 4 + (p[4] == '='); + break; + case 'f': // https://dlang.org/dmd.html#switch-Hf + if (!p[4]) + goto Lnoarg; + params.hdrname = p + 4 + (p[4] == '='); + break; + case 0: + break; + default: + goto Lerror; + } + } else if (p[1] == 'H') // https://dlang.org/dmd.html#switch-H { params.doHdrGeneration = true; From 8a64333d04141a1231a1f47ff0b43f469d7c01fc Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 4 Jun 2019 19:22:11 +0300 Subject: [PATCH 07/44] Update code after rebase --- src/dmd/dtoh.d | 20 ++++++++++---------- src/dmd/mars.d | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index b87284270f1f..c8af99a8b20e 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -829,7 +829,7 @@ public: buf = &decl; ds.accept(this); buf = save; - donebuf.writestring(decl.peekString()); + donebuf.writestring(decl.peekChars()); } } @@ -1029,16 +1029,16 @@ public: ident = null; buf.writeByte(')'); buf.writeByte('('); - foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) + foreach (i; 0 .. AST.Parameter.dim(tf.parameterList.parameters)) { if (i) buf.writestring(", "); - auto fparam = AST.Parameter.getNth(tf.parameters, i); + auto fparam = AST.Parameter.getNth(tf.parameterList.parameters, i); fparam.accept(this); } - if (tf.varargs) + if (tf.parameterList.varargs) { - if (tf.parameters.dim && tf.varargs == 1) + if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1) buf.writestring(", "); buf.writestring("..."); } @@ -1259,16 +1259,16 @@ public: buf.writestring(ident.toChars()); buf.writeByte('('); - foreach (i; 0 .. AST.Parameter.dim(tf.parameters)) + foreach (i; 0 .. AST.Parameter.dim(tf.parameterList.parameters)) { if (i) buf.writestring(", "); - auto fparam = AST.Parameter.getNth(tf.parameters, i); + auto fparam = AST.Parameter.getNth(tf.parameterList.parameters, i); fparam.accept(this); } - if (tf.varargs) + if (tf.parameterList.varargs) { - if (tf.parameters.dim && tf.varargs == 1) + if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1) buf.writestring(", "); buf.writestring("..."); } @@ -1582,5 +1582,5 @@ void gencpphdrfiles(Modules *ms) `); debug buf.write(&check); - printf("%s\n", buf.peekString()); + printf("%s\n", buf.peekChars()); } diff --git a/src/dmd/mars.d b/src/dmd/mars.d index 2993927725f9..ab7a2d8e5840 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -2120,12 +2120,12 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param case 'd': // https://dlang.org/dmd.html#switch-Hd if (!p[4]) goto Lnoarg; - params.hdrdir = p + 4 + (p[4] == '='); + params.hdrdir = (p + 4 + (p[4] == '=')).toDString; break; case 'f': // https://dlang.org/dmd.html#switch-Hf if (!p[4]) goto Lnoarg; - params.hdrname = p + 4 + (p[4] == '='); + params.hdrname = (p + 4 + (p[4] == '=')).toDString; break; case 0: break; From 453188f9338ca9bd29b5fad64de541a51fe18d21 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Fri, 14 Jun 2019 17:09:34 +0300 Subject: [PATCH 08/44] Compile frontend srcs and write to flie --- src/dmd/dtoh.d | 284 ++++++++++++++++++++++++++-------------------- src/dmd/globals.d | 6 +- src/dmd/mars.d | 4 +- 3 files changed, 165 insertions(+), 129 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index c8af99a8b20e..003c1adbc333 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -28,6 +28,8 @@ import dmd.root.rmem; import dmd.visitor; import dmd.root.outbuffer; +import dmd.utils; + version(BUILD_COMPILER) { immutable string[] sources = [ @@ -80,13 +82,13 @@ int main(string[] args) import dmd.root.response; import dmd.root.stringtable; import dmd.target : Target; - + import core.memory; import core.stdc.stdio : printf; - + GC.disable(); initDMD(); - + Strings arguments = Strings(args.length); for (size_t i = 0; i < args.length; i++) { @@ -97,7 +99,6 @@ int main(string[] args) auto files = Strings(arguments.dim - 1); global.params.argv0 = args[0]; - global.inifilename = parse_conf_arg(&arguments); if (global.inifilename) { @@ -134,10 +135,10 @@ int main(string[] args) */ sections.push("Environment"); parseConfFile(&environment, global.inifilename, inifilepath, inifile.len, inifile.buffer, §ions); - + const(char)* arch = global.params.is64bit ? "64" : "32"; // use default arch = parse_arch_arg(&arguments, arch); - + // parse architecture from DFLAGS read from [Environment] section { Strings dflags; @@ -145,13 +146,13 @@ int main(string[] args) environment.reset(7); // erase cached environment updates arch = parse_arch_arg(&dflags, arch); } - + bool is64bit = arch[0] == '6'; - + version(Windows) // delete LIB entry in [Environment] (necessary for optlink) to allow inheriting environment for MS-COFF if (is64bit || strcmp(arch, "32mscoff") == 0) environment.update("LIB", 3).ptrvalue = null; - + // read from DFLAGS in [Environment{arch}] section char[80] envsection = void; sprintf(envsection.ptr, "Environment%s", arch); @@ -160,14 +161,14 @@ int main(string[] args) getenv_setargv(readFromEnv(&environment, "DFLAGS"), &arguments); updateRealEnvironment(&environment); environment.reset(1); // don't need environment cache any more - + if (parseCommandLine(arguments, args.length, global.params, files)) { Loc loc; errorSupplemental(loc, "run 'dmd -man' to open browser on manual"); return 1; } - + /*version(BUILD_COMPILER) { @@ -176,7 +177,7 @@ int main(string[] args) global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../").toStringz()); global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../res/").toStringz()); }*/ - + DMDType._init(); version(BUILD_COMPILER) { @@ -187,7 +188,7 @@ int main(string[] args) setVersions(); Modules modules; - + string path = __FILE_FULL_PATH__.dirName.buildPath("../dmd/"); version (BUILD_COMPILER) auto srcs = sources; @@ -196,21 +197,21 @@ int main(string[] args) foreach (f; srcs) { string fn = buildPath(path, f); - + auto id = Identifier.idPool(baseName(fn, ".d")); auto m = new Module(fn.toStringz(), id, false, false); auto input = readText(fn); - + if (!Module.rootModule) Module.rootModule = m; - + m.importedFrom = m; m.srcfile.setbuffer(cast(void*)input.ptr, input.length); m.srcfile._ref = 1; m.parse(); modules.push(m); } - + foreach (m; modules) m.importAll(null); foreach (m; modules) @@ -226,10 +227,10 @@ int main(string[] args) foreach (m; modules) m.semantic3(null); Module.runDeferredSemantic3(); - + OutBuffer buf; genCppFiles(&buf, &modules); - + printf("%s\n", buf.peekString()); return 0; } @@ -322,9 +323,9 @@ version(BUILD_COMPILER) Visitor = Identifier.idPool("Visitor"); ParseTimeVisitor = Identifier.idPool("ParseTimeVisitor"); } - + } - + private bool isIdentifierClass(ASTCodegen.ClassDeclaration cd) { return (cd.ident == DMDClass.ID && @@ -333,7 +334,7 @@ version(BUILD_COMPILER) cd.parent.parent && cd.parent.parent.ident == DMDModule.dmd && !cd.parent.parent.parent); } - + private bool isVisitorClass(ASTCodegen.ClassDeclaration cd) { for (auto cdb = cd; cdb; cdb = cdb.baseClass) @@ -344,12 +345,12 @@ version(BUILD_COMPILER) } return false; } - + private bool isFrontendModule(ASTCodegen.Module m) { if (!m || !m.parent) - return false; - + return false; + // Ignore dmd.root if (m.parent.ident == DMDModule.root && m.parent.parent && m.parent.parent.ident == DMDModule.dmd && @@ -357,7 +358,7 @@ version(BUILD_COMPILER) { return false; } - + // Ignore dmd.visitor and derivatives if ((m.ident == DMDModule.visitor || m.ident == DMDModule.parsetimevisitor || @@ -369,18 +370,18 @@ version(BUILD_COMPILER) { return false; } - + return ((m.parent.ident == DMDModule.dmd && !m.parent.parent) || (m.parent.parent.ident == DMDModule.dmd && !m.parent.parent.parent)); } - + /*string druntimeFullPath() { version (IN_LLVM) string path = "../runtime/druntime/src"; else string path = "../../../druntime/src/"; - + return __FILE_FULL_PATH__.dirName.buildPath(path); }*/ } @@ -402,7 +403,7 @@ public: AST.TemplateDeclaration tdparent; Identifier ident; LINK linkage = LINK.d; - + this(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf) { this.checkbuf = checkbuf; @@ -410,13 +411,13 @@ public: this.donebuf = donebuf; this.buf = buf; } - + private void indent() { if (adparent) buf.writestring(" "); } - + override void visit(AST.Dsymbol s) { version(BUILD_COMPILER) @@ -427,13 +428,13 @@ public: buf.printf("// ignored %s %s\n", s.kind(), s.toPrettyChars()); } } - + } - + override void visit(AST.Import) { } - + override void visit(AST.AttribDeclaration pd) { Dsymbols* decl = pd.include(null); @@ -447,7 +448,7 @@ public: } } } - + override void visit(AST.LinkDeclaration ld) { auto save = linkage; @@ -461,7 +462,7 @@ public: visit(cast(AST.AttribDeclaration)ld); linkage = save; } - + override void visit(AST.Module m) { foreach (s; *m.members) @@ -471,7 +472,7 @@ public: s.accept(this); } } - + override void visit(AST.FuncDeclaration fd) { if (cast(void*)fd in visited) @@ -481,10 +482,10 @@ public: if (fd.getModule() && !fd.getModule().isFrontendModule()) return; } - + // printf("FuncDeclaration %s %s\n", fd.toPrettyChars(), fd.type.toChars()); visited[cast(void*)fd] = true; - + auto tf = cast(AST.TypeFunction)fd.type; indent(); if (!tf || !tf.deco) @@ -502,7 +503,7 @@ public: buf.printf("// ignoring function %s because it's extern\n", fd.toPrettyChars()); return; } - + if (tf.linkage == LINK.c) buf.writestring("extern \"C\" "); else if (!adparent) @@ -513,7 +514,7 @@ public: { if (!fd.isOverride()) buf.writestring("virtual "); - + auto s = adparent.search(Loc.initial, fd.ident); if (!(adparent.storage_class & AST.STC.abstract_) && !(cast(AST.ClassDeclaration)adparent).isAbstract() && @@ -540,11 +541,11 @@ public: if (!adparent) buf.printf("\n"); } - + override void visit(AST.UnitTestDeclaration fd) { } - + override void visit(AST.VarDeclaration vd) { if (cast(void*)vd in visited) @@ -554,9 +555,9 @@ public: if (vd.getModule() && !vd.getModule().isFrontendModule()) return; } - + visited[cast(void*)vd] = true; - + if (vd.storage_class & AST.STC.manifest && vd.type.isintegral() && vd._init && vd._init.isExpInitializer()) @@ -575,7 +576,7 @@ public: buf.printf("\n"); return; } - + if (tdparent && vd.type && !vd.type.deco) { indent(); @@ -588,7 +589,7 @@ public: buf.writestring(";\n"); return; } - + if (vd.storage_class & (AST.STC.static_ | AST.STC.extern_ | AST.STC.tls | AST.STC.gshared) || vd.parent && vd.parent.isModule()) { @@ -615,7 +616,7 @@ public: buf.printf("\n"); return; } - + if (adparent && vd.type && vd.type.deco) { indent(); @@ -639,14 +640,14 @@ public: buf = savex; return; } - + visit(cast(AST.Dsymbol)vd); } - + override void visit(AST.TypeInfoDeclaration) { } - + override void visit(AST.AliasDeclaration ad) { version(BUILD_COMPILER) @@ -654,7 +655,7 @@ public: if (ad.getModule() && !ad.getModule().isFrontendModule()) return; } - + if (auto t = ad.type) { if (t.ty == AST.Tdelegate) @@ -693,7 +694,7 @@ public: indent(); buf.printf("// ignored %s %s\n", ad.aliassym.kind(), ad.aliassym.toPrettyChars()); } - + override void visit(AST.AnonDeclaration ad) { buf.writestring(ad.isunion ? "union" : "struct"); @@ -704,7 +705,7 @@ public: } buf.writestring("};\n"); } - + private bool memberField(AST.VarDeclaration vd) { if (!vd.type || !vd.type.deco || !vd.ident) @@ -717,7 +718,7 @@ public: return false; return true; } - + override void visit(AST.StructDeclaration sd) { if (sd.isInstantiated()) @@ -731,9 +732,9 @@ public: if (sd.getModule() && !sd.getModule().isFrontendModule()) return; } - + visited[cast(void*)sd] = true; - + if (sd.alignment == 1) buf.writestring("#pragma pack(push, 1)\n"); buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); @@ -770,7 +771,7 @@ public: } } buf.printf(" }\n"); - + if (varCount) { buf.printf(" %s(", sd.ident.toChars()); @@ -802,12 +803,12 @@ public: } buf.printf(" }\n"); } - + buf.writestring("};\n\n"); - + if (sd.alignment == 1) buf.writestring("#pragma pack(pop)\n"); - + auto savex = buf; buf = checkbuf; buf.writestring(" assert(sizeof("); @@ -818,7 +819,7 @@ public: else buf.writestring(";\n\n"); } - + private void includeSymbol(AST.Dsymbol ds) { // printf("Forward declaring %s %d\n", ds.toChars(), level); @@ -832,7 +833,7 @@ public: donebuf.writestring(decl.peekChars()); } } - + override void visit(AST.ClassDeclaration cd) { if (cast(void*)cd in visited) @@ -844,21 +845,21 @@ public: if (cd.isVisitorClass()) return; } - + visited[cast(void*)cd] = true; if (!cd.isCPPclass()) { buf.printf("// ignoring non-cpp class %s\n", cd.toChars()); return; } - + buf.writestring("class "); buf.writestring(cd.ident.toChars()); if (cd.baseClass) { buf.writestring(" : public "); buf.writestring(cd.baseClass.ident.toChars()); - + includeSymbol(cd.baseClass); } if (cd.members) @@ -879,13 +880,13 @@ public: buf.writestring(" static inline Identifier *idPool(const char *s) { return idPool(s, strlen(s)); }\n"); } } - + buf.writestring("};\n\n"); } else buf.writestring(";\n\n"); } - + override void visit(AST.EnumDeclaration ed) { if (cast(void*)ed in visited) @@ -895,7 +896,7 @@ public: if (ed.getModule() && !ed.getModule().isFrontendModule()) return; } - + visited[cast(void*)ed] = true; if (ed.isSpecial()) return; @@ -928,20 +929,20 @@ public: else buf.writestring(";\n\n"); } - + override void visit(AST.EnumMember em) { buf.writestring(em.ident.toChars()); buf.writestring(" = "); - if (cast(AST.StringExp)em.value) - { - em.value.error("cannot convert string enum"); - return ; - } + //if (cast(AST.StringExp)em.value) + //{ + //em.value.error("cannot convert string enum"); + //return ; + //} auto ie = cast(AST.IntegerExp)em.value; visitInteger(ie.toInteger(), em.ed.memtype); } - + private void typeToBuffer(AST.Type t, Identifier ident) { this.ident = ident; @@ -960,18 +961,18 @@ public: buf.writeByte(']'); } } - + override void visit(AST.Type t) { printf("Invalid type: %s\n", t.toPrettyChars()); assert(0); } - + override void visit(AST.TypeIdentifier t) { buf.writestring(t.ident.toChars()); } - + override void visit(AST.TypeBasic t) { if (!cdparent && t.isConst()) @@ -993,7 +994,7 @@ public: assert(0); } } - + override void visit(AST.TypePointer t) { if (t.next.ty == AST.Tstruct && @@ -1008,17 +1009,17 @@ public: if (!cdparent && t.isConst()) buf.writestring(" const"); } - + override void visit(AST.TypeSArray t) { t.next.accept(this); } - + override void visit(AST.TypeAArray t) { AST.Type.tvoidptr.accept(this); } - + override void visit(AST.TypeFunction tf) { tf.next.accept(this); @@ -1044,7 +1045,7 @@ public: } buf.writeByte(')'); } - + private void enumToBuffer(AST.EnumDeclaration ed) { if (ed.isSpecial()) @@ -1068,7 +1069,7 @@ public: else buf.writestring(ed.toChars()); } - + override void visit(AST.TypeEnum t) { if (cast(void*)t.sym !in forwarded) @@ -1083,7 +1084,7 @@ public: buf.writestring("const "); enumToBuffer(t.sym); } - + override void visit(AST.TypeStruct t) { if (cast(void*)t.sym !in forwarded && @@ -1094,7 +1095,7 @@ public: fwdbuf.writestring(t.sym.toChars()); fwdbuf.writestring(";\n"); } - + if (!cdparent && t.isConst()) buf.writestring("const "); if (auto ti = t.sym.parent.isTemplateInstance()) @@ -1104,7 +1105,7 @@ public: } buf.writestring(t.sym.toChars()); } - + override void visit(AST.TypeDArray t) { if (!cdparent && t.isConst()) @@ -1113,7 +1114,7 @@ public: t.next.accept(this); buf.writestring(">"); } - + private void visitTi(AST.TemplateInstance ti) { version(BUILD_COMPILER) @@ -1162,7 +1163,7 @@ public: } buf.writeByte('>'); } - + override void visit(AST.TemplateDeclaration td) { if (cast(void*)td in visited) @@ -1173,13 +1174,13 @@ public: if (td.getModule() && !td.getModule().isFrontendModule()) return; } - + if (!td.parameters || !td.onemember || !td.onemember.isStructDeclaration()) { visit(cast(AST.Dsymbol)td); return; } - + // Explicitly disallow templates with non-type parameters or specialization. foreach (p; *td.parameters) { @@ -1189,13 +1190,13 @@ public: return; } } - + if (linkage != LINK.c && linkage != LINK.cpp) { buf.printf("// ignoring template %s because of linkage\n", td.toPrettyChars()); return; } - + auto sd = td.onemember.isStructDeclaration(); auto save = tdparent; tdparent = td; @@ -1230,7 +1231,7 @@ public: buf.writestring(";\n\n"); tdparent = save; } - + override void visit(AST.TypeClass t) { if (cast(void*)t.sym !in forwarded) @@ -1240,7 +1241,7 @@ public: fwdbuf.writestring(t.sym.toChars()); fwdbuf.writestring(";\n"); } - + if (!cdparent && t.isConst()) buf.writestring("const "); buf.writestring(t.sym.toChars()); @@ -1248,7 +1249,7 @@ public: if (!cdparent && t.isConst()) buf.writestring(" const"); } - + private void funcToBuffer(AST.TypeFunction tf, Identifier ident) { assert(tf.next); @@ -1257,7 +1258,7 @@ public: buf.writeByte('&'); buf.writeByte(' '); buf.writestring(ident.toChars()); - + buf.writeByte('('); foreach (i; 0 .. AST.Parameter.dim(tf.parameterList.parameters)) { @@ -1274,7 +1275,7 @@ public: } buf.writeByte(')'); } - + override void visit(AST.Parameter p) { ident = p.ident; @@ -1286,31 +1287,49 @@ public: if (ident) buf.writestring(ident.toChars()); ident = null; - if (p.defaultArg) + version (none) + { + if (p.defaultArg && p.defaultArg.op >= 105 && p.defaultArg.op < 152) + { + //printf("%s %d\n", p.defaultArg.toChars, p.defaultArg.op); + buf.writestring(" = "); + buf.writestring(p.defaultArg.toChars()); + } + } + else { - // buf.writestring("/*"); - buf.writestring(" = "); - p.defaultArg.accept(this); - // buf.writestring("*/"); + if (p.defaultArg) + { + //printf("%s %d\n", p.defaultArg.toChars, p.defaultArg.op); + return; + // buf.writestring("/*"); + //buf.writestring(" = "); + //p.defaultArg.accept(this); + // buf.writestring("*/"); + } } } - + override void visit(AST.Expression e) { //e.print(); + printf("====\n%s\n====\n", e.toChars()); + //printf("\n=============\n"); + //printf("%s\n", buf.peekChars()); + //printf("\n=============\n"); assert(0); } - + override void visit(AST.NullExp e) { buf.writestring("_d_null"); } - + override void visit(AST.ArrayLiteralExp e) { buf.writestring("arrayliteral"); } - + override void visit(AST.StringExp e) { assert(e.sz == 1 || e.sz == 2); @@ -1344,17 +1363,17 @@ public: } buf.writeByte('"'); } - + override void visit(AST.RealExp e) { buf.writestring("0"); } - + override void visit(AST.IntegerExp e) { visitInteger(e.toInteger, e.type); } - + private void visitInteger(dinteger_t v, AST.Type t) { switch (t.ty) @@ -1399,7 +1418,7 @@ public: assert(0); } } - + override void visit(AST.StructLiteralExp sle) { buf.writestring(sle.sd.ident.toChars()); @@ -1455,11 +1474,11 @@ void genCppFiles(OutBuffer* buf, Modules *ms) version(BUILD_COMPILER) buf.writestring("struct AA;\n"); buf.writestring("\n"); - + OutBuffer check; check.writestring(` #if OFFSETS - + template size_t getSlotNumber(int dummy, ...) { @@ -1474,11 +1493,11 @@ void genCppFiles(OutBuffer* buf, Modules *ms) } va_end(ap); } - + void testOffsets() { `); - + OutBuffer done; OutBuffer decl; scope v = new ToCppBuffer!ASTCodegen(&check, buf, &done, &decl); @@ -1489,12 +1508,12 @@ void genCppFiles(OutBuffer* buf, Modules *ms) } buf.write(&done); buf.write(&decl); - + check.writestring(` } #endif `); - + debug buf.write(&check); } @@ -1503,6 +1522,7 @@ void gencpphdrfiles(Modules *ms) import dmd.tokens; OutBuffer buf; + buf.writestring("#pragma once\n"); buf.writeByte('\n'); buf.printf("// Automatically generated by dtoh\n"); buf.writeByte('\n'); @@ -1541,11 +1561,11 @@ void gencpphdrfiles(Modules *ms) version(BUILD_COMPILER) buf.writestring("struct AA;\n"); buf.writestring("\n"); - + OutBuffer check; check.writestring(` #if OFFSETS - + template size_t getSlotNumber(int dummy, ...) { @@ -1560,11 +1580,11 @@ void gencpphdrfiles(Modules *ms) } va_end(ap); } - + void testOffsets() { `); - + OutBuffer done; OutBuffer decl; scope v = new ToCppBuffer!ASTCodegen(&check, &buf, &done, &decl); @@ -1575,12 +1595,24 @@ void gencpphdrfiles(Modules *ms) } buf.write(&done); buf.write(&decl); - + check.writestring(` } #endif `); - + debug buf.write(&check); - printf("%s\n", buf.peekChars()); + + if (global.params.cxxhdrname is null) + { + //printf("%s\n", buf.peekChars()); + //// Write to stdout; assume it succeeds + size_t n = fwrite(buf.data, 1, buf.offset, stdout); + assert(n == buf.offset); // keep gcc happy about return values + } + else + { + const(char)[] name = FileName.combine(global.params.cxxhdrdir, global.params.cxxhdrname); + writeFile(Loc.initial, name, buf.peekSlice()); + } } diff --git a/src/dmd/globals.d b/src/dmd/globals.d index aa70bbcd1675..4633eaa41d1d 100644 --- a/src/dmd/globals.d +++ b/src/dmd/globals.d @@ -225,11 +225,14 @@ extern (C++) struct Param Array!(const(char)*) ddocfiles; // macro include files for Ddoc bool doHdrGeneration; // process embedded documentation comments - bool doCxxHdrGeneration; // write 'Cxx header' file const(char)[] hdrdir; // write 'header' file to docdir directory const(char)[] hdrname; // write 'header' file to docname bool hdrStripPlainFunctions = true; // strip the bodies of plain (non-template) functions + bool doCxxHdrGeneration; // write 'Cxx header' file + const(char)[] cxxhdrdir; // write 'header' file to docdir directory + const(char)[] cxxhdrname; // write 'header' file to docname + bool doJsonGeneration; // write JSON file const(char)[] jsonfilename; // write JSON file to jsonfilename JsonFieldFlags jsonFieldFlags; // JSON field flags to include @@ -290,6 +293,7 @@ extern (C++) struct Global string doc_ext = "html"; // for Ddoc generated files string ddoc_ext = "ddoc"; // for Ddoc macro include files string hdr_ext = "di"; // for D 'header' import files + string cxxhdr_ext = "h"; // for C/C++ 'header' files string json_ext = "json"; // for JSON files string map_ext = "map"; // for .map files bool run_noext; // allow -run sources without extensions. diff --git a/src/dmd/mars.d b/src/dmd/mars.d index ab7a2d8e5840..9acde449239b 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -2120,12 +2120,12 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param case 'd': // https://dlang.org/dmd.html#switch-Hd if (!p[4]) goto Lnoarg; - params.hdrdir = (p + 4 + (p[4] == '=')).toDString; + params.cxxhdrdir = (p + 4 + (p[4] == '=')).toDString; break; case 'f': // https://dlang.org/dmd.html#switch-Hf if (!p[4]) goto Lnoarg; - params.hdrname = (p + 4 + (p[4] == '=')).toDString; + params.cxxhdrname = (p + 4 + (p[4] == '=')).toDString; break; case 0: break; From f33421bae4dc2ba763165db7eb546eaafab06cf0 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 18 Jun 2019 11:10:48 +0300 Subject: [PATCH 09/44] wip generate frontend.h --- src/dmd/dtoh.d | 17 ++++++++++++----- src/dmd/mars.d | 15 ++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 003c1adbc333..6d263a60f879 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -370,7 +370,6 @@ version(BUILD_COMPILER) { return false; } - return ((m.parent.ident == DMDModule.dmd && !m.parent.parent) || (m.parent.parent.ident == DMDModule.dmd && !m.parent.parent.parent)); } @@ -1228,7 +1227,7 @@ public: buf.writestring("};\n\n"); } else - buf.writestring(";\n\n"); + buf.writestring(";\n\n"); tdparent = save; } @@ -1313,7 +1312,7 @@ public: override void visit(AST.Expression e) { //e.print(); - printf("====\n%s\n====\n", e.toChars()); + //printf("====\n%s\n====\n", e.toChars()); //printf("\n=============\n"); //printf("%s\n", buf.peekChars()); //printf("\n=============\n"); @@ -1521,6 +1520,14 @@ void gencpphdrfiles(Modules *ms) { import dmd.tokens; + DMDType._init(); + version(BUILD_COMPILER) + { + DMDModule._init(); + DMDClass._init(); + } + setVersions(); + OutBuffer buf; buf.writestring("#pragma once\n"); buf.writeByte('\n'); @@ -1590,6 +1597,7 @@ void gencpphdrfiles(Modules *ms) scope v = new ToCppBuffer!ASTCodegen(&check, &buf, &done, &decl); foreach (m; *ms) { + //printf("// Parsing module %s\n", m.toPrettyChars()); buf.printf("// Parsing module %s\n", m.toPrettyChars()); m.accept(v); } @@ -1605,8 +1613,7 @@ void gencpphdrfiles(Modules *ms) if (global.params.cxxhdrname is null) { - //printf("%s\n", buf.peekChars()); - //// Write to stdout; assume it succeeds + // Write to stdout; assume it succeeds size_t n = fwrite(buf.data, 1, buf.offset, stdout); assert(n == buf.offset); // keep gcc happy about return values } diff --git a/src/dmd/mars.d b/src/dmd/mars.d index 9acde449239b..39edbff790c8 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -597,13 +597,6 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) if (global.errors) fatal(); - if (global.params.doCxxHdrGeneration) - { - gencpphdrfiles(&modules); - } - if (global.errors) - fatal(); - // Scan for functions to inline if (params.useInline) { @@ -674,6 +667,14 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) File.write(cgFilename.ptr, buf[]); } } + + if (global.params.doCxxHdrGeneration) + { + gencpphdrfiles(&modules); + } + if (global.errors) + fatal(); + if (!params.obj) { } From ad4f6f23f5b81a0ad478f538f078f9acd80830fe Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Fri, 21 Jun 2019 18:26:35 +0300 Subject: [PATCH 10/44] Add dtoh enum test --- test/compilable/dtoh_enum.d | 15 ++++++++ .../compilable/extra-files/dtoh-postscript.sh | 5 +++ test/compilable/extra-files/dtoh_enum.out | 36 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 test/compilable/dtoh_enum.d create mode 100644 test/compilable/extra-files/dtoh-postscript.sh create mode 100644 test/compilable/extra-files/dtoh_enum.out diff --git a/test/compilable/dtoh_enum.d b/test/compilable/dtoh_enum.d new file mode 100644 index 000000000000..66fcfd7c1c5f --- /dev/null +++ b/test/compilable/dtoh_enum.d @@ -0,0 +1,15 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_enum.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +enum Dummy +{ + One, + Two +} diff --git a/test/compilable/extra-files/dtoh-postscript.sh b/test/compilable/extra-files/dtoh-postscript.sh new file mode 100644 index 000000000000..92c7f50e2645 --- /dev/null +++ b/test/compilable/extra-files/dtoh-postscript.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +diff -pu --strip-trailing-cr ${EXTRA_FILES}/${TEST_NAME}.out ${OUTPUT_BASE}.out + +rm -f ${OUTPUT_BASE}.out diff --git a/test/compilable/extra-files/dtoh_enum.out b/test/compilable/extra-files/dtoh_enum.out new file mode 100644 index 000000000000..af38cf8961c1 --- /dev/null +++ b/test/compilable/extra-files/dtoh_enum.out @@ -0,0 +1,36 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_enum +enum Dummy +{ + DUMMYOne = 0, + DUMMYTwo = 1 +}; + From eb0e0b88987a17a3f7b1959250fabebe826b276f Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 13:08:57 +0300 Subject: [PATCH 11/44] Add free functions dtoh test --- src/dmd/dtoh.d | 9 +-- test/compilable/dtoh_functions.d | 57 +++++++++++++++++++ .../compilable/extra-files/dtoh_functions.out | 45 +++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 test/compilable/dtoh_functions.d create mode 100644 test/compilable/extra-files/dtoh_functions.out diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 6d263a60f879..0c947e16b8d8 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -1300,11 +1300,12 @@ public: if (p.defaultArg) { //printf("%s %d\n", p.defaultArg.toChars, p.defaultArg.op); - return; - // buf.writestring("/*"); - //buf.writestring(" = "); + //return; + buf.writestring("/*"); + buf.writestring(" = "); + buf.writestring(p.defaultArg.toChars()); //p.defaultArg.accept(this); - // buf.writestring("*/"); + buf.writestring("*/"); } } } diff --git a/test/compilable/dtoh_functions.d b/test/compilable/dtoh_functions.d new file mode 100644 index 000000000000..07a3225fa37b --- /dev/null +++ b/test/compilable/dtoh_functions.d @@ -0,0 +1,57 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_functions.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +int foo(int x) +{ + return x * 42; +} + +extern (C) int fun(); +extern (C++) int fun2(); + +extern (C) int bar(int x) +{ + return x * 42; +} + +extern (C) static int bar2(int x) +{ + return x * 42; +} + +extern (C) private int bar3(int x) +{ + return x * 42; +} + +extern (C) int bar4(int x = 42) +{ + return x * 42; +} + +extern (C++) int baz(int x) +{ + return x * 42; +} + +extern (C++) static int baz2(int x) +{ + return x * 42; +} + +extern (C++) private int baz3(int x) +{ + return x * 42; +} + +extern (C++) int baz3(int x = 42) +{ + return x * 42; +} diff --git a/test/compilable/extra-files/dtoh_functions.out b/test/compilable/extra-files/dtoh_functions.out new file mode 100644 index 000000000000..82ce865c63c4 --- /dev/null +++ b/test/compilable/extra-files/dtoh_functions.out @@ -0,0 +1,45 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_functions +// ignoring function dtoh_functions.foo because of linkage +// ignoring function dtoh_functions.fun because it's extern +// ignoring function dtoh_functions.fun2 because it's extern +extern "C" _d_int bar(_d_int x); + +extern "C" _d_int bar2(_d_int x); + +extern "C" _d_int bar4(_d_int x/* = 42*/); + +extern _d_int baz(_d_int x); + +extern _d_int baz2(_d_int x); + +extern _d_int baz3(_d_int x/* = 42*/); + From 8b5ecfee72d92c689e11492fcaec3a1265c998b8 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 13:17:25 +0300 Subject: [PATCH 12/44] Add unittest block dtoh test --- test/compilable/dtoh_unittest_block.d | 17 +++++++++++ .../extra-files/dtoh_unittest_block.out | 30 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/compilable/dtoh_unittest_block.d create mode 100644 test/compilable/extra-files/dtoh_unittest_block.out diff --git a/test/compilable/dtoh_unittest_block.d b/test/compilable/dtoh_unittest_block.d new file mode 100644 index 000000000000..da9fc0c5d276 --- /dev/null +++ b/test/compilable/dtoh_unittest_block.d @@ -0,0 +1,17 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_unittest_block.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +unittest +{ + extern (C++) int foo(int x) + { + return x * 42; + } +} diff --git a/test/compilable/extra-files/dtoh_unittest_block.out b/test/compilable/extra-files/dtoh_unittest_block.out new file mode 100644 index 000000000000..ee8da2190774 --- /dev/null +++ b/test/compilable/extra-files/dtoh_unittest_block.out @@ -0,0 +1,30 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_unittest_block From 6d4dca2b2502745f8d2bbf066c672514e25fbca8 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 13:35:33 +0300 Subject: [PATCH 13/44] Add VarDeclaration dtoh test --- test/compilable/dtoh_VarDeclaration.d | 29 ++++++++++++ .../extra-files/dtoh_VarDeclaration.out | 47 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/compilable/dtoh_VarDeclaration.d create mode 100644 test/compilable/extra-files/dtoh_VarDeclaration.out diff --git a/test/compilable/dtoh_VarDeclaration.d b/test/compilable/dtoh_VarDeclaration.d new file mode 100644 index 000000000000..0f249e9b9e0a --- /dev/null +++ b/test/compilable/dtoh_VarDeclaration.d @@ -0,0 +1,29 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_VarDeclaration.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +int x = 42; + +extern int y; + +extern (C) int z; + +extern (C++) __gshared int t; + +extern (C) struct S; + +extern (C++) struct S2; + +extern (C) class C; + +extern (C++) class C2; + +extern (C) union U; + +extern (C++) union U2; diff --git a/test/compilable/extra-files/dtoh_VarDeclaration.out b/test/compilable/extra-files/dtoh_VarDeclaration.out new file mode 100644 index 000000000000..01a9d0bc6529 --- /dev/null +++ b/test/compilable/extra-files/dtoh_VarDeclaration.out @@ -0,0 +1,47 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_VarDeclaration +// ignoring variable dtoh_VarDeclaration.x because of linkage +// ignoring variable dtoh_VarDeclaration.y because of linkage +extern "C" _d_int z; + +extern _d_int t; + +struct S; + +struct S2; + +// ignoring non-cpp class C +class C2; + +union U; + +union U2; + From 5b4ee56cbe3c9a58ba033b013934cf8e54c2738b Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 13:45:54 +0300 Subject: [PATCH 14/44] Add AliasDeclaration dtoh test --- test/compilable/dtoh_AliasDeclaration.d | 45 ++++++++++++++ .../extra-files/dtoh_AliasDeclaration.out | 60 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 test/compilable/dtoh_AliasDeclaration.d create mode 100644 test/compilable/extra-files/dtoh_AliasDeclaration.out diff --git a/test/compilable/dtoh_AliasDeclaration.d b/test/compilable/dtoh_AliasDeclaration.d new file mode 100644 index 000000000000..ced46ff95850 --- /dev/null +++ b/test/compilable/dtoh_AliasDeclaration.d @@ -0,0 +1,45 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_AliasDeclaration.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +alias T = int; + +extern (C) int x; + +alias u = x; + +extern (C) int foo(int x) +{ + return x * 42; +} + +alias fun = foo; + +extern (C++) int foo2(int x) +{ + return x * 42; +} + +alias fun2 = foo2; + +extern (C) struct S; + +alias aliasS = S; + +extern (C++) struct S2; + +alias aliasS2 = S2; + +extern (C) class C; + +alias aliasC = C; + +extern (C++) class C2; + +alias aliasC2 = C2; diff --git a/test/compilable/extra-files/dtoh_AliasDeclaration.out b/test/compilable/extra-files/dtoh_AliasDeclaration.out new file mode 100644 index 000000000000..fae9ccab9ed8 --- /dev/null +++ b/test/compilable/extra-files/dtoh_AliasDeclaration.out @@ -0,0 +1,60 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_AliasDeclaration +struct S; +struct S2; +class C; +class C2; +typedef _d_int T; + +extern "C" _d_int x; + +// ignored variable dtoh_AliasDeclaration.x +extern "C" _d_int foo(_d_int x); + +// ignored function dtoh_AliasDeclaration.foo +extern _d_int foo2(_d_int x); + +// ignored function dtoh_AliasDeclaration.foo2 +struct S; + +typedef S aliasS; + +struct S2; + +typedef S2 aliasS2; + +// ignoring non-cpp class C +typedef C* aliasC; + +class C2; + +typedef C2* aliasC2; + From 8cdb6a32aa07591811b3d9be834cedd2e8a2f773 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 14:08:43 +0300 Subject: [PATCH 15/44] Add AnonDeclaration dtoh test --- src/dmd/dtoh.d | 8 +++- test/compilable/dtoh_AnonDeclaration.d | 26 ++++++++++ .../extra-files/dtoh_AnonDeclaration.out | 47 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 test/compilable/dtoh_AnonDeclaration.d create mode 100644 test/compilable/extra-files/dtoh_AnonDeclaration.out diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 0c947e16b8d8..630fb7406f7c 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -696,12 +696,16 @@ public: override void visit(AST.AnonDeclaration ad) { - buf.writestring(ad.isunion ? "union" : "struct"); - buf.writestring("\n{\n"); + indent(); + buf.writestring(ad.isunion ? "union\n" : "struct\n"); + indent(); + buf.writestring("{\n"); foreach (s; *ad.decl) { + indent(); s.accept(this); } + indent(); buf.writestring("};\n"); } diff --git a/test/compilable/dtoh_AnonDeclaration.d b/test/compilable/dtoh_AnonDeclaration.d new file mode 100644 index 000000000000..e1936f62c441 --- /dev/null +++ b/test/compilable/dtoh_AnonDeclaration.d @@ -0,0 +1,26 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_AnonDeclaration.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +struct S +{ + union + { + int x; + char[4] c; + } + + struct + { + int y; + double z; + extern(C) void foo() {} + extern(C++) void bar() {} + } +} diff --git a/test/compilable/extra-files/dtoh_AnonDeclaration.out b/test/compilable/extra-files/dtoh_AnonDeclaration.out new file mode 100644 index 000000000000..0e9094351747 --- /dev/null +++ b/test/compilable/extra-files/dtoh_AnonDeclaration.out @@ -0,0 +1,47 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_AnonDeclaration +struct S +{ + union + { + _d_int x; + _d_char c[4LLU]; + }; + struct + { + _d_int y; + _d_double z; + extern "C" _d_void foo(); + _d_void bar(); + }; + S() { } +}; + From e4d42a53a8047d9ceff98fe987ad5366005f195b Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 15:12:26 +0300 Subject: [PATCH 16/44] Add StructDeclaration dtoh test --- src/dmd/dtoh.d | 2 +- test/compilable/dtoh_StructDeclaration.d | 87 ++++++++++++++ .../extra-files/dtoh_StructDeclaration.out | 106 ++++++++++++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 test/compilable/dtoh_StructDeclaration.d create mode 100644 test/compilable/extra-files/dtoh_StructDeclaration.out diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 630fb7406f7c..5e2b45e3c261 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -739,7 +739,7 @@ public: visited[cast(void*)sd] = true; if (sd.alignment == 1) - buf.writestring("#pragma pack(push, 1)\n"); + buf.writestring("#pragma pack(push, 1)\n"); buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); buf.writestring(sd.ident.toChars()); if (sd.members) diff --git a/test/compilable/dtoh_StructDeclaration.d b/test/compilable/dtoh_StructDeclaration.d new file mode 100644 index 000000000000..8b59039fbd70 --- /dev/null +++ b/test/compilable/dtoh_StructDeclaration.d @@ -0,0 +1,87 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_StructDeclaration.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +/* +StructDeclaration has the following issues: + * align different than 1 does nothing; we should support align(n), where `n` in [1, 2, 4, 8, 16] + * align(n): inside struct definition doesn’t add alignment, but breaks generation of default ctors + * default ctors should be generated only if struct has no ctors + * if a struct has ctors defined, only default ctor (S() { … }) should be generated to init members to default values, and the defined ctors must be declared + * if a struct has ctors defined, the declared ctors must have the name of the struct, not __ctor, as `__ctor` might not be portable + * if a struct has a `member = void`, dtoh code segfaults + * a struct should only define ctors if it’s extern (C++) +*/ + +struct S +{ + byte a; + int b; + long c; +} + +extern (C++) struct S2 +{ + int a = 42; + int b; + long c; + + this(int a) {} +} + +extern (C) struct S3 +{ + int a = 42; + int b; + long c; + + this(int a) {} +} + +align(1) struct Aligned +{ + //align(1): + byte a; + int b; + long c; + + this(int a) {} +} + +struct A +{ + int a; + S s; + + void foo(); + extern (C) void bar() {} + extern (C++) void baz(int x = 42) {} + + struct + { + int x; + int y; + } + + union + { + int u1; + char[4] u2; + } + + struct Inner + { + int x; + } + + alias I = Inner; + + extern(C++) class C; + +} diff --git a/test/compilable/extra-files/dtoh_StructDeclaration.out b/test/compilable/extra-files/dtoh_StructDeclaration.out new file mode 100644 index 000000000000..0af77b9bd4e2 --- /dev/null +++ b/test/compilable/extra-files/dtoh_StructDeclaration.out @@ -0,0 +1,106 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_StructDeclaration +struct S2; +struct S3; +struct S; +struct Inner; +struct S +{ + _d_byte a; + _d_int b; + _d_long c; + S() { this->a = 0; this->b = 0; this->c = 0LL; } + S(_d_byte a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } +}; + +struct S2 +{ + _d_int a; + _d_int b; + _d_long c; + S2& __ctor(_d_int a); + S2() { this->a = 42; this->b = 0; this->c = 0LL; } + S2(_d_int a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } +}; + +struct S3 +{ + _d_int a; + _d_int b; + _d_long c; + extern "C" S3& __ctor(_d_int a); + S3() { this->a = 42; this->b = 0; this->c = 0LL; } + S3(_d_int a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } +}; + +#pragma pack(push, 1) +struct Aligned +{ + _d_byte a; + _d_int b; + _d_long c; + // ignoring function dtoh_StructDeclaration.Aligned.this because of linkage + Aligned() { this->a = 0; this->b = 0; this->c = 0LL; } + Aligned(_d_byte a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } +}; + +#pragma pack(pop) +struct A +{ + _d_int a; + S s; + // ignoring function dtoh_StructDeclaration.A.foo because of linkage + extern "C" _d_void bar(); + _d_void baz(_d_int x/* = 42*/); + struct + { + _d_int x; + _d_int y; + }; + union + { + _d_int u1; + _d_char u2[4LLU]; + }; +struct Inner +{ + _d_int x; + Inner() { this->x = 0; } + Inner(_d_int x) { this->x = x; } +}; + +typedef Inner I; +class C; + + A() { this->a = 0; } + A(_d_int a, S s) { this->a = a; this->s = s; } +}; + From 66cfd166e1e365adb78ef80e2ce264bbffb8b9bc Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 15:40:24 +0300 Subject: [PATCH 17/44] Add ClassDeclaration dtoh test --- test/compilable/dtoh_ClassDeclaration.d | 90 +++++++++++++++ .../extra-files/dtoh_ClassDeclaration.out | 105 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 test/compilable/dtoh_ClassDeclaration.d create mode 100644 test/compilable/extra-files/dtoh_ClassDeclaration.out diff --git a/test/compilable/dtoh_ClassDeclaration.d b/test/compilable/dtoh_ClassDeclaration.d new file mode 100644 index 000000000000..2586e6409fa3 --- /dev/null +++ b/test/compilable/dtoh_ClassDeclaration.d @@ -0,0 +1,90 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_ClassDeclaration.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +/* +ClassDeclaration has the following issues: + * align(n) does nothing. You can use align on classes in C++, though It is generally regarded as bad practice and should be avoided +*/ + +extern (C++) class C +{ + byte a; + int b; + long c; +} + +extern (C++) class C2 +{ + int a = 42; + int b; + long c; + + this(int a) {} +} + +extern (C) class C3 +{ + int a = 42; + int b; + long c; + + this(int a) {} +} + +extern (C++) align(1) class Aligned +{ + byte a; + int b; + long c; + + this(int a) {} +} + +extern (C++) class A +{ + int a; + C c; + + void foo(); + extern (C) void bar() {} + extern (C++) void baz(int x = 42) {} + + struct + { + int x; + int y; + } + + union + { + int u1; + char[4] u2; + } + + struct Inner + { + int x; + } + + static extern(C++) class InnerC + { + int x; + } + + class NonStaticInnerC + { + int x; + } + + alias I = Inner; + + extern(C++) class CC; + +} diff --git a/test/compilable/extra-files/dtoh_ClassDeclaration.out b/test/compilable/extra-files/dtoh_ClassDeclaration.out new file mode 100644 index 000000000000..e2eac0b780bb --- /dev/null +++ b/test/compilable/extra-files/dtoh_ClassDeclaration.out @@ -0,0 +1,105 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_ClassDeclaration +class C2; +class Aligned; +class C; +class A; +struct Inner; +class C +{ +public: + _d_byte a; + _d_int b; + _d_long c; +}; + +class C2 +{ +public: + _d_int a; + _d_int b; + _d_long c; + C2* __ctor(_d_int a); +}; + +// ignoring non-cpp class C3 +class Aligned +{ +public: + _d_byte a; + _d_int b; + _d_long c; + Aligned* __ctor(_d_int a); +}; + +class A +{ +public: + _d_int a; + C* c; + virtual _d_void foo(); + extern "C" virtual _d_void bar(); + virtual _d_void baz(_d_int x/* = 42*/); + struct + { + _d_int x; + _d_int y; + }; + union + { + _d_int u1; + _d_char u2[4LLU]; + }; +struct Inner +{ + _d_int x; + Inner() { this->x = 0; } + Inner(_d_int x) { this->x = x; } +}; + +class InnerC +{ +public: + _d_int x; +}; + +class NonStaticInnerC +{ +public: + _d_int x; + A* this; +}; + +typedef Inner I; +class CC; + +}; + From 11623146d183fee19bf27b33796dca5348400e7e Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 24 Jun 2019 18:03:18 +0300 Subject: [PATCH 18/44] Add TemplateDeclaration dtoh test --- test/compilable/dtoh_TemplateDeclaration.d | 22 ++++++++++ .../extra-files/dtoh_TemplateDeclaration.out | 44 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 test/compilable/dtoh_TemplateDeclaration.d create mode 100644 test/compilable/extra-files/dtoh_TemplateDeclaration.out diff --git a/test/compilable/dtoh_TemplateDeclaration.d b/test/compilable/dtoh_TemplateDeclaration.d new file mode 100644 index 000000000000..b5eb7be5bfee --- /dev/null +++ b/test/compilable/dtoh_TemplateDeclaration.d @@ -0,0 +1,22 @@ +// REQUIRED_ARGS: -HCf=${RESULTS_DIR}/compilable/dtoh_TemplateDeclaration.out -c +// PERMUTE_ARGS: +// POST_SCRIPT: compilable/extra-files/dtoh-postscript.sh + +/* +TEST_OUTPUT: +--- +--- +*/ + +extern (C++) struct A(T) +{ + T x; + // enum Num = 42; // dtoh segfaults at enum + + void foo() {} +} + +extern (C++) struct B +{ + A!int x; +} diff --git a/test/compilable/extra-files/dtoh_TemplateDeclaration.out b/test/compilable/extra-files/dtoh_TemplateDeclaration.out new file mode 100644 index 000000000000..95a7034a74e6 --- /dev/null +++ b/test/compilable/extra-files/dtoh_TemplateDeclaration.out @@ -0,0 +1,44 @@ +#pragma once + +// Automatically generated by dtoh + +#include +#include +#include +#include + +#define _d_void void +#define _d_bool bool +#define _d_byte signed char +#define _d_ubyte unsigned char +#define _d_short short +#define _d_ushort unsigned short +#define _d_int int +#define _d_uint unsigned +#define _d_long long +#define _d_ulong unsigned long +#define _d_float float +#define _d_double double +#define _d_real long double +#define _d_char char +#define _d_wchar wchar_t +#define _d_dchar unsigned + +#define _d_null NULL + + +// Parsing module dtoh_TemplateDeclaration +template +struct A +{ + T x; + // ignoring function foo because semantic hasn't been run +}; + +struct B +{ + A<_d_int> x; + B() { } + B(A<_d_int> x) { this->x = x; } +}; + From 645dcd79c1c38d52c6c49c2184a2b4972546e69e Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Thu, 4 Jul 2019 11:45:05 +0300 Subject: [PATCH 19/44] Add debug prints --- src/dmd/dtoh.d | 222 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 3 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 5e2b45e3c261..0e4075db3ebc 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -30,6 +30,8 @@ import dmd.visitor; import dmd.root.outbuffer; import dmd.utils; +//debug = Debug_DtoH; + version(BUILD_COMPILER) { immutable string[] sources = [ @@ -419,6 +421,11 @@ public: override void visit(AST.Dsymbol s) { + debug (Debug_DtoH) + { + printf("[AST.Dsymbol enter] %s\n", s.toChars()); + scope(exit) printf("[AST.Dsymbol exit] %s\n", s.toChars()); + } version(BUILD_COMPILER) { if (s.getModule() && s.getModule().isFrontendModule()) @@ -430,12 +437,22 @@ public: } - override void visit(AST.Import) + override void visit(AST.Import i) { + debug (Debug_DtoH) + { + printf("[AST.Import enter] %s\n", i.toChars()); + scope(exit) printf("[AST.Import exit] %s\n", i.toChars()); + } } override void visit(AST.AttribDeclaration pd) { + debug (Debug_DtoH) + { + printf("[AST.AttribDeclaration enter] %s\n", pd.toChars()); + scope(exit) printf("[AST.AttribDeclaration exit] %s\n", pd.toChars()); + } Dsymbols* decl = pd.include(null); if (decl) { @@ -450,6 +467,11 @@ public: override void visit(AST.LinkDeclaration ld) { + debug (Debug_DtoH) + { + printf("[AST.LinkDeclaration enter] %s\n", ld.toChars()); + scope(exit) printf("[AST.LinkDeclaration exit] %s\n", ld.toChars()); + } auto save = linkage; linkage = ld.linkage; if (ld.linkage != LINK.c && ld.linkage != LINK.cpp) @@ -464,6 +486,11 @@ public: override void visit(AST.Module m) { + debug (Debug_DtoH) + { + printf("[AST.Module enter] %s\n", m.toChars()); + scope(exit) printf("[AST.Module exit] %s\n", m.toChars()); + } foreach (s; *m.members) { if (s.prot().kind < AST.Prot.Kind.public_) @@ -474,6 +501,11 @@ public: override void visit(AST.FuncDeclaration fd) { + debug (Debug_DtoH) + { + printf("[AST.FuncDeclaration enter] %s\n", fd.toChars()); + scope(exit) printf("[AST.FuncDeclaration exit] %s\n", fd.toChars()); + } if (cast(void*)fd in visited) return; version(BUILD_COMPILER) @@ -541,12 +573,22 @@ public: buf.printf("\n"); } - override void visit(AST.UnitTestDeclaration fd) + override void visit(AST.UnitTestDeclaration utd) { + debug (Debug_DtoH) + { + printf("[AST.UnitTestDeclaration enter] %s\n", utd.toChars()); + scope(exit) printf("[AST.UnitTestDeclaration exit] %s\n", utd.toChars()); + } } override void visit(AST.VarDeclaration vd) { + debug (Debug_DtoH) + { + printf("[AST.VarDeclaration enter] %s\n", vd.toChars()); + scope(exit) printf("[AST.VarDeclaration exit] %s\n", vd.toChars()); + } if (cast(void*)vd in visited) return; version(BUILD_COMPILER) @@ -618,6 +660,8 @@ public: if (adparent && vd.type && vd.type.deco) { + //printf("Here %s\n", vd.toChars()); + //printf("Za buff\n====\n%s\n====\n", buf.peekChars()); indent(); auto save = cdparent; cdparent = vd.isField() ? adparent.isClassDeclaration() : null; @@ -643,12 +687,22 @@ public: visit(cast(AST.Dsymbol)vd); } - override void visit(AST.TypeInfoDeclaration) + override void visit(AST.TypeInfoDeclaration tid) { + debug (Debug_DtoH) + { + printf("[AST.TypeInfoDeclaration enter] %s\n", tid.toChars()); + scope(exit) printf("[AST.TypeInfoDeclaration exit] %s\n", tid.toChars()); + } } override void visit(AST.AliasDeclaration ad) { + debug (Debug_DtoH) + { + printf("[AST.AliasDeclaration enter] %s\n", ad.toChars()); + scope(exit) printf("[AST.AliasDeclaration exit] %s\n", ad.toChars()); + } version(BUILD_COMPILER) { if (ad.getModule() && !ad.getModule().isFrontendModule()) @@ -696,6 +750,11 @@ public: override void visit(AST.AnonDeclaration ad) { + debug (Debug_DtoH) + { + printf("[AST.AnonDeclaration enter] %s\n", ad.toChars()); + scope(exit) printf("[AST.AnonDeclaration exit] %s\n", ad.toChars()); + } indent(); buf.writestring(ad.isunion ? "union\n" : "struct\n"); indent(); @@ -724,6 +783,11 @@ public: override void visit(AST.StructDeclaration sd) { + debug (Debug_DtoH) + { + printf("[AST.StructDeclaration enter] %s\n", sd.toChars()); + scope(exit) printf("[AST.StructDeclaration exit] %s\n", sd.toChars()); + } if (sd.isInstantiated()) return; if (cast(void*)sd in visited) @@ -825,6 +889,11 @@ public: private void includeSymbol(AST.Dsymbol ds) { + debug (Debug_DtoH) + { + printf("[includeSymbol(AST.Dsymbol) enter] %s\n", ds.toChars()); + scope(exit) printf("[includeSymbol(AST.Dsymbol) exit] %s\n", ds.toChars()); + } // printf("Forward declaring %s %d\n", ds.toChars(), level); if (cast(void*)ds !in visited) { @@ -839,6 +908,11 @@ public: override void visit(AST.ClassDeclaration cd) { + debug (Debug_DtoH) + { + printf("[AST.ClassDeclaration enter] %s\n", cd.toChars()); + scope(exit) printf("[AST.ClassDeclaration exit] %s\n", cd.toChars()); + } if (cast(void*)cd in visited) return; version(BUILD_COMPILER) @@ -892,6 +966,11 @@ public: override void visit(AST.EnumDeclaration ed) { + debug (Debug_DtoH) + { + printf("[AST.EnumDeclaration enter] %s\n", ed.toChars()); + scope(exit) printf("[AST.EnumDeclaration exit] %s\n", ed.toChars()); + } if (cast(void*)ed in visited) return; version(BUILD_COMPILER) @@ -935,6 +1014,11 @@ public: override void visit(AST.EnumMember em) { + debug (Debug_DtoH) + { + printf("[AST.EnumMember enter] %s\n", em.toChars()); + scope(exit) printf("[AST.EnumMember exit] %s\n", em.toChars()); + } buf.writestring(em.ident.toChars()); buf.writestring(" = "); //if (cast(AST.StringExp)em.value) @@ -948,8 +1032,19 @@ public: private void typeToBuffer(AST.Type t, Identifier ident) { + debug (Debug_DtoH) + { + printf("[typeToBuffer(AST.Type) enter] %s ident %s\n", t.toChars(), ident.toChars()); + scope(exit) printf("[typeToBuffer(AST.Type) exit] %s ident %s\n", t.toChars(), ident.toChars()); + } this.ident = ident; + //printf("====\nBefore\n"); + //printf("buf\n%s\n", buf.peekChars()); + //printf("fwdbuf\n%s\n", fwdbuf.peekChars()); t.accept(this); + //printf("After\n====\n"); + //printf("fwdbuf\n%s\n", fwdbuf.peekChars()); + //printf("\n====\n"); if (this.ident) { buf.writeByte(' '); @@ -967,17 +1062,32 @@ public: override void visit(AST.Type t) { + debug (Debug_DtoH) + { + printf("[AST.Type enter] %s\n", t.toChars()); + scope(exit) printf("[AST.Type exit] %s\n", t.toChars()); + } printf("Invalid type: %s\n", t.toPrettyChars()); assert(0); } override void visit(AST.TypeIdentifier t) { + debug (Debug_DtoH) + { + printf("[AST.TypeIdentifier enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeIdentifier exit] %s\n", t.toChars()); + } buf.writestring(t.ident.toChars()); } override void visit(AST.TypeBasic t) { + debug (Debug_DtoH) + { + printf("[AST.TypeBasic enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeBasic exit] %s\n", t.toChars()); + } if (!cdparent && t.isConst()) buf.writestring("const "); switch (t.ty) @@ -1000,6 +1110,11 @@ public: override void visit(AST.TypePointer t) { + debug (Debug_DtoH) + { + printf("[AST.TypePointer enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypePointer exit] %s\n", t.toChars()); + } if (t.next.ty == AST.Tstruct && !strcmp((cast(AST.TypeStruct)t.next).sym.ident.toChars(), "__va_list_tag")) { @@ -1015,16 +1130,31 @@ public: override void visit(AST.TypeSArray t) { + debug (Debug_DtoH) + { + printf("[AST.TypeSArray enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeSArray exit] %s\n", t.toChars()); + } t.next.accept(this); } override void visit(AST.TypeAArray t) { + debug (Debug_DtoH) + { + printf("[AST.TypeAArray enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeAArray exit] %s\n", t.toChars()); + } AST.Type.tvoidptr.accept(this); } override void visit(AST.TypeFunction tf) { + debug (Debug_DtoH) + { + printf("[AST.TypeFunction enter] %s\n", tf.toChars()); + scope(exit) printf("[AST.TypeFunction exit] %s\n", tf.toChars()); + } tf.next.accept(this); buf.writeByte('('); buf.writeByte('*'); @@ -1051,6 +1181,11 @@ public: private void enumToBuffer(AST.EnumDeclaration ed) { + debug (Debug_DtoH) + { + printf("[enumToBuffer(AST.EnumDeclaration) enter] %s\n", ed.toChars()); + scope(exit) printf("[enumToBuffer(AST.EnumDeclaration) exit] %s\n", ed.toChars()); + } if (ed.isSpecial()) { if (ed.ident == DMDType.c_long) @@ -1075,11 +1210,17 @@ public: override void visit(AST.TypeEnum t) { + debug (Debug_DtoH) + { + printf("[AST.TypeEnum enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeEnum exit] %s\n", t.toChars()); + } if (cast(void*)t.sym !in forwarded) { forwarded[cast(void*)t.sym] = true; auto save = buf; buf = fwdbuf; + //printf("Visiting enum %s from module %s %s\n", t.sym.toPrettyChars(), t.toChars(), t.sym.loc.toChars()); t.sym.accept(this); buf = save; } @@ -1090,6 +1231,11 @@ public: override void visit(AST.TypeStruct t) { + debug (Debug_DtoH) + { + printf("[AST.TypeStruct enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeStruct exit] %s\n", t.toChars()); + } if (cast(void*)t.sym !in forwarded && !t.sym.parent.isTemplateInstance()) { @@ -1111,6 +1257,11 @@ public: override void visit(AST.TypeDArray t) { + debug (Debug_DtoH) + { + printf("[AST.TypeDArray enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeDArray exit] %s\n", t.toChars()); + } if (!cdparent && t.isConst()) buf.writestring("const "); buf.writestring("DArray<"); @@ -1120,6 +1271,11 @@ public: private void visitTi(AST.TemplateInstance ti) { + debug (Debug_DtoH) + { + printf("[visitTi(AST.TemplateInstance) enter] %s\n", ti.toChars()); + scope(exit) printf("[visitTi(AST.TemplateInstance) exit] %s\n", ti.toChars()); + } version(BUILD_COMPILER) { if (ti.tempdecl.ident == DMDType.AssocArray) @@ -1169,6 +1325,11 @@ public: override void visit(AST.TemplateDeclaration td) { + debug (Debug_DtoH) + { + printf("[AST.TemplateDeclaration enter] %s\n", td.toChars()); + scope(exit) printf("[AST.TemplateDeclaration exit] %s\n", td.toChars()); + } if (cast(void*)td in visited) return; visited[cast(void*)td] = true; @@ -1237,6 +1398,11 @@ public: override void visit(AST.TypeClass t) { + debug (Debug_DtoH) + { + printf("[AST.TypeClass enter] %s\n", t.toChars()); + scope(exit) printf("[AST.TypeClass exit] %s\n", t.toChars()); + } if (cast(void*)t.sym !in forwarded) { forwarded[cast(void*)t.sym] = true; @@ -1255,6 +1421,11 @@ public: private void funcToBuffer(AST.TypeFunction tf, Identifier ident) { + debug (Debug_DtoH) + { + printf("[funcToBuffer(AST.TypeFunction) enter] %s\n", tf.toChars()); + scope(exit) printf("[funcToBuffer(AST.TypeFunction) exit] %s\n", tf.toChars()); + } assert(tf.next); tf.next.accept(this); if (tf.isref) @@ -1281,6 +1452,11 @@ public: override void visit(AST.Parameter p) { + debug (Debug_DtoH) + { + printf("[AST.Parameter enter] %s\n", p.toChars()); + scope(exit) printf("[AST.Parameter exit] %s\n", p.toChars()); + } ident = p.ident; p.type.accept(this); assert(!(p.storageClass & ~(AST.STC.ref_))); @@ -1316,6 +1492,11 @@ public: override void visit(AST.Expression e) { + debug (Debug_DtoH) + { + printf("[AST.Expression enter] %s\n", e.toChars()); + scope(exit) printf("[AST.Expression exit] %s\n", e.toChars()); + } //e.print(); //printf("====\n%s\n====\n", e.toChars()); //printf("\n=============\n"); @@ -1326,16 +1507,31 @@ public: override void visit(AST.NullExp e) { + debug (Debug_DtoH) + { + printf("[AST.NullExp enter] %s\n", e.toChars()); + scope(exit) printf("[AST.NullExp exit] %s\n", e.toChars()); + } buf.writestring("_d_null"); } override void visit(AST.ArrayLiteralExp e) { + debug (Debug_DtoH) + { + printf("[AST.ArrayLiteralExp enter] %s\n", e.toChars()); + scope(exit) printf("[AST.ArrayLiteralExp exit] %s\n", e.toChars()); + } buf.writestring("arrayliteral"); } override void visit(AST.StringExp e) { + debug (Debug_DtoH) + { + printf("[AST.StringExp enter] %s\n", e.toChars()); + scope(exit) printf("[AST.StringExp exit] %s\n", e.toChars()); + } assert(e.sz == 1 || e.sz == 2); if (e.sz == 2) buf.writeByte('L'); @@ -1370,16 +1566,31 @@ public: override void visit(AST.RealExp e) { + debug (Debug_DtoH) + { + printf("[AST.RealExp enter] %s\n", e.toChars()); + scope(exit) printf("[AST.RealExp exit] %s\n", e.toChars()); + } buf.writestring("0"); } override void visit(AST.IntegerExp e) { + debug (Debug_DtoH) + { + printf("[AST.IntegerExp enter] %s\n", e.toChars()); + scope(exit) printf("[AST.IntegerExp exit] %s\n", e.toChars()); + } visitInteger(e.toInteger, e.type); } private void visitInteger(dinteger_t v, AST.Type t) { + debug (Debug_DtoH) + { + printf("[visitInteger(AST.Type) enter] %s\n", t.toChars()); + scope(exit) printf("[visitInteger(AST.Type) exit] %s\n", t.toChars()); + } switch (t.ty) { case AST.Tenum: @@ -1425,6 +1636,11 @@ public: override void visit(AST.StructLiteralExp sle) { + debug (Debug_DtoH) + { + printf("[AST.StructLiteralExp enter] %s\n", sle.toChars()); + scope(exit) printf("[AST.StructLiteralExp exit] %s\n", sle.toChars()); + } buf.writestring(sle.sd.ident.toChars()); buf.writeByte('('); foreach(i, e; *sle.elements) From 63891deef4bf7e485f491f4502c50f67e2d06f1e Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Thu, 4 Jul 2019 16:19:03 +0300 Subject: [PATCH 20/44] Fix struct field void initializer --- src/dmd/dtoh.d | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 0e4075db3ebc..c083c79cc9ca 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -829,6 +829,8 @@ public: varCount++; if (!vd._init && !vd.type.isTypeBasic()) continue; + if (vd._init && vd._init.isVoidInitializer()) + continue; buf.printf(" this->%s = ", vd.ident.toChars()); if (vd._init) AST.initializerToExpression(vd._init).accept(this); From 416e6cd6a3dcb53f83fdd46176713c550150ae5b Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 15 Jul 2019 16:34:31 +0300 Subject: [PATCH 21/44] Generate frontend header files and compile and run cxxfrontend test --- src/dmd/dtoh.d | 116 +++++++++++++++------------ src/dmd/root/dcompat.h | 8 ++ src/tests/cxxfrontend.c | 169 +++++++++++++++++----------------------- 3 files changed, 146 insertions(+), 147 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index c083c79cc9ca..eafab2298c8a 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -270,11 +270,11 @@ struct DMDType __gshared static Identifier c_longlong; __gshared static Identifier c_ulonglong; __gshared static Identifier c_long_double; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ __gshared static Identifier AssocArray; __gshared static Identifier Array; - } + //} static void _init() { c_long = Identifier.idPool("__c_long"); @@ -282,16 +282,16 @@ struct DMDType c_longlong = Identifier.idPool("__c_longlong"); c_ulonglong = Identifier.idPool("__c_ulonglong"); c_long_double = Identifier.idPool("__c_long_double"); - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ AssocArray = Identifier.idPool("AssocArray"); Array = Identifier.idPool("Array"); - } + //} } } -version(BUILD_COMPILER) -{ +//version(BUILD_COMPILER) +//{ struct DMDModule { __gshared static Identifier identifier; @@ -385,7 +385,7 @@ version(BUILD_COMPILER) return __FILE_FULL_PATH__.dirName.buildPath(path); }*/ -} +//} /**************************************************** */ @@ -508,11 +508,11 @@ public: } if (cast(void*)fd in visited) return; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (fd.getModule() && !fd.getModule().isFrontendModule()) return; - } + //} // printf("FuncDeclaration %s %s\n", fd.toPrettyChars(), fd.type.toChars()); visited[cast(void*)fd] = true; @@ -591,11 +591,11 @@ public: } if (cast(void*)vd in visited) return; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (vd.getModule() && !vd.getModule().isFrontendModule()) return; - } + //} visited[cast(void*)vd] = true; @@ -703,11 +703,11 @@ public: printf("[AST.AliasDeclaration enter] %s\n", ad.toChars()); scope(exit) printf("[AST.AliasDeclaration exit] %s\n", ad.toChars()); } - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (ad.getModule() && !ad.getModule().isFrontendModule()) return; - } + //} if (auto t = ad.type) { @@ -794,13 +794,18 @@ public: return; if (!sd.type || !sd.type.deco) return; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (sd.getModule() && !sd.getModule().isFrontendModule()) return; - } + //} visited[cast(void*)sd] = true; + if (linkage != LINK.c && linkage != LINK.cpp) + { + buf.printf("// ignoring non-cpp struct %s because of linkage\n", sd.toChars()); + return; + } if (sd.alignment == 1) buf.writestring("#pragma pack(push, 1)\n"); @@ -827,6 +832,7 @@ public: if (!memberField(vd)) continue; varCount++; + if (!vd._init && !vd.type.isTypeBasic()) continue; if (vd._init && vd._init.isVoidInitializer()) @@ -917,13 +923,13 @@ public: } if (cast(void*)cd in visited) return; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (cd.getModule() && !cd.getModule().isFrontendModule()) return; if (cd.isVisitorClass()) return; - } + //} visited[cast(void*)cd] = true; if (!cd.isCPPclass()) @@ -951,14 +957,14 @@ public: m.accept(this); } adparent = save; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ // Generate special static inline function. if (cd.isIdentifierClass()) { buf.writestring(" static inline Identifier *idPool(const char *s) { return idPool(s, strlen(s)); }\n"); } - } + //} buf.writestring("};\n\n"); } @@ -974,14 +980,22 @@ public: scope(exit) printf("[AST.EnumDeclaration exit] %s\n", ed.toChars()); } if (cast(void*)ed in visited) - return; - version(BUILD_COMPILER) - { + return; + + //version(BUILD_COMPILER) + //{ if (ed.getModule() && !ed.getModule().isFrontendModule()) return; - } + //} visited[cast(void*)ed] = true; + + //if (linkage != LINK.c && linkage != LINK.cpp) + //{ + //buf.printf("// ignoring non-cpp enum %s because of linkage\n", ed.toChars()); + //return; + //} + if (ed.isSpecial()) return; buf.writestring("enum"); @@ -1012,6 +1026,7 @@ public: } else buf.writestring(";\n\n"); + //printf("Enum %s min %d max %d\n", ident, ed.minval.toInteger(), ed.maxval.toInteger()); } override void visit(AST.EnumMember em) @@ -1278,8 +1293,8 @@ public: printf("[visitTi(AST.TemplateInstance) enter] %s\n", ti.toChars()); scope(exit) printf("[visitTi(AST.TemplateInstance) exit] %s\n", ti.toChars()); } - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (ti.tempdecl.ident == DMDType.AssocArray) { buf.writestring("AA*"); @@ -1296,16 +1311,16 @@ public: } buf.writestring(ti.tempdecl.ident.toChars()); } - } - else - { - foreach (o; *ti.tiargs) - { - if (!AST.isType(o)) - return; - } - buf.writestring(ti.tempdecl.ident.toChars()); - } + //} + //else + //{ + //foreach (o; *ti.tiargs) + //{ + //if (!AST.isType(o)) + //return; + //} + //buf.writestring(ti.tempdecl.ident.toChars()); + //} buf.writeByte('<'); foreach (i, o; *ti.tiargs) { @@ -1335,11 +1350,11 @@ public: if (cast(void*)td in visited) return; visited[cast(void*)td] = true; - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ if (td.getModule() && !td.getModule().isFrontendModule()) return; - } + //} if (!td.parameters || !td.onemember || !td.onemember.isStructDeclaration()) { @@ -1744,11 +1759,11 @@ void gencpphdrfiles(Modules *ms) import dmd.tokens; DMDType._init(); - version(BUILD_COMPILER) - { + //version(BUILD_COMPILER) + //{ DMDModule._init(); DMDClass._init(); - } + //} setVersions(); OutBuffer buf; @@ -1788,7 +1803,7 @@ void gencpphdrfiles(Modules *ms) buf.writestring("\n"); buf.writestring("#define _d_null NULL\n"); buf.writestring("\n"); - version(BUILD_COMPILER) + //version(BUILD_COMPILER) buf.writestring("struct AA;\n"); buf.writestring("\n"); @@ -1826,6 +1841,7 @@ void gencpphdrfiles(Modules *ms) } buf.write(&done); buf.write(&decl); + //printf("%s\n", decl.peekSlice().ptr); check.writestring(` } diff --git a/src/dmd/root/dcompat.h b/src/dmd/root/dcompat.h index 213799c662b4..3b8a2f76bdc7 100644 --- a/src/dmd/root/dcompat.h +++ b/src/dmd/root/dcompat.h @@ -24,6 +24,14 @@ struct DArray : length(length_in), ptr(ptr_in) { } }; +template<> +struct DArray +{ + size_t length; + const char *ptr; + DArray& operator=(const char str[]) { ptr = str; length = strlen(str); } +}; + struct DString : public DArray { DString() : DArray() { } diff --git a/src/tests/cxxfrontend.c b/src/tests/cxxfrontend.c index 8b5d6792881c..be84c6ebaff2 100644 --- a/src/tests/cxxfrontend.c +++ b/src/tests/cxxfrontend.c @@ -13,61 +13,60 @@ #include "root/dcompat.h" #include "root/file.h" #include "root/filename.h" -#include "root/longdouble.h" -#include "root/object.h" -#include "root/outbuffer.h" -#include "root/port.h" -#include "root/rmem.h" -#include "root/root.h" - -#include "aggregate.h" -#include "aliasthis.h" -#include "arraytypes.h" -#include "ast_node.h" -#include "attrib.h" -#include "compiler.h" -#include "complex_t.h" -#include "cond.h" -#include "ctfe.h" -#include "declaration.h" -#include "doc.h" -#include "dsymbol.h" -#include "enum.h" -#include "errors.h" -#include "expression.h" -#include "globals.h" -#include "hdrgen.h" -#include "identifier.h" -#include "id.h" -#include "import.h" -#include "init.h" -#include "json.h" -#include "mangle.h" -#include "module.h" -#include "mtype.h" -#include "nspace.h" -#include "objc.h" -#include "scope.h" -#include "statement.h" -#include "staticassert.h" -#include "target.h" -#include "template.h" -#include "tokens.h" -#include "version.h" - -#include "array.h" -#include "ctfloat.h" -#include "file.h" -#include "filename.h" -#include "longdouble.h" -#include "object.h" -// FIXME: UINT64_MAX -//#include "outbuffer.h" -//#include "port.h" -#include "rmem.h" -//#include "root.h" -//#include "stringtable.h" -#include "thread.h" +/*#include "root/longdouble.h"*/ +/*#include "root/object.h"*/ +/*#include "root/outbuffer.h"*/ +/*#include "root/port.h"*/ +/*#include "root/rmem.h"*/ +/*#include "root/root.h"*/ + +/*#include "aggregate.h"*/ +/*#include "aliasthis.h"*/ +/*#include "arraytypes.h"*/ +/*#include "attrib.h"*/ +/*#include "compiler.h"*/ +/*#include "complex_t.h"*/ +/*#include "cond.h"*/ +/*#include "ctfe.h"*/ +/*#include "declaration.h"*/ +/*#include "doc.h"*/ +/*#include "dsymbol.h"*/ +/*#include "enum.h"*/ +/*#include "errors.h"*/ +/*#include "expression.h"*/ +/*#include "globals.h"*/ +/*#include "hdrgen.h"*/ +/*#include "identifier.h"*/ +/*#include "id.h"*/ +/*#include "import.h"*/ +/*#include "init.h"*/ +/*#include "json.h"*/ +/*#include "mangle.h"*/ +/*#include "module.h"*/ +/*#include "mtype.h"*/ +/*#include "nspace.h"*/ +/*#include "objc.h"*/ +/*#include "scope.h"*/ +/*#include "statement.h"*/ +/*#include "staticassert.h"*/ +/*#include "target.h"*/ +/*#include "template.h"*/ +/*#include "tokens.h"*/ +/*#include "version.h"*/ + +/*#include "array.h"*/ +/*#include "ctfloat.h"*/ +/*#include "file.h"*/ +/*#include "filename.h"*/ +/*#include "longdouble.h"*/ +/*#include "object.h"*/ +/*// FIXME: UINT64_MAX*/ +/*//#include "outbuffer.h"*/ +/*//#include "port.h"*/ +/*#include "rmem.h"*/ +/*//#include "root.h"*/ +/*//#include "stringtable.h"*/ +/*#include "thread.h"*/ #include "visitor.h" #include "frontend.h" @@ -313,54 +312,30 @@ void test_expression() void test_target() { - assert(target.isVectorOpSupported(Type::tint32, TOKpow)); + assert(target.isVectorOpSupported(Type::tint32, TOKpow, NULL)); } /**********************************/ void test_emplace() { - Loc loc; - UnionExp ue; - - IntegerExp::emplace(&ue, loc, 1065353216, Type::tint32); - Expression *e = ue.exp(); - assert(e->op == TOKint64); - assert(e->toInteger() == 1065353216); - - UnionExp ure; - Expression *re = Compiler::paintAsType(&ure, e, Type::tfloat32); - assert(re->op == TOKfloat64); - assert(re->toReal() == CTFloat::one); - - UnionExp uie; - Expression *ie = Compiler::paintAsType(&uie, re, Type::tint32); - assert(ie->op == TOKint64); - assert(ie->toInteger() == e->toInteger()); -} - -/**********************************/ - -void test_parameters() -{ - Parameters *args = new Parameters; - args->push(Parameter::create(STCundefined, Type::tint32, NULL, NULL, NULL)); - args->push(Parameter::create(STCundefined, Type::tint64, NULL, NULL, NULL)); - - TypeFunction *tf = TypeFunction::create(args, Type::tvoid, VARARGnone, LINKc); - - assert(tf->parameterList.length() == 2); - assert(tf->parameterList[0]->type == Type::tint32); - assert(tf->parameterList[1]->type == Type::tint64); -} - -/**********************************/ - -void test_location() -{ - Loc loc1 = Loc("test.d", 24, 42); - assert(loc1.equals(Loc("test.d", 24, 42))); - assert(strcmp(loc1.toChars(true), "test.d(24,42)") == 0); + Loc loc; + UnionExp ue; + + IntegerExp::emplacei(&ue, loc, 1065353216, Type::tint32); + Expression *e = ue.exp(); + assert((unsigned char) e->op == TOKint64); + assert(e->toInteger() == 1065353216); + + UnionExp ure; + Expression *re = Compiler::paintAsType(&ure, e, Type::tfloat32); + assert((unsigned char) re->op == TOKfloat64); + assert(re->toReal() == CTFloat::one); + + UnionExp uie; + Expression *ie = Compiler::paintAsType(&uie, re, Type::tint32); + assert((unsigned char) ie->op == TOKint64); + assert(ie->toInteger() == e->toInteger()); } /**********************************/ From 63a850d74576260d49cab1bed30eb863018d7069 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 15 Jul 2019 16:47:14 +0300 Subject: [PATCH 22/44] Add ignoredModule tmp helper --- src/dmd/dtoh.d | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index eafab2298c8a..23a85bb3daed 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -348,6 +348,34 @@ struct DMDType return false; } + private bool isIgnoredModule(ASTCodegen.Module m) + { + //if (!m || !m.parent) + if (!m) + return true; + + // Ignore dmd.root + if (m.parent && m.parent.ident == DMDModule.root && + m.parent.parent && m.parent.parent.ident == DMDModule.dmd && + !m.parent.parent.parent) + { + return true; + } + + // Ignore dmd.visitor and derivatives + if ((m.ident == DMDModule.visitor || + m.ident == DMDModule.parsetimevisitor || + m.ident == DMDModule.permissivevisitor || + m.ident == DMDModule.strictvisitor || + m.ident == DMDModule.transitivevisitor) && + m.parent && m.parent.ident == DMDModule.dmd && + !m.parent.parent) + { + return true; + } + return false; + } + private bool isFrontendModule(ASTCodegen.Module m) { if (!m || !m.parent) @@ -510,7 +538,8 @@ public: return; //version(BUILD_COMPILER) //{ - if (fd.getModule() && !fd.getModule().isFrontendModule()) + //if (fd.getModule() && !fd.getModule().isFrontendModule()) + if (fd.getModule() && fd.getModule().isIgnoredModule()) return; //} @@ -593,7 +622,8 @@ public: return; //version(BUILD_COMPILER) //{ - if (vd.getModule() && !vd.getModule().isFrontendModule()) + //if (vd.getModule() && !vd.getModule().isFrontendModule()) + if (vd.getModule() && vd.getModule().isIgnoredModule()) return; //} @@ -705,7 +735,8 @@ public: } //version(BUILD_COMPILER) //{ - if (ad.getModule() && !ad.getModule().isFrontendModule()) + //if (ad.getModule() && !ad.getModule().isFrontendModule()) + if (ad.getModule() && ad.getModule().isIgnoredModule()) return; //} @@ -796,7 +827,8 @@ public: return; //version(BUILD_COMPILER) //{ - if (sd.getModule() && !sd.getModule().isFrontendModule()) + //if (sd.getModule() && !sd.getModule().isFrontendModule()) + if (sd.getModule() && sd.getModule().isIgnoredModule()) return; //} @@ -925,7 +957,8 @@ public: return; //version(BUILD_COMPILER) //{ - if (cd.getModule() && !cd.getModule().isFrontendModule()) + //if (cd.getModule() && !cd.getModule().isFrontendModule()) + if (cd.getModule() && cd.getModule().isIgnoredModule()) return; if (cd.isVisitorClass()) return; @@ -984,7 +1017,8 @@ public: //version(BUILD_COMPILER) //{ - if (ed.getModule() && !ed.getModule().isFrontendModule()) + //if (ed.getModule() && !ed.getModule().isFrontendModule()) + if (ed.getModule() && ed.getModule().isIgnoredModule()) return; //} @@ -1352,7 +1386,8 @@ public: visited[cast(void*)td] = true; //version(BUILD_COMPILER) //{ - if (td.getModule() && !td.getModule().isFrontendModule()) + //if (td.getModule() && !td.getModule().isFrontendModule()) + if (td.getModule() && td.getModule().isIgnoredModule()) return; //} From 892ffe97c82c917e645f0b37e53877462518f8dc Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 15 Jul 2019 16:51:40 +0300 Subject: [PATCH 23/44] Add tmp workaround for alias forward decl and >> template issue --- src/dmd/dtoh.d | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 23a85bb3daed..07f02ea5c664 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -1315,9 +1315,9 @@ public: } if (!cdparent && t.isConst()) buf.writestring("const "); - buf.writestring("DArray<"); + buf.writestring("DArray< "); t.next.accept(this); - buf.writestring(">"); + buf.writestring(" >"); } private void visitTi(AST.TemplateInstance ti) @@ -1835,6 +1835,7 @@ void gencpphdrfiles(Modules *ms) buf.writestring("#define _d_char char\n"); buf.writestring("#define _d_wchar wchar_t\n"); buf.writestring("#define _d_dchar unsigned\n"); + buf.writestring("typedef _d_long d_int64;\n"); buf.writestring("\n"); buf.writestring("#define _d_null NULL\n"); buf.writestring("\n"); From dac9254e44575bf2daf96450afa844f0b2e87f3e Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 17 Jul 2019 18:26:39 +0300 Subject: [PATCH 24/44] Add support for enum base type --- src/dmd/dtoh.d | 46 +++++++++++++++++++++++++++++++++++++---- src/tests/cxxfrontend.c | 6 +++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 07f02ea5c664..e6c6deaf47e8 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -1030,16 +1030,54 @@ public: //return; //} + bool hasBaseType = false; + + switch (ed.memtype.ty) + { + case AST.Tbool, AST.Tvoid: + case AST.Tchar, AST.Twchar, AST.Tdchar: + case AST.Tint8, AST.Tuns8: + case AST.Tint16, AST.Tuns16: + case AST.Tint64, AST.Tuns64: + case AST.Tfloat32, AST.Tfloat64, AST.Tfloat80: + //buf.writestring("_d_"); + //buf.writestring(t.dstring); + //printf("Jaa _d_%s\n", ed.memtype.kind); + hasBaseType = true; + break; + case AST.Tint32, AST.Tuns32, AST.Tenum: // by default, the base is an int + break; + default: + printf ("%s\n", ed.ident.toChars()); + assert(0, ed.memtype.kind.toDString); + } + if (ed.isSpecial()) return; - buf.writestring("enum"); const(char)* ident = null; if (ed.ident) ident = ed.ident.toChars(); - if (ident) + if (!ident) { - buf.writeByte(' '); - buf.writestring(ident); + buf.writestring("enum"); + } + else + { + if (hasBaseType) + { + //printf("typedef _d_%s %s;\n", ed.memtype.kind, ident); + buf.writestring("typedef _d_"); + buf.writestring(ed.memtype.kind); + buf.writeByte(' '); + buf.writestring(ident); + buf.writestring(";\n"); + buf.writestring("enum"); + } + else + { + buf.writestring("enum "); + buf.writestring(ident); + } } if (ed.members) { diff --git a/src/tests/cxxfrontend.c b/src/tests/cxxfrontend.c index be84c6ebaff2..241eab160c4e 100644 --- a/src/tests/cxxfrontend.c +++ b/src/tests/cxxfrontend.c @@ -324,17 +324,17 @@ void test_emplace() IntegerExp::emplacei(&ue, loc, 1065353216, Type::tint32); Expression *e = ue.exp(); - assert((unsigned char) e->op == TOKint64); + assert(e->op == TOKint64); assert(e->toInteger() == 1065353216); UnionExp ure; Expression *re = Compiler::paintAsType(&ure, e, Type::tfloat32); - assert((unsigned char) re->op == TOKfloat64); + assert(re->op == TOKfloat64); assert(re->toReal() == CTFloat::one); UnionExp uie; Expression *ie = Compiler::paintAsType(&uie, re, Type::tint32); - assert((unsigned char) ie->op == TOKint64); + assert(ie->op == TOKint64); assert(ie->toInteger() == e->toInteger()); } From 2bf8605f0881aeed977dbac6ca438cfc3eb53a2c Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 30 Jul 2019 15:28:13 +0300 Subject: [PATCH 25/44] Add support for alignment of pow2 --- src/dmd/dtoh.d | 52 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index e6c6deaf47e8..08888f4deebe 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -432,6 +432,7 @@ public: AST.TemplateDeclaration tdparent; Identifier ident; LINK linkage = LINK.d; + bool forwardedAA; this(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf) { @@ -629,6 +630,12 @@ public: visited[cast(void*)vd] = true; + if (vd.alignment != uint.max) + { + indent(); + buf.printf("// Ignoring var %s alignment %u\n", vd.toChars(), vd.alignment); + } + if (vd.storage_class & AST.STC.manifest && vd.type.isintegral() && vd._init && vd._init.isExpInitializer()) @@ -828,7 +835,7 @@ public: //version(BUILD_COMPILER) //{ //if (sd.getModule() && !sd.getModule().isFrontendModule()) - if (sd.getModule() && sd.getModule().isIgnoredModule()) + if (sd.getModule() && sd.getModule().isIgnoredModule()) return; //} @@ -839,8 +846,8 @@ public: return; } - if (sd.alignment == 1) - buf.writestring("#pragma pack(push, 1)\n"); + pushAlignToBuffer(sd.alignment); + buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); buf.writestring(sd.ident.toChars()); if (sd.members) @@ -910,11 +917,10 @@ public: } buf.printf(" }\n"); } + buf.writestring("};\n"); - buf.writestring("};\n\n"); - - if (sd.alignment == 1) - buf.writestring("#pragma pack(pop)\n"); + popAlignToBuffer(sd.alignment); + buf.writestring("\n"); auto savex = buf; buf = checkbuf; @@ -927,6 +933,25 @@ public: buf.writestring(";\n\n"); } + private void pushAlignToBuffer(uint alignment) + { + // DMD ensures alignment is a power of two + //assert(alignment > 0 && ((alignment & (alignment - 1)) == 0), + // "Invalid alignment size"); + + // When no alignment is specified, `uint.max` is the default + if (alignment != uint.max) + { + buf.printf("#pragma pack(push, %d)\n", alignment); + } + } + + private void popAlignToBuffer(uint alignment) + { + if (alignment != uint.max) + buf.writestring("#pragma pack(pop)\n"); + } + private void includeSymbol(AST.Dsymbol ds) { debug (Debug_DtoH) @@ -1127,13 +1152,7 @@ public: scope(exit) printf("[typeToBuffer(AST.Type) exit] %s ident %s\n", t.toChars(), ident.toChars()); } this.ident = ident; - //printf("====\nBefore\n"); - //printf("buf\n%s\n", buf.peekChars()); - //printf("fwdbuf\n%s\n", fwdbuf.peekChars()); t.accept(this); - //printf("After\n====\n"); - //printf("fwdbuf\n%s\n", fwdbuf.peekChars()); - //printf("\n====\n"); if (this.ident) { buf.writeByte(' '); @@ -1369,6 +1388,11 @@ public: //{ if (ti.tempdecl.ident == DMDType.AssocArray) { + if (!forwardedAA) + { + forwardedAA = true; + fwdbuf.writestring("struct AA;\n"); + } buf.writestring("AA*"); return; } @@ -1878,7 +1902,7 @@ void gencpphdrfiles(Modules *ms) buf.writestring("#define _d_null NULL\n"); buf.writestring("\n"); //version(BUILD_COMPILER) - buf.writestring("struct AA;\n"); + //buf.writestring("struct AA;\n"); buf.writestring("\n"); OutBuffer check; From aa240e685b915fcfaa8dfe77258863ca560fc144 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 30 Jul 2019 16:16:16 +0300 Subject: [PATCH 26/44] Fix alignment issues --- src/dmd/dtoh.d | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 08888f4deebe..86fd181a9daf 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -846,9 +846,8 @@ public: return; } + buf.writestring(sd.isUnionDeclaration() ? "union" : "struct"); pushAlignToBuffer(sd.alignment); - - buf.writestring(sd.isUnionDeclaration() ? "union " : "struct "); buf.writestring(sd.ident.toChars()); if (sd.members) { @@ -942,14 +941,33 @@ public: // When no alignment is specified, `uint.max` is the default if (alignment != uint.max) { - buf.printf("#pragma pack(push, %d)\n", alignment); + buf.writestring("\n#if defined(__GNUC__) || defined(__clang__)\n"); + // The equivalent of `#pragma pack(push, n)` is `__attribute__((packed, aligned(n)))` + // NOTE: removing the packed attribute will might change the resulting size + buf.printf(" __attribute__((packed, aligned(%d)))\n", alignment); + buf.writestring("#elif defined(_MSC_VER)\n"); + buf.printf(" __declspec(align(%d))\n", alignment); + buf.writestring("#elif defined(__DMC__)\n"); + buf.printf(" #pragma pack(push, %d)\n", alignment); + //buf.printf("#pragma pack(%d)\n", alignment); + buf.writestring("#endif\n"); } + else + { + buf.writeByte(' '); + } + } private void popAlignToBuffer(uint alignment) { if (alignment != uint.max) - buf.writestring("#pragma pack(pop)\n"); + { + buf.writestring("#if defined(__DMC__)\n"); + buf.writestring(" #pragma pack(pop)\n"); + //buf.writestring("#pragma pack()\n"); + buf.writestring("#endif\n"); + } } private void includeSymbol(AST.Dsymbol ds) From 7362bdf458824c15f31118fdbde22d22f65a4a32 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 30 Jul 2019 17:34:14 +0300 Subject: [PATCH 27/44] Generate enums based on -extern-std version --- src/dmd/dtoh.d | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 86fd181a9daf..724b22becbc8 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -1109,12 +1109,21 @@ public: if (hasBaseType) { //printf("typedef _d_%s %s;\n", ed.memtype.kind, ident); - buf.writestring("typedef _d_"); - buf.writestring(ed.memtype.kind); - buf.writeByte(' '); - buf.writestring(ident); - buf.writestring(";\n"); - buf.writestring("enum"); + if (global.params.cplusplus >= CppStdRevision.cpp11) + { + //printf("Using cpp 11 and beyond\n"); + buf.printf("enum %s : %s", ident, ed.memtype.kind); + } + else + { + //printf("Using cpp 98\n"); + buf.writestring("typedef _d_"); + buf.writestring(ed.memtype.kind); + buf.writeByte(' '); + buf.writestring(ident); + buf.writestring(";\n"); + buf.writestring("enum"); + } } else { @@ -1130,7 +1139,7 @@ public: if (i) buf.writestring(",\n"); buf.writestring(" "); - if (ident) + if (ident && global.params.cplusplus == CppStdRevision.cpp98) { foreach (c; ident[0 .. strlen(ident)]) buf.writeByte(toupper(c)); From 9a3ce62227809e6852b8309093d8b3bb2a658908 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 21 Aug 2019 15:21:45 +0300 Subject: [PATCH 28/44] Update tool auto-gen message --- src/dmd/dtoh.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 724b22becbc8..f89083aecb4b 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -1893,7 +1893,7 @@ void gencpphdrfiles(Modules *ms) OutBuffer buf; buf.writestring("#pragma once\n"); buf.writeByte('\n'); - buf.printf("// Automatically generated by dtoh\n"); + buf.printf("// Automatically generated by dmd -HC\n"); buf.writeByte('\n'); buf.writestring("#include \n"); buf.writestring("#include \n"); From 7072bdc046bab5bd7ed8389e35b3d68cb92ccb7d Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 21 Aug 2019 15:44:23 +0300 Subject: [PATCH 29/44] Update tests --- test/compilable/dtoh_AnonDeclaration.d | 2 +- test/compilable/dtoh_StructDeclaration.d | 8 +++---- .../extra-files/dtoh_AliasDeclaration.out | 3 ++- .../extra-files/dtoh_AnonDeclaration.out | 3 ++- .../extra-files/dtoh_ClassDeclaration.out | 3 ++- .../extra-files/dtoh_StructDeclaration.out | 23 ++++++++++++++----- .../extra-files/dtoh_TemplateDeclaration.out | 4 +++- .../extra-files/dtoh_VarDeclaration.out | 3 ++- test/compilable/extra-files/dtoh_enum.out | 3 ++- .../compilable/extra-files/dtoh_functions.out | 3 ++- .../extra-files/dtoh_unittest_block.out | 3 ++- 11 files changed, 39 insertions(+), 19 deletions(-) diff --git a/test/compilable/dtoh_AnonDeclaration.d b/test/compilable/dtoh_AnonDeclaration.d index e1936f62c441..5ad36c2effcf 100644 --- a/test/compilable/dtoh_AnonDeclaration.d +++ b/test/compilable/dtoh_AnonDeclaration.d @@ -8,7 +8,7 @@ TEST_OUTPUT: --- */ -struct S +extern (C++) struct S { union { diff --git a/test/compilable/dtoh_StructDeclaration.d b/test/compilable/dtoh_StructDeclaration.d index 8b59039fbd70..d9440337b8cc 100644 --- a/test/compilable/dtoh_StructDeclaration.d +++ b/test/compilable/dtoh_StructDeclaration.d @@ -19,7 +19,7 @@ StructDeclaration has the following issues: * a struct should only define ctors if it’s extern (C++) */ -struct S +extern (C++) struct S { byte a; int b; @@ -44,7 +44,7 @@ extern (C) struct S3 this(int a) {} } -align(1) struct Aligned +extern (C++) align(1) struct Aligned { //align(1): byte a; @@ -54,12 +54,12 @@ align(1) struct Aligned this(int a) {} } -struct A +extern (C++) struct A { int a; S s; - void foo(); + extern (D) void foo(); extern (C) void bar() {} extern (C++) void baz(int x = 42) {} diff --git a/test/compilable/extra-files/dtoh_AliasDeclaration.out b/test/compilable/extra-files/dtoh_AliasDeclaration.out index fae9ccab9ed8..ed59bb2ab7ff 100644 --- a/test/compilable/extra-files/dtoh_AliasDeclaration.out +++ b/test/compilable/extra-files/dtoh_AliasDeclaration.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL diff --git a/test/compilable/extra-files/dtoh_AnonDeclaration.out b/test/compilable/extra-files/dtoh_AnonDeclaration.out index 0e9094351747..a3aff4230c70 100644 --- a/test/compilable/extra-files/dtoh_AnonDeclaration.out +++ b/test/compilable/extra-files/dtoh_AnonDeclaration.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL diff --git a/test/compilable/extra-files/dtoh_ClassDeclaration.out b/test/compilable/extra-files/dtoh_ClassDeclaration.out index e2eac0b780bb..888678534b32 100644 --- a/test/compilable/extra-files/dtoh_ClassDeclaration.out +++ b/test/compilable/extra-files/dtoh_ClassDeclaration.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL diff --git a/test/compilable/extra-files/dtoh_StructDeclaration.out b/test/compilable/extra-files/dtoh_StructDeclaration.out index 0af77b9bd4e2..f75fadfbf7d0 100644 --- a/test/compilable/extra-files/dtoh_StructDeclaration.out +++ b/test/compilable/extra-files/dtoh_StructDeclaration.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL @@ -30,6 +31,7 @@ // Parsing module dtoh_StructDeclaration struct S2; struct S3; +struct Aligned; struct S; struct Inner; struct S @@ -61,23 +63,32 @@ struct S3 S3(_d_int a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } }; -#pragma pack(push, 1) -struct Aligned +struct +#if defined(__GNUC__) || defined(__clang__) + __attribute__((packed, aligned(1))) +#elif defined(_MSC_VER) + __declspec(align(1)) +#elif defined(__DMC__) + #pragma pack(push, 1) +#endif +Aligned { _d_byte a; _d_int b; _d_long c; - // ignoring function dtoh_StructDeclaration.Aligned.this because of linkage + Aligned& __ctor(_d_int a); Aligned() { this->a = 0; this->b = 0; this->c = 0LL; } Aligned(_d_byte a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } }; +#if defined(__DMC__) + #pragma pack(pop) +#endif -#pragma pack(pop) struct A { _d_int a; S s; - // ignoring function dtoh_StructDeclaration.A.foo because of linkage + // ignoring extern () block because of linkage extern "C" _d_void bar(); _d_void baz(_d_int x/* = 42*/); struct diff --git a/test/compilable/extra-files/dtoh_TemplateDeclaration.out b/test/compilable/extra-files/dtoh_TemplateDeclaration.out index 95a7034a74e6..37ea86806857 100644 --- a/test/compilable/extra-files/dtoh_TemplateDeclaration.out +++ b/test/compilable/extra-files/dtoh_TemplateDeclaration.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL @@ -31,6 +32,7 @@ template struct A { + // Ignoring var x alignment 0 T x; // ignoring function foo because semantic hasn't been run }; diff --git a/test/compilable/extra-files/dtoh_VarDeclaration.out b/test/compilable/extra-files/dtoh_VarDeclaration.out index 01a9d0bc6529..eaced69390ea 100644 --- a/test/compilable/extra-files/dtoh_VarDeclaration.out +++ b/test/compilable/extra-files/dtoh_VarDeclaration.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL diff --git a/test/compilable/extra-files/dtoh_enum.out b/test/compilable/extra-files/dtoh_enum.out index af38cf8961c1..6135d77a2767 100644 --- a/test/compilable/extra-files/dtoh_enum.out +++ b/test/compilable/extra-files/dtoh_enum.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL diff --git a/test/compilable/extra-files/dtoh_functions.out b/test/compilable/extra-files/dtoh_functions.out index 82ce865c63c4..a172c1c3624c 100644 --- a/test/compilable/extra-files/dtoh_functions.out +++ b/test/compilable/extra-files/dtoh_functions.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL diff --git a/test/compilable/extra-files/dtoh_unittest_block.out b/test/compilable/extra-files/dtoh_unittest_block.out index ee8da2190774..c6a05985e077 100644 --- a/test/compilable/extra-files/dtoh_unittest_block.out +++ b/test/compilable/extra-files/dtoh_unittest_block.out @@ -1,6 +1,6 @@ #pragma once -// Automatically generated by dtoh +// Automatically generated by dmd -HC #include #include @@ -23,6 +23,7 @@ #define _d_char char #define _d_wchar wchar_t #define _d_dchar unsigned +typedef _d_long d_int64; #define _d_null NULL From d17d199090c1f5104bcc93f666f4aaed2d3cad45 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 21 Aug 2019 16:20:21 +0300 Subject: [PATCH 30/44] Fix outdated code in cxxfrontend test --- src/tests/cxxfrontend.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tests/cxxfrontend.c b/src/tests/cxxfrontend.c index 241eab160c4e..42abf4722833 100644 --- a/src/tests/cxxfrontend.c +++ b/src/tests/cxxfrontend.c @@ -110,12 +110,12 @@ static void frontend_term() void test_tokens() { // First valid TOK value - assert(TOKlparen == 1); - assert(strcmp(Token::toChars(TOKlparen), "(") == 0); + assert(TOKleftParentheses == 1); + assert(strcmp(Token::toChars(TOKleftParentheses), "(") == 0); // Last valid TOK value - assert(TOKvectorarray == TOKMAX - 1); - assert(strcmp(Token::toChars(TOKvectorarray), "vectorarray") == 0); + assert(TOKvectorArray == TOKmax_ - 1); + assert(strcmp(Token::toChars(TOKvectorArray), "vectorarray") == 0); } /**********************************/ @@ -234,7 +234,7 @@ void test_visitors() AliasDeclaration *ad = AliasDeclaration::create(loc, ident, tp); assert(ad->isAliasDeclaration() == ad); - ad->storage_class = STCabstract; + ad->storage_class = STCabstract_; assert(ad->isAbstract() == true); ad->accept(&tv); assert(tv.decl == true); @@ -282,7 +282,7 @@ void test_semantic() semantic2(m, NULL); semantic3(m, NULL); - Dsymbol *s = m->search(Loc(), Identifier::idPool("Error")); + Dsymbol *s = m->search(Loc(), Identifier::idPool("Error"), SearchLocalsOnly); assert(s); AggregateDeclaration *ad = s->isAggregateDeclaration(); assert(ad && ad->ctor); @@ -322,7 +322,7 @@ void test_emplace() Loc loc; UnionExp ue; - IntegerExp::emplacei(&ue, loc, 1065353216, Type::tint32); + IntegerExp::emplace(&ue, loc, 1065353216, Type::tint32); Expression *e = ue.exp(); assert(e->op == TOKint64); assert(e->toInteger() == 1065353216); From 54e7e1884d30614d04224559dc7cbd4f146b75da Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 21 Aug 2019 18:12:38 +0300 Subject: [PATCH 31/44] Code cleanup --- src/dmd/dtoh.d | 671 +++++++++++++------------------------------------ src/dmd/mars.d | 2 +- 2 files changed, 171 insertions(+), 502 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index f89083aecb4b..7f9bbcdfb153 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -2,7 +2,7 @@ * Compiler implementation of the * $(LINK2 http://www.dlang.org, D programming language). * - * Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtohd, _dtoh.d) @@ -32,238 +32,7 @@ import dmd.utils; //debug = Debug_DtoH; -version(BUILD_COMPILER) -{ - immutable string[] sources = [ - "access.d", "aggregate.d", "aliasthis.d", "apply.d", "argtypes.d", "arrayop.d", "arraytypes.d", "attrib.d", - "blockexit.d", "builtin.d", - "canthrow.d", "clone.d", "compiler.d", "complex.d", "cond.d", "console.d", "constfold.d", "cppmangle.d", "cppmanglewin.d", "ctfeexpr.d", "ctorflow.d", - "dcast.d", "dclass.d", "declaration.d", "delegatize.d", "denum.d", "dimport.d", "dinterpret.d", - "dmacro.d", "dmangle.d", "dmodule.d", "doc.d", "dscope.d", "dstruct.d", "dsymbol.d", "dsymbolsem.d", "dtemplate.d", "dversion.d", - "entity.d", "errors.d", "escape.d", "expression.d", "expressionsem.d", - "func.d", - "globals.d", "gluelayer.d", - "hdrgen.d", - "iasm.d", "id.d", "identifier.d", "impcnvtab.d", "imphint.d", "init.d", "initsem.d", "inline.d", "inlinecost.d", "intrange.d", - "json.d", - "lambdacomp.d", "lexer.d", - "mtype.d", - "nogc.d", "nspace.d", - "objc.d", "opover.d", "optimize.d", - "parse.d", "printast.d", - "safe.d", "sapply.d", "semantic2.d", "semantic3.d", "sideeffect.d", "statement.d", - "statementsem.d", "staticassert.d", "staticcond.d", - "target.d", "templateparamsem.d", "tokens.d", "traits.d", "typesem.d", "typinf.d", - "utf.d", "utils.d", - ]; -} - -version(none) -{ -int main(string[] args) -{ - import std.algorithm.sorting : sort; - import std.array : array; - import std.file : readText; - import std.path : baseName, buildPath, dirName; - import std.string : toStringz; - - import dmd.dsymbolsem; - import dmd.errors; - import dmd.id; - import dmd.dinifile; - import dmd.parse; - - import dmd.semantic2; - import dmd.semantic3; - import dmd.builtin : builtin_init; - import dmd.dmodule : Module; - import dmd.expression : Expression; - import dmd.frontend; - import dmd.objc : Objc; - import dmd.root.response; - import dmd.root.stringtable; - import dmd.target : Target; - - import core.memory; - import core.stdc.stdio : printf; - - GC.disable(); - initDMD(); - - Strings arguments = Strings(args.length); - for (size_t i = 0; i < args.length; i++) - { - arguments[i] = args[i].ptr; - } - if (response_expand(&arguments)) // expand response files - error(Loc.initial, "can't open response file"); - auto files = Strings(arguments.dim - 1); - global.params.argv0 = args[0]; - - global.inifilename = parse_conf_arg(&arguments); - if (global.inifilename) - { - // can be empty as in -conf= - if (strlen(global.inifilename) && !FileName.exists(global.inifilename)) - error(Loc.initial, "Config file '%s' does not exist.", global.inifilename); - } - else - { - version (Windows) - { - global.inifilename = findConfFile(global.params.argv0, "sc.ini").ptr; - } - else version (Posix) - { - global.inifilename = findConfFile(global.params.argv0, "dmd.conf").ptr; - } - else - { - static assert(0, "fix this"); - } - } - // Read the configurarion file - auto inifile = File(global.inifilename); - inifile.read(); - /* Need path of configuration file, for use in expanding @P macro - */ - const(char)* inifilepath = FileName.path(global.inifilename); - Strings sections; - StringTable environment; - environment._init(7); - /* Read the [Environment] section, so we can later - * pick up any DFLAGS settings. - */ - sections.push("Environment"); - parseConfFile(&environment, global.inifilename, inifilepath, inifile.len, inifile.buffer, §ions); - - const(char)* arch = global.params.is64bit ? "64" : "32"; // use default - arch = parse_arch_arg(&arguments, arch); - - // parse architecture from DFLAGS read from [Environment] section - { - Strings dflags; - getenv_setargv(readFromEnv(&environment, "DFLAGS"), &dflags); - environment.reset(7); // erase cached environment updates - arch = parse_arch_arg(&dflags, arch); - } - - bool is64bit = arch[0] == '6'; - - version(Windows) // delete LIB entry in [Environment] (necessary for optlink) to allow inheriting environment for MS-COFF - if (is64bit || strcmp(arch, "32mscoff") == 0) - environment.update("LIB", 3).ptrvalue = null; - - // read from DFLAGS in [Environment{arch}] section - char[80] envsection = void; - sprintf(envsection.ptr, "Environment%s", arch); - sections.push(envsection.ptr); - parseConfFile(&environment, global.inifilename, inifilepath, inifile.len, inifile.buffer, §ions); - getenv_setargv(readFromEnv(&environment, "DFLAGS"), &arguments); - updateRealEnvironment(&environment); - environment.reset(1); // don't need environment cache any more - - if (parseCommandLine(arguments, args.length, global.params, files)) - { - Loc loc; - errorSupplemental(loc, "run 'dmd -man' to open browser on manual"); - return 1; - } - - - /*version(BUILD_COMPILER) - { - global.path.push(druntimeFullPath.toStringz()); - //TODO: fixme for LDC - global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../").toStringz()); - global.filePath.push(__FILE_FULL_PATH__.dirName.buildPath("../../res/").toStringz()); - }*/ - - DMDType._init(); - version(BUILD_COMPILER) - { - DMDModule._init(); - DMDClass._init(); - } - - setVersions(); - - Modules modules; - - string path = __FILE_FULL_PATH__.dirName.buildPath("../dmd/"); - version (BUILD_COMPILER) - auto srcs = sources; - else - auto srcs = args [1 .. $]; - foreach (f; srcs) - { - string fn = buildPath(path, f); - - auto id = Identifier.idPool(baseName(fn, ".d")); - auto m = new Module(fn.toStringz(), id, false, false); - auto input = readText(fn); - - if (!Module.rootModule) - Module.rootModule = m; - - m.importedFrom = m; - m.srcfile.setbuffer(cast(void*)input.ptr, input.length); - m.srcfile._ref = 1; - m.parse(); - modules.push(m); - } - - foreach (m; modules) - m.importAll(null); - foreach (m; modules) - m.dsymbolSemantic(null); - - Module.dprogress = 1; - Module.runDeferredSemantic(); - - foreach (m; modules) - m.semantic2(null); - Module.runDeferredSemantic2(); - - foreach (m; modules) - m.semantic3(null); - Module.runDeferredSemantic3(); - - OutBuffer buf; - genCppFiles(&buf, &modules); - - printf("%s\n", buf.peekString()); - return 0; -} -} - -void setVersions() -{ - import dmd.cond : VersionCondition; - version(BUILD_COMPILER) - { - VersionCondition.addPredefinedGlobalIdent("NoBackend"); - VersionCondition.addPredefinedGlobalIdent("NoMain"); - } -} - -string dirName(string path) -{ - version (Windows) - enum char separator = '\\'; - else - enum char separator = '/'; - - for (size_t i = path.length - 1; i > 0; i--) - { - if (path[i] == separator) - return path[0..i]; - } - return path; -} - -struct DMDType +private struct DMDType { __gshared static Identifier c_long; __gshared static Identifier c_ulong; @@ -275,6 +44,7 @@ struct DMDType __gshared static Identifier AssocArray; __gshared static Identifier Array; //} + static void _init() { c_long = Identifier.idPool("__c_long"); @@ -292,7 +62,7 @@ struct DMDType } //version(BUILD_COMPILER) //{ - struct DMDModule + private struct DMDModule { __gshared static Identifier identifier; __gshared static Identifier root; @@ -314,7 +84,8 @@ struct DMDType dmd = Identifier.idPool("dmd"); } } - struct DMDClass + + private struct DMDClass { __gshared static Identifier ID; ////Identifier __gshared static Identifier Visitor; @@ -403,17 +174,113 @@ struct DMDType return ((m.parent.ident == DMDModule.dmd && !m.parent.parent) || (m.parent.parent.ident == DMDModule.dmd && !m.parent.parent.parent)); } +//} + +void genCppHdrFiles(ref Modules ms) +{ + import dmd.tokens; + + DMDType._init(); + //version(BUILD_COMPILER) + //{ + DMDModule._init(); + DMDClass._init(); + //} - /*string druntimeFullPath() + OutBuffer buf; + buf.writestring("#pragma once\n"); + buf.writeByte('\n'); + buf.printf("// Automatically generated by dmd -HC\n"); + buf.writeByte('\n'); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writestring("#include \n"); + buf.writeByte('\n'); + buf.writestring("#define _d_void void\n"); + buf.writestring("#define _d_bool bool\n"); + buf.writestring("#define _d_byte signed char\n"); + buf.writestring("#define _d_ubyte unsigned char\n"); + buf.writestring("#define _d_short short\n"); + buf.writestring("#define _d_ushort unsigned short\n"); + buf.writestring("#define _d_int int\n"); + buf.writestring("#define _d_uint unsigned\n"); + if (global.params.isLP64) { - version (IN_LLVM) - string path = "../runtime/druntime/src"; - else - string path = "../../../druntime/src/"; + buf.writestring("#define _d_long long\n"); + buf.writestring("#define _d_ulong unsigned long\n"); + } + else + { + buf.writestring("#define _d_long long long\n"); + buf.writestring("#define _d_ulong unsigned long long\n"); + } + buf.writestring("#define _d_float float\n"); + buf.writestring("#define _d_double double\n"); + buf.writestring("#define _d_real long double\n"); + buf.writestring("#define _d_char char\n"); + buf.writestring("#define _d_wchar wchar_t\n"); + buf.writestring("#define _d_dchar unsigned\n"); + buf.writestring("typedef _d_long d_int64;\n"); + buf.writestring("\n"); + buf.writestring("#define _d_null NULL\n"); + buf.writestring("\n\n"); - return __FILE_FULL_PATH__.dirName.buildPath(path); - }*/ -//} + OutBuffer check; + check.writestring(` + #if OFFSETS + + template + size_t getSlotNumber(int dummy, ...) + { + T c; + va_list ap; + va_start(ap, dummy); + void *f = va_arg(ap, void*); + for (size_t i = 0; ; i++) + { + if ( (*(void***)&c)[i] == f) + return i; + } + va_end(ap); + } + + void testOffsets() + { + `); + + OutBuffer done; + OutBuffer decl; + scope v = new ToCppBuffer!ASTCodegen(&check, &buf, &done, &decl); + foreach (m; ms) + { + //printf("// Parsing module %s\n", m.toPrettyChars()); + buf.printf("// Parsing module %s\n", m.toPrettyChars()); + m.accept(v); + } + buf.write(&done); + buf.write(&decl); + //printf("%s\n", decl.peekSlice().ptr); + + check.writestring(` + } + #endif + `); + + debug buf.write(&check); + + if (global.params.cxxhdrname is null) + { + // Write to stdout; assume it succeeds + size_t n = fwrite(buf.data, 1, buf.offset, stdout); + assert(n == buf.offset); // keep gcc happy about return values + } + else + { + const(char)[] name = FileName.combine(global.params.cxxhdrdir, global.params.cxxhdrname); + writeFile(Loc.initial, name, buf.peekSlice()); + } +} /**************************************************** */ @@ -463,7 +330,6 @@ public: buf.printf("// ignored %s %s\n", s.kind(), s.toPrettyChars()); } } - } override void visit(AST.Import i) @@ -509,7 +375,9 @@ public: buf.printf("// ignoring %s block because of linkage\n", ld.toPrettyChars()); } else + { visit(cast(AST.AttribDeclaration)ld); + } linkage = save; } @@ -539,9 +407,8 @@ public: return; //version(BUILD_COMPILER) //{ - //if (fd.getModule() && !fd.getModule().isFrontendModule()) if (fd.getModule() && fd.getModule().isIgnoredModule()) - return; + return; //} // printf("FuncDeclaration %s %s\n", fd.toPrettyChars(), fd.type.toChars()); @@ -574,7 +441,7 @@ public: if (adparent && fd.vtblIndex != -1) { if (!fd.isOverride()) - buf.writestring("virtual "); + buf.writestring("virtual "); auto s = adparent.search(Loc.initial, fd.ident); if (!(adparent.storage_class & AST.STC.abstract_) && @@ -620,10 +487,9 @@ public: scope(exit) printf("[AST.VarDeclaration exit] %s\n", vd.toChars()); } if (cast(void*)vd in visited) - return; + return; //version(BUILD_COMPILER) //{ - //if (vd.getModule() && !vd.getModule().isFrontendModule()) if (vd.getModule() && vd.getModule().isIgnoredModule()) return; //} @@ -697,8 +563,6 @@ public: if (adparent && vd.type && vd.type.deco) { - //printf("Here %s\n", vd.toChars()); - //printf("Za buff\n====\n%s\n====\n", buf.peekChars()); indent(); auto save = cdparent; cdparent = vd.isField() ? adparent.isClassDeclaration() : null; @@ -720,7 +584,6 @@ public: buf = savex; return; } - visit(cast(AST.Dsymbol)vd); } @@ -742,9 +605,8 @@ public: } //version(BUILD_COMPILER) //{ - //if (ad.getModule() && !ad.getModule().isFrontendModule()) if (ad.getModule() && ad.getModule().isIgnoredModule()) - return; + return; //} if (auto t = ad.type) @@ -763,7 +625,6 @@ public: } if (!ad.aliassym) { - //ad.print(); assert(0); } if (auto ti = ad.aliassym.isTemplateInstance()) @@ -834,9 +695,8 @@ public: return; //version(BUILD_COMPILER) //{ - //if (sd.getModule() && !sd.getModule().isFrontendModule()) - if (sd.getModule() && sd.getModule().isIgnoredModule()) - return; + if (sd.getModule() && sd.getModule().isIgnoredModule()) + return; //} visited[cast(void*)sd] = true; @@ -929,7 +789,9 @@ public: buf = savex; } else + { buf.writestring(";\n\n"); + } } private void pushAlignToBuffer(uint alignment) @@ -956,7 +818,6 @@ public: { buf.writeByte(' '); } - } private void popAlignToBuffer(uint alignment) @@ -977,7 +838,6 @@ public: printf("[includeSymbol(AST.Dsymbol) enter] %s\n", ds.toChars()); scope(exit) printf("[includeSymbol(AST.Dsymbol) exit] %s\n", ds.toChars()); } - // printf("Forward declaring %s %d\n", ds.toChars(), level); if (cast(void*)ds !in visited) { OutBuffer decl; @@ -997,14 +857,13 @@ public: scope(exit) printf("[AST.ClassDeclaration exit] %s\n", cd.toChars()); } if (cast(void*)cd in visited) - return; + return; //version(BUILD_COMPILER) //{ - //if (cd.getModule() && !cd.getModule().isFrontendModule()) if (cd.getModule() && cd.getModule().isIgnoredModule()) - return; + return; if (cd.isVisitorClass()) - return; + return; //} visited[cast(void*)cd] = true; @@ -1045,7 +904,9 @@ public: buf.writestring("};\n\n"); } else + { buf.writestring(";\n\n"); + } } override void visit(AST.EnumDeclaration ed) @@ -1060,9 +921,8 @@ public: //version(BUILD_COMPILER) //{ - //if (ed.getModule() && !ed.getModule().isFrontendModule()) if (ed.getModule() && ed.getModule().isIgnoredModule()) - return; + return; //} visited[cast(void*)ed] = true; @@ -1083,9 +943,6 @@ public: case AST.Tint16, AST.Tuns16: case AST.Tint64, AST.Tuns64: case AST.Tfloat32, AST.Tfloat64, AST.Tfloat80: - //buf.writestring("_d_"); - //buf.writestring(t.dstring); - //printf("Jaa _d_%s\n", ed.memtype.kind); hasBaseType = true; break; case AST.Tint32, AST.Tuns32, AST.Tenum: // by default, the base is an int @@ -1137,19 +994,21 @@ public: foreach (i, m; *ed.members) { if (i) - buf.writestring(",\n"); + buf.writestring(",\n"); buf.writestring(" "); if (ident && global.params.cplusplus == CppStdRevision.cpp98) { foreach (c; ident[0 .. strlen(ident)]) - buf.writeByte(toupper(c)); + buf.writeByte(toupper(c)); } m.accept(this); } buf.writestring("\n};\n\n"); } else + { buf.writestring(";\n\n"); + } //printf("Enum %s min %d max %d\n", ident, ed.minval.toInteger(), ed.maxval.toInteger()); } @@ -1224,7 +1083,7 @@ public: scope(exit) printf("[AST.TypeBasic exit] %s\n", t.toChars()); } if (!cdparent && t.isConst()) - buf.writestring("const "); + buf.writestring("const "); switch (t.ty) { case AST.Tbool, AST.Tvoid: @@ -1251,16 +1110,16 @@ public: scope(exit) printf("[AST.TypePointer exit] %s\n", t.toChars()); } if (t.next.ty == AST.Tstruct && - !strcmp((cast(AST.TypeStruct)t.next).sym.ident.toChars(), "__va_list_tag")) + !strcmp((cast(AST.TypeStruct)t.next).sym.ident.toChars(), "__va_list_tag")) { buf.writestring("va_list"); return; } t.next.accept(this); if (t.next.ty != AST.Tfunction) - buf.writeByte('*'); + buf.writeByte('*'); if (!cdparent && t.isConst()) - buf.writestring(" const"); + buf.writestring(" const"); } override void visit(AST.TypeSArray t) @@ -1308,7 +1167,7 @@ public: if (tf.parameterList.varargs) { if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1) - buf.writestring(", "); + buf.writestring(", "); buf.writestring("..."); } buf.writeByte(')'); @@ -1340,7 +1199,9 @@ public: } } else + { buf.writestring(ed.toChars()); + } } override void visit(AST.TypeEnum t) @@ -1360,7 +1221,7 @@ public: buf = save; } if (!cdparent && t.isConst()) - buf.writestring("const "); + buf.writestring("const "); enumToBuffer(t.sym); } @@ -1371,8 +1232,7 @@ public: printf("[AST.TypeStruct enter] %s\n", t.toChars()); scope(exit) printf("[AST.TypeStruct exit] %s\n", t.toChars()); } - if (cast(void*)t.sym !in forwarded && - !t.sym.parent.isTemplateInstance()) + if (cast(void*)t.sym !in forwarded && !t.sym.parent.isTemplateInstance()) { forwarded[cast(void*)t.sym] = true; fwdbuf.writestring(t.sym.isUnionDeclaration() ? "union " : "struct "); @@ -1381,7 +1241,7 @@ public: } if (!cdparent && t.isConst()) - buf.writestring("const "); + buf.writestring("const "); if (auto ti = t.sym.parent.isTemplateInstance()) { visitTi(ti); @@ -1398,7 +1258,7 @@ public: scope(exit) printf("[AST.TypeDArray exit] %s\n", t.toChars()); } if (!cdparent && t.isConst()) - buf.writestring("const "); + buf.writestring("const "); buf.writestring("DArray< "); t.next.accept(this); buf.writestring(" >"); @@ -1424,13 +1284,15 @@ public: return; } if (ti.tempdecl.ident == DMDType.Array) + { buf.writestring("Array"); + } else { foreach (o; *ti.tiargs) { if (!AST.isType(o)) - return; + return; } buf.writestring(ti.tempdecl.ident.toChars()); } @@ -1448,7 +1310,7 @@ public: foreach (i, o; *ti.tiargs) { if (i) - buf.writestring(", "); + buf.writestring(", "); if (auto tt = AST.isType(o)) { tt.accept(this); @@ -1475,7 +1337,6 @@ public: visited[cast(void*)td] = true; //version(BUILD_COMPILER) //{ - //if (td.getModule() && !td.getModule().isFrontendModule()) if (td.getModule() && td.getModule().isIgnoredModule()) return; //} @@ -1533,7 +1394,9 @@ public: buf.writestring("};\n\n"); } else + { buf.writestring(";\n\n"); + } tdparent = save; } @@ -1570,7 +1433,7 @@ public: assert(tf.next); tf.next.accept(this); if (tf.isref) - buf.writeByte('&'); + buf.writeByte('&'); buf.writeByte(' '); buf.writestring(ident.toChars()); @@ -1578,14 +1441,14 @@ public: foreach (i; 0 .. AST.Parameter.dim(tf.parameterList.parameters)) { if (i) - buf.writestring(", "); + buf.writestring(", "); auto fparam = AST.Parameter.getNth(tf.parameterList.parameters, i); fparam.accept(this); } if (tf.parameterList.varargs) { if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1) - buf.writestring(", "); + buf.writestring(", "); buf.writestring("..."); } buf.writeByte(')'); @@ -1638,11 +1501,6 @@ public: printf("[AST.Expression enter] %s\n", e.toChars()); scope(exit) printf("[AST.Expression exit] %s\n", e.toChars()); } - //e.print(); - //printf("====\n%s\n====\n", e.toChars()); - //printf("\n=============\n"); - //printf("%s\n", buf.peekChars()); - //printf("\n=============\n"); assert(0); } @@ -1675,7 +1533,7 @@ public: } assert(e.sz == 1 || e.sz == 2); if (e.sz == 2) - buf.writeByte('L'); + buf.writeByte('L'); buf.writeByte('"'); size_t o = buf.offset; for (size_t i = 0; i < e.len; i++) @@ -1685,21 +1543,26 @@ public: { case '"': case '\\': - buf.writeByte('\\'); - goto default; + buf.writeByte('\\'); + goto default; default: - if (c <= 0xFF) - { - if (c <= 0x7F && isprint(c)) - buf.writeByte(c); + if (c <= 0xFF) + { + if (c <= 0x7F && isprint(c)) + buf.writeByte(c); + else + buf.printf("\\x%02x", c); + } + else if (c <= 0xFFFF) + { + buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8); + } else - buf.printf("\\x%02x", c); - } - else if (c <= 0xFFFF) - buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8); - else - buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24); - break; + { + buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", + c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24); + } + break; } } buf.writeByte('"'); @@ -1787,203 +1650,9 @@ public: foreach(i, e; *sle.elements) { if (i) - buf.writestring(", "); + buf.writestring(", "); e.accept(this); } buf.writeByte(')'); } } -void genCppFiles(OutBuffer* buf, Modules *ms) -{ - import dmd.tokens; - - buf.writeByte('\n'); - buf.printf("// Automatically generated by dtoh\n"); - buf.writeByte('\n'); - buf.writestring("#include \n"); - buf.writestring("#include \n"); - buf.writestring("#include \n"); - buf.writestring("#include \n"); - buf.writeByte('\n'); - buf.writestring("#define _d_void void\n"); - buf.writestring("#define _d_bool bool\n"); - buf.writestring("#define _d_byte signed char\n"); - buf.writestring("#define _d_ubyte unsigned char\n"); - buf.writestring("#define _d_short short\n"); - buf.writestring("#define _d_ushort unsigned short\n"); - buf.writestring("#define _d_int int\n"); - buf.writestring("#define _d_uint unsigned\n"); - if (global.params.isLP64) - { - buf.writestring("#define _d_long long\n"); - buf.writestring("#define _d_ulong unsigned long\n"); - } - else - { - buf.writestring("#define _d_long long long\n"); - buf.writestring("#define _d_ulong unsigned long long\n"); - } - buf.writestring("#define _d_float float\n"); - buf.writestring("#define _d_double double\n"); - buf.writestring("#define _d_real long double\n"); - buf.writestring("#define _d_char char\n"); - buf.writestring("#define _d_wchar wchar_t\n"); - buf.writestring("#define _d_dchar unsigned\n"); - buf.writestring("\n"); - buf.writestring("#define _d_null NULL\n"); - buf.writestring("\n"); - version(BUILD_COMPILER) - buf.writestring("struct AA;\n"); - buf.writestring("\n"); - - OutBuffer check; - check.writestring(` - #if OFFSETS - - template - size_t getSlotNumber(int dummy, ...) - { - T c; - va_list ap; - va_start(ap, dummy); - void *f = va_arg(ap, void*); - for (size_t i = 0; ; i++) - { - if ( (*(void***)&c)[i] == f) - return i; - } - va_end(ap); - } - - void testOffsets() - { - `); - - OutBuffer done; - OutBuffer decl; - scope v = new ToCppBuffer!ASTCodegen(&check, buf, &done, &decl); - foreach (m; *ms) - { - buf.printf("// Parsing module %s\n", m.toPrettyChars()); - m.accept(v); - } - buf.write(&done); - buf.write(&decl); - - check.writestring(` - } - #endif - `); - - debug buf.write(&check); -} - -void gencpphdrfiles(Modules *ms) -{ - import dmd.tokens; - - DMDType._init(); - //version(BUILD_COMPILER) - //{ - DMDModule._init(); - DMDClass._init(); - //} - setVersions(); - - OutBuffer buf; - buf.writestring("#pragma once\n"); - buf.writeByte('\n'); - buf.printf("// Automatically generated by dmd -HC\n"); - buf.writeByte('\n'); - buf.writestring("#include \n"); - buf.writestring("#include \n"); - buf.writestring("#include \n"); - buf.writestring("#include \n"); - buf.writeByte('\n'); - buf.writestring("#define _d_void void\n"); - buf.writestring("#define _d_bool bool\n"); - buf.writestring("#define _d_byte signed char\n"); - buf.writestring("#define _d_ubyte unsigned char\n"); - buf.writestring("#define _d_short short\n"); - buf.writestring("#define _d_ushort unsigned short\n"); - buf.writestring("#define _d_int int\n"); - buf.writestring("#define _d_uint unsigned\n"); - if (global.params.isLP64) - { - buf.writestring("#define _d_long long\n"); - buf.writestring("#define _d_ulong unsigned long\n"); - } - else - { - buf.writestring("#define _d_long long long\n"); - buf.writestring("#define _d_ulong unsigned long long\n"); - } - buf.writestring("#define _d_float float\n"); - buf.writestring("#define _d_double double\n"); - buf.writestring("#define _d_real long double\n"); - buf.writestring("#define _d_char char\n"); - buf.writestring("#define _d_wchar wchar_t\n"); - buf.writestring("#define _d_dchar unsigned\n"); - buf.writestring("typedef _d_long d_int64;\n"); - buf.writestring("\n"); - buf.writestring("#define _d_null NULL\n"); - buf.writestring("\n"); - //version(BUILD_COMPILER) - //buf.writestring("struct AA;\n"); - buf.writestring("\n"); - - OutBuffer check; - check.writestring(` - #if OFFSETS - - template - size_t getSlotNumber(int dummy, ...) - { - T c; - va_list ap; - va_start(ap, dummy); - void *f = va_arg(ap, void*); - for (size_t i = 0; ; i++) - { - if ( (*(void***)&c)[i] == f) - return i; - } - va_end(ap); - } - - void testOffsets() - { - `); - - OutBuffer done; - OutBuffer decl; - scope v = new ToCppBuffer!ASTCodegen(&check, &buf, &done, &decl); - foreach (m; *ms) - { - //printf("// Parsing module %s\n", m.toPrettyChars()); - buf.printf("// Parsing module %s\n", m.toPrettyChars()); - m.accept(v); - } - buf.write(&done); - buf.write(&decl); - //printf("%s\n", decl.peekSlice().ptr); - - check.writestring(` - } - #endif - `); - - debug buf.write(&check); - - if (global.params.cxxhdrname is null) - { - // Write to stdout; assume it succeeds - size_t n = fwrite(buf.data, 1, buf.offset, stdout); - assert(n == buf.offset); // keep gcc happy about return values - } - else - { - const(char)[] name = FileName.combine(global.params.cxxhdrdir, global.params.cxxhdrname); - writeFile(Loc.initial, name, buf.peekSlice()); - } -} diff --git a/src/dmd/mars.d b/src/dmd/mars.d index 39edbff790c8..726f00c45a11 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -670,7 +670,7 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) if (global.params.doCxxHdrGeneration) { - gencpphdrfiles(&modules); + genCppHdrFiles(modules); } if (global.errors) fatal(); From 0ef5acf23e5de592497e198ecff1734e9aa539cc Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Fri, 23 Aug 2019 19:11:00 +0300 Subject: [PATCH 32/44] CPP does not support covariant const methods --- src/dmd/dtoh.d | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 7f9bbcdfb153..195dc7889cf7 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -460,9 +460,30 @@ public: buf = save; } } + funcToBuffer(tf, fd.ident); if (adparent && tf.isConst()) - buf.writestring(" const"); + { + bool fdOverridesAreConst = true; + foreach (fdv; fd.foverrides) + { + auto tfv = cast(AST.TypeFunction)fdv.type; + if (!tfv.isConst()) + { + fdOverridesAreConst = false; + break; + } + } + + if (fdOverridesAreConst) + { + buf.writestring(" const"); + } + else + { + buf.writestring(" /* const */"); + } + } if (adparent && fd.isAbstract()) buf.writestring(" = 0"); buf.printf(";\n"); From 77b584aca1533b5ca2e4910c59479e2c6064a50f Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 2 Sep 2019 16:10:01 +0300 Subject: [PATCH 33/44] Correctly write ctor declarations --- src/dmd/dtoh.d | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 195dc7889cf7..e5597af0e12d 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -461,7 +461,7 @@ public: } } - funcToBuffer(tf, fd.ident); + funcToBuffer(tf, fd.ident, fd.isCtorDeclaration() !is null); if (adparent && tf.isConst()) { bool fdOverridesAreConst = true; @@ -740,6 +740,8 @@ public: m.accept(this); } adparent = save; + version (none) + { // Generate default ctor buf.printf(" %s(", sd.ident.toChars()); buf.printf(") {"); @@ -797,6 +799,7 @@ public: } buf.printf(" }\n"); } + } buf.writestring("};\n"); popAlignToBuffer(sd.alignment); @@ -1444,19 +1447,34 @@ public: buf.writestring(" const"); } - private void funcToBuffer(AST.TypeFunction tf, Identifier ident) + private void funcToBuffer(AST.TypeFunction tf, Identifier ident, bool isCtor) { debug (Debug_DtoH) { printf("[funcToBuffer(AST.TypeFunction) enter] %s\n", tf.toChars()); scope(exit) printf("[funcToBuffer(AST.TypeFunction) exit] %s\n", tf.toChars()); } + assert(tf.next); - tf.next.accept(this); - if (tf.isref) - buf.writeByte('&'); - buf.writeByte(' '); - buf.writestring(ident.toChars()); + if (isCtor) + { + if (tf.next.isTypeStruct()) + { + buf.writestring(tf.next.isTypeStruct().sym.toChars()); + } + else + { + buf.writestring(tf.next.isTypeClass().sym.toChars()); + } + } + else + { + tf.next.accept(this); + if (tf.isref) + buf.writeByte('&'); + buf.writeByte(' '); + buf.writestring(ident.toChars()); + } buf.writeByte('('); foreach (i; 0 .. AST.Parameter.dim(tf.parameterList.parameters)) From a548da65675e3156b8c8e592c0b574277fb86853 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 2 Sep 2019 16:12:50 +0300 Subject: [PATCH 34/44] Generate default args for literals --- src/dmd/dtoh.d | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index e5597af0e12d..9fffd53db78a 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -26,6 +26,7 @@ import dmd.root.file; import dmd.root.filename; import dmd.root.rmem; import dmd.visitor; +import dmd.tokens; import dmd.root.outbuffer; import dmd.utils; @@ -178,8 +179,6 @@ private struct DMDType void genCppHdrFiles(ref Modules ms) { - import dmd.tokens; - DMDType._init(); //version(BUILD_COMPILER) //{ @@ -1509,9 +1508,9 @@ public: if (ident) buf.writestring(ident.toChars()); ident = null; - version (none) + version (all) { - if (p.defaultArg && p.defaultArg.op >= 105 && p.defaultArg.op < 152) + if (p.defaultArg && p.defaultArg.op >= TOK.int32Literal && p.defaultArg.op < TOK.struct_) { //printf("%s %d\n", p.defaultArg.toChars, p.defaultArg.op); buf.writestring(" = "); From 3e7551455e19ce50378a7d9efe85c435650daa64 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 14 Oct 2019 17:15:00 +0300 Subject: [PATCH 35/44] Generate dtor and copy ctor declarations --- src/dmd/dtoh.d | 74 ++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 9fffd53db78a..2dce033a538c 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -460,7 +460,7 @@ public: } } - funcToBuffer(tf, fd.ident, fd.isCtorDeclaration() !is null); + funcToBuffer(tf, fd); if (adparent && tf.isConst()) { bool fdOverridesAreConst = true; @@ -663,6 +663,11 @@ public: buf.printf("\n"); return; } + if (auto fd = ad.aliassym.isDtorDeclaration()) + { + // Ignore. It's taken care of while visiting FuncDeclaration + return; + } indent(); buf.printf("// ignored %s %s\n", ad.aliassym.kind(), ad.aliassym.toPrettyChars()); } @@ -739,8 +744,6 @@ public: m.accept(this); } adparent = save; - version (none) - { // Generate default ctor buf.printf(" %s(", sd.ident.toChars()); buf.printf(") {"); @@ -767,37 +770,39 @@ public: } buf.printf(" }\n"); - if (varCount) + version (none) { - buf.printf(" %s(", sd.ident.toChars()); - bool first = true; - foreach (m; *sd.members) + if (varCount) { - if (auto vd = m.isVarDeclaration()) + buf.printf(" %s(", sd.ident.toChars()); + bool first = true; + foreach (m; *sd.members) { - if (!memberField(vd)) - continue; - if (first) - first = false; - else - buf.writestring(", "); - assert(vd.type); - assert(vd.ident); - typeToBuffer(vd.type, vd.ident); + if (auto vd = m.isVarDeclaration()) + { + if (!memberField(vd)) + continue; + if (first) + first = false; + else + buf.writestring(", "); + assert(vd.type); + assert(vd.ident); + typeToBuffer(vd.type, vd.ident); + } } - } - buf.printf(") {"); - foreach (m; *sd.members) - { - if (auto vd = m.isVarDeclaration()) + buf.printf(") {"); + foreach (m; *sd.members) { - if (!memberField(vd)) - continue; - buf.printf(" this->%s = %s;", vd.ident.toChars(), vd.ident.toChars()); + if (auto vd = m.isVarDeclaration()) + { + if (!memberField(vd)) + continue; + buf.printf(" this->%s = %s;", vd.ident.toChars(), vd.ident.toChars()); + } } + buf.printf(" }\n"); } - buf.printf(" }\n"); - } } buf.writestring("};\n"); @@ -1446,7 +1451,7 @@ public: buf.writestring(" const"); } - private void funcToBuffer(AST.TypeFunction tf, Identifier ident, bool isCtor) + private void funcToBuffer(AST.TypeFunction tf, AST.FuncDeclaration fd) { debug (Debug_DtoH) { @@ -1454,17 +1459,16 @@ public: scope(exit) printf("[funcToBuffer(AST.TypeFunction) exit] %s\n", tf.toChars()); } + Identifier ident = fd.ident; + assert(tf.next); - if (isCtor) + if (fd.isCtorDeclaration() || fd.isDtorDeclaration()) { - if (tf.next.isTypeStruct()) - { - buf.writestring(tf.next.isTypeStruct().sym.toChars()); - } - else + if (fd.isDtorDeclaration()) { - buf.writestring(tf.next.isTypeClass().sym.toChars()); + buf.writeByte('~'); } + buf.writestring(adparent.toChars()); } else { From 6e052f8170cfa0773954639fbda1b9c66b843424 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 14 Oct 2019 18:02:18 +0300 Subject: [PATCH 36/44] Rebase with master --- src/build.d | 2 +- src/dmd/dtoh.d | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/build.d b/src/build.d index fea0d95ca5be..ccdd13b9e65b 100755 --- a/src/build.d +++ b/src/build.d @@ -1025,7 +1025,7 @@ auto sourceFiles() cli.d clone.d compiler.d complex.d cond.d constfold.d cppmangle.d cppmanglewin.d ctfeexpr.d ctorflow.d dcast.d dclass.d declaration.d delegatize.d denum.d dimport.d dinifile.d dinterpret.d dmacro.d dmangle.d dmodule.d doc.d dscope.d dstruct.d dsymbol.d dsymbolsem.d - dtemplate.d dversion.d env.d escape.d expression.d expressionsem.d func.d hdrgen.d impcnvtab.d + dtemplate.d dtoh.d dversion.d env.d escape.d expression.d expressionsem.d func.d hdrgen.d impcnvtab.d imphint.d init.d initsem.d inline.d inlinecost.d intrange.d json.d lambdacomp.d lib.d libelf.d libmach.d libmscoff.d libomf.d link.d mars.d mtype.d nogc.d nspace.d objc.d opover.d optimize.d parse.d parsetimevisitor.d permissivevisitor.d printast.d safe.d sapply.d scanelf.d scanmach.d diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 2dce033a538c..8d65f14d7951 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -271,13 +271,13 @@ void genCppHdrFiles(ref Modules ms) if (global.params.cxxhdrname is null) { // Write to stdout; assume it succeeds - size_t n = fwrite(buf.data, 1, buf.offset, stdout); - assert(n == buf.offset); // keep gcc happy about return values + size_t n = fwrite(buf[].ptr, 1, buf.length, stdout); + assert(n == buf.length); // keep gcc happy about return values } else { const(char)[] name = FileName.combine(global.params.cxxhdrdir, global.params.cxxhdrname); - writeFile(Loc.initial, name, buf.peekSlice()); + writeFile(Loc.initial, name, buf[]); } } @@ -1577,7 +1577,7 @@ public: if (e.sz == 2) buf.writeByte('L'); buf.writeByte('"'); - size_t o = buf.offset; + size_t o = buf.length; for (size_t i = 0; i < e.len; i++) { uint c = e.charAt(i); From 70b2f7f03c8ce47b7a52877c822f94c0d74c02a6 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 22 Oct 2019 14:12:41 +0300 Subject: [PATCH 37/44] Add compiler switch to cli.d --- src/dmd/cli.d | 9 +++++++++ src/dmd/mars.d | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/dmd/cli.d b/src/dmd/cli.d index 9bd07111ea50..58e9dfb8d853 100644 --- a/src/dmd/cli.d +++ b/src/dmd/cli.d @@ -363,6 +363,15 @@ dmd -cov -unittest myprog.d Option("Hf=", "write 'header' file to filename" ), + Option("HC", + "generate C++ 'header' file" + ), + Option("HCd=", + "write C++ 'header' file to directory" + ), + Option("HCf=", + "write C++ 'header' file to filename" + ), Option("-help", "print help and exit" ), diff --git a/src/dmd/mars.d b/src/dmd/mars.d index 726f00c45a11..f800ffb6f9d8 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -2113,17 +2113,17 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param goto Lerror; } } - else if (p[1] == 'H' && p[2] == 'C') + else if (p[1] == 'H' && p[2] == 'C') // https://dlang.org/dmd.html#switch-HC { params.doCxxHdrGeneration = true; switch (p[3]) { - case 'd': // https://dlang.org/dmd.html#switch-Hd + case 'd': // https://dlang.org/dmd.html#switch-HCd if (!p[4]) goto Lnoarg; params.cxxhdrdir = (p + 4 + (p[4] == '=')).toDString; break; - case 'f': // https://dlang.org/dmd.html#switch-Hf + case 'f': // https://dlang.org/dmd.html#switch-HCf if (!p[4]) goto Lnoarg; params.cxxhdrname = (p + 4 + (p[4] == '=')).toDString; From ca370fbab6d11a0e5c5e9ba7bde2754db1846886 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 22 Oct 2019 14:30:37 +0300 Subject: [PATCH 38/44] Update tests --- .../extra-files/dtoh_ClassDeclaration.out | 9 +++------ .../extra-files/dtoh_StructDeclaration.out | 17 ++++------------- .../extra-files/dtoh_TemplateDeclaration.out | 1 - test/compilable/extra-files/dtoh_functions.out | 4 ++-- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/test/compilable/extra-files/dtoh_ClassDeclaration.out b/test/compilable/extra-files/dtoh_ClassDeclaration.out index 888678534b32..8c358bb677a8 100644 --- a/test/compilable/extra-files/dtoh_ClassDeclaration.out +++ b/test/compilable/extra-files/dtoh_ClassDeclaration.out @@ -29,8 +29,6 @@ typedef _d_long d_int64; // Parsing module dtoh_ClassDeclaration -class C2; -class Aligned; class C; class A; struct Inner; @@ -48,7 +46,7 @@ public: _d_int a; _d_int b; _d_long c; - C2* __ctor(_d_int a); + C2(_d_int a); }; // ignoring non-cpp class C3 @@ -58,7 +56,7 @@ public: _d_byte a; _d_int b; _d_long c; - Aligned* __ctor(_d_int a); + Aligned(_d_int a); }; class A @@ -68,7 +66,7 @@ public: C* c; virtual _d_void foo(); extern "C" virtual _d_void bar(); - virtual _d_void baz(_d_int x/* = 42*/); + virtual _d_void baz(_d_int x = 42); struct { _d_int x; @@ -83,7 +81,6 @@ struct Inner { _d_int x; Inner() { this->x = 0; } - Inner(_d_int x) { this->x = x; } }; class InnerC diff --git a/test/compilable/extra-files/dtoh_StructDeclaration.out b/test/compilable/extra-files/dtoh_StructDeclaration.out index f75fadfbf7d0..e4943574f47e 100644 --- a/test/compilable/extra-files/dtoh_StructDeclaration.out +++ b/test/compilable/extra-files/dtoh_StructDeclaration.out @@ -29,9 +29,6 @@ typedef _d_long d_int64; // Parsing module dtoh_StructDeclaration -struct S2; -struct S3; -struct Aligned; struct S; struct Inner; struct S @@ -40,7 +37,6 @@ struct S _d_int b; _d_long c; S() { this->a = 0; this->b = 0; this->c = 0LL; } - S(_d_byte a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } }; struct S2 @@ -48,9 +44,8 @@ struct S2 _d_int a; _d_int b; _d_long c; - S2& __ctor(_d_int a); + S2(_d_int a); S2() { this->a = 42; this->b = 0; this->c = 0LL; } - S2(_d_int a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } }; struct S3 @@ -58,9 +53,8 @@ struct S3 _d_int a; _d_int b; _d_long c; - extern "C" S3& __ctor(_d_int a); + extern "C" S3(_d_int a); S3() { this->a = 42; this->b = 0; this->c = 0LL; } - S3(_d_int a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } }; struct @@ -76,9 +70,8 @@ Aligned _d_byte a; _d_int b; _d_long c; - Aligned& __ctor(_d_int a); + Aligned(_d_int a); Aligned() { this->a = 0; this->b = 0; this->c = 0LL; } - Aligned(_d_byte a, _d_int b, _d_long c) { this->a = a; this->b = b; this->c = c; } }; #if defined(__DMC__) #pragma pack(pop) @@ -90,7 +83,7 @@ struct A S s; // ignoring extern () block because of linkage extern "C" _d_void bar(); - _d_void baz(_d_int x/* = 42*/); + _d_void baz(_d_int x = 42); struct { _d_int x; @@ -105,13 +98,11 @@ struct Inner { _d_int x; Inner() { this->x = 0; } - Inner(_d_int x) { this->x = x; } }; typedef Inner I; class C; A() { this->a = 0; } - A(_d_int a, S s) { this->a = a; this->s = s; } }; diff --git a/test/compilable/extra-files/dtoh_TemplateDeclaration.out b/test/compilable/extra-files/dtoh_TemplateDeclaration.out index 37ea86806857..4064f5cda5b8 100644 --- a/test/compilable/extra-files/dtoh_TemplateDeclaration.out +++ b/test/compilable/extra-files/dtoh_TemplateDeclaration.out @@ -41,6 +41,5 @@ struct B { A<_d_int> x; B() { } - B(A<_d_int> x) { this->x = x; } }; diff --git a/test/compilable/extra-files/dtoh_functions.out b/test/compilable/extra-files/dtoh_functions.out index a172c1c3624c..d9d9260fed83 100644 --- a/test/compilable/extra-files/dtoh_functions.out +++ b/test/compilable/extra-files/dtoh_functions.out @@ -36,11 +36,11 @@ extern "C" _d_int bar(_d_int x); extern "C" _d_int bar2(_d_int x); -extern "C" _d_int bar4(_d_int x/* = 42*/); +extern "C" _d_int bar4(_d_int x = 42); extern _d_int baz(_d_int x); extern _d_int baz2(_d_int x); -extern _d_int baz3(_d_int x/* = 42*/); +extern _d_int baz3(_d_int x = 42); From 1eba99bd33634aaea8b8068bd7060f6a484e45d0 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 22 Oct 2019 15:34:57 +0300 Subject: [PATCH 39/44] Add support for @disable --- src/dmd/dtoh.d | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 8d65f14d7951..44c8c035917d 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -460,6 +460,8 @@ public: } } + if (adparent && fd.isDisabled && global.params.cplusplus < CppStdRevision.cpp11) + buf.printf("private: "); funcToBuffer(tf, fd); if (adparent && tf.isConst()) { @@ -485,7 +487,11 @@ public: } if (adparent && fd.isAbstract()) buf.writestring(" = 0"); + if (adparent && fd.isDisabled && global.params.cplusplus >= CppStdRevision.cpp11) + buf.printf(" = delete"); buf.printf(";\n"); + if (adparent && fd.isDisabled && global.params.cplusplus < CppStdRevision.cpp11) + buf.printf("public:\n"); if (!adparent) buf.printf("\n"); } @@ -745,30 +751,33 @@ public: } adparent = save; // Generate default ctor - buf.printf(" %s(", sd.ident.toChars()); - buf.printf(") {"); - size_t varCount; - foreach (m; *sd.members) + if (!sd.noDefaultCtor) { - if (auto vd = m.isVarDeclaration()) + buf.printf(" %s(", sd.ident.toChars()); + buf.printf(") {"); + size_t varCount; + foreach (m; *sd.members) { - if (!memberField(vd)) - continue; - varCount++; - - if (!vd._init && !vd.type.isTypeBasic()) - continue; - if (vd._init && vd._init.isVoidInitializer()) - continue; - buf.printf(" this->%s = ", vd.ident.toChars()); - if (vd._init) - AST.initializerToExpression(vd._init).accept(this); - else if (vd.type.isTypeBasic()) - vd.type.defaultInitLiteral(Loc.initial).accept(this); - buf.printf(";"); + if (auto vd = m.isVarDeclaration()) + { + if (!memberField(vd)) + continue; + varCount++; + + if (!vd._init && !vd.type.isTypeBasic()) + continue; + if (vd._init && vd._init.isVoidInitializer()) + continue; + buf.printf(" this->%s = ", vd.ident.toChars()); + if (vd._init) + AST.initializerToExpression(vd._init).accept(this); + else if (vd.type.isTypeBasic()) + vd.type.defaultInitLiteral(Loc.initial).accept(this); + buf.printf(";"); + } } + buf.printf(" }\n"); } - buf.printf(" }\n"); version (none) { From 65b05f4be63051bfc07e6453cdb631dd13eefa8c Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 22 Oct 2019 17:56:10 +0300 Subject: [PATCH 40/44] Improve default ctor generation --- src/dmd/dtoh.d | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 44c8c035917d..7c1274fb0629 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -764,8 +764,22 @@ public: continue; varCount++; - if (!vd._init && !vd.type.isTypeBasic()) + if (!vd._init && !vd.type.isTypeBasic() && !vd.type.isTypePointer && !vd.type.isTypeStruct && + !vd.type.isTypeClass && !vd.type.isTypeDArray && !vd.type.isTypeSArray) + { + continue; + } + if (!vd._init && vd.type.isTypeStruct) + { + auto s = vd.type.isTypeStruct().toChars(); + while (*s != '\0' && *s != '!') // Find if it's template instance + { + ++s; + } + if (*s == '\0') // Ignore template instance, for now + buf.printf(" this->%s = %s();", vd.ident.toChars(), vd.type.isTypeStruct().toChars()); continue; + } if (vd._init && vd._init.isVoidInitializer()) continue; buf.printf(" this->%s = ", vd.ident.toChars()); @@ -773,6 +787,13 @@ public: AST.initializerToExpression(vd._init).accept(this); else if (vd.type.isTypeBasic()) vd.type.defaultInitLiteral(Loc.initial).accept(this); + else if (vd.type.isTypePointer || vd.type.isTypeClass) + buf.printf("_d_null"); + else if (vd.type.isTypeDArray) + { + this.visit(vd.type.isTypeDArray()); + buf.printf("()"); + } buf.printf(";"); } } From c3f2a245cef160bdf586df43d5c20d38dfd3b94b Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Tue, 22 Oct 2019 18:20:40 +0300 Subject: [PATCH 41/44] Cleanup cxxfrontend.c --- src/tests/cxxfrontend.c | 57 +---------------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/src/tests/cxxfrontend.c b/src/tests/cxxfrontend.c index 42abf4722833..e44cf5bb0f13 100644 --- a/src/tests/cxxfrontend.c +++ b/src/tests/cxxfrontend.c @@ -13,60 +13,7 @@ #include "root/dcompat.h" #include "root/file.h" #include "root/filename.h" -/*#include "root/longdouble.h"*/ -/*#include "root/object.h"*/ -/*#include "root/outbuffer.h"*/ -/*#include "root/port.h"*/ -/*#include "root/rmem.h"*/ -/*#include "root/root.h"*/ - -/*#include "aggregate.h"*/ -/*#include "aliasthis.h"*/ -/*#include "arraytypes.h"*/ -/*#include "attrib.h"*/ -/*#include "compiler.h"*/ -/*#include "complex_t.h"*/ -/*#include "cond.h"*/ -/*#include "ctfe.h"*/ -/*#include "declaration.h"*/ -/*#include "doc.h"*/ -/*#include "dsymbol.h"*/ -/*#include "enum.h"*/ -/*#include "errors.h"*/ -/*#include "expression.h"*/ -/*#include "globals.h"*/ -/*#include "hdrgen.h"*/ -/*#include "identifier.h"*/ -/*#include "id.h"*/ -/*#include "import.h"*/ -/*#include "init.h"*/ -/*#include "json.h"*/ -/*#include "mangle.h"*/ -/*#include "module.h"*/ -/*#include "mtype.h"*/ -/*#include "nspace.h"*/ -/*#include "objc.h"*/ -/*#include "scope.h"*/ -/*#include "statement.h"*/ -/*#include "staticassert.h"*/ -/*#include "target.h"*/ -/*#include "template.h"*/ -/*#include "tokens.h"*/ -/*#include "version.h"*/ - -/*#include "array.h"*/ -/*#include "ctfloat.h"*/ -/*#include "file.h"*/ -/*#include "filename.h"*/ -/*#include "longdouble.h"*/ -/*#include "object.h"*/ -/*// FIXME: UINT64_MAX*/ -/*//#include "outbuffer.h"*/ -/*//#include "port.h"*/ -/*#include "rmem.h"*/ -/*//#include "root.h"*/ -/*//#include "stringtable.h"*/ -/*#include "thread.h"*/ +#include "root/bitarray.h" #include "visitor.h" #include "frontend.h" @@ -424,8 +371,6 @@ int main(int argc, char **argv) test_expression(); test_target(); test_emplace(); - test_parameters(); - test_location(); test_array(); test_outbuffer(); From 00d65f8888838c3158dbeb95a6a5c1eca94779dd Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 23 Oct 2019 16:29:05 +0300 Subject: [PATCH 42/44] Update struct decl test --- test/compilable/extra-files/dtoh_StructDeclaration.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compilable/extra-files/dtoh_StructDeclaration.out b/test/compilable/extra-files/dtoh_StructDeclaration.out index e4943574f47e..62c706aedf32 100644 --- a/test/compilable/extra-files/dtoh_StructDeclaration.out +++ b/test/compilable/extra-files/dtoh_StructDeclaration.out @@ -103,6 +103,6 @@ struct Inner typedef Inner I; class C; - A() { this->a = 0; } + A() { this->a = 0; this->s = S(); } }; From 144c85d52e9d7fd272e62ed973639a5463de53bb Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Wed, 23 Oct 2019 18:14:05 +0300 Subject: [PATCH 43/44] Use member initializer list for default ctor definition --- src/dmd/dtoh.d | 41 ++++++++----------- src/dmd/root/dcompat.h | 5 +++ .../extra-files/dtoh_AnonDeclaration.out | 2 +- .../extra-files/dtoh_ClassDeclaration.out | 2 +- .../extra-files/dtoh_StructDeclaration.out | 12 +++--- .../extra-files/dtoh_TemplateDeclaration.out | 2 +- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/dmd/dtoh.d b/src/dmd/dtoh.d index 7c1274fb0629..6a2ec7e6fc3e 100644 --- a/src/dmd/dtoh.d +++ b/src/dmd/dtoh.d @@ -753,9 +753,9 @@ public: // Generate default ctor if (!sd.noDefaultCtor) { - buf.printf(" %s(", sd.ident.toChars()); - buf.printf(") {"); + buf.printf(" %s()", sd.ident.toChars()); size_t varCount; + bool first = true; foreach (m; *sd.members) { if (auto vd = m.isVarDeclaration()) @@ -769,35 +769,28 @@ public: { continue; } - if (!vd._init && vd.type.isTypeStruct) - { - auto s = vd.type.isTypeStruct().toChars(); - while (*s != '\0' && *s != '!') // Find if it's template instance - { - ++s; - } - if (*s == '\0') // Ignore template instance, for now - buf.printf(" this->%s = %s();", vd.ident.toChars(), vd.type.isTypeStruct().toChars()); - continue; - } if (vd._init && vd._init.isVoidInitializer()) continue; - buf.printf(" this->%s = ", vd.ident.toChars()); + + if (first) + { + buf.printf(" : "); + first = false; + } + else + { + buf.printf(", "); + } + buf.printf("%s(", vd.ident.toChars()); + if (vd._init) - AST.initializerToExpression(vd._init).accept(this); - else if (vd.type.isTypeBasic()) - vd.type.defaultInitLiteral(Loc.initial).accept(this); - else if (vd.type.isTypePointer || vd.type.isTypeClass) - buf.printf("_d_null"); - else if (vd.type.isTypeDArray) { - this.visit(vd.type.isTypeDArray()); - buf.printf("()"); + AST.initializerToExpression(vd._init).accept(this); } - buf.printf(";"); + buf.printf(")"); } } - buf.printf(" }\n"); + buf.printf(" {}\n"); } version (none) diff --git a/src/dmd/root/dcompat.h b/src/dmd/root/dcompat.h index 3b8a2f76bdc7..e9921e33a3bd 100644 --- a/src/dmd/root/dcompat.h +++ b/src/dmd/root/dcompat.h @@ -29,6 +29,11 @@ struct DArray { size_t length; const char *ptr; + + DArray() : length(0), ptr(NULL) {} + + DArray(const char str[]) : length(strlen(str)), ptr(str) {} + DArray& operator=(const char str[]) { ptr = str; length = strlen(str); } }; diff --git a/test/compilable/extra-files/dtoh_AnonDeclaration.out b/test/compilable/extra-files/dtoh_AnonDeclaration.out index a3aff4230c70..4d959afb68db 100644 --- a/test/compilable/extra-files/dtoh_AnonDeclaration.out +++ b/test/compilable/extra-files/dtoh_AnonDeclaration.out @@ -43,6 +43,6 @@ struct S extern "C" _d_void foo(); _d_void bar(); }; - S() { } + S() {} }; diff --git a/test/compilable/extra-files/dtoh_ClassDeclaration.out b/test/compilable/extra-files/dtoh_ClassDeclaration.out index 8c358bb677a8..21236d62e733 100644 --- a/test/compilable/extra-files/dtoh_ClassDeclaration.out +++ b/test/compilable/extra-files/dtoh_ClassDeclaration.out @@ -80,7 +80,7 @@ public: struct Inner { _d_int x; - Inner() { this->x = 0; } + Inner() : x() {} }; class InnerC diff --git a/test/compilable/extra-files/dtoh_StructDeclaration.out b/test/compilable/extra-files/dtoh_StructDeclaration.out index 62c706aedf32..5ed37bf7d522 100644 --- a/test/compilable/extra-files/dtoh_StructDeclaration.out +++ b/test/compilable/extra-files/dtoh_StructDeclaration.out @@ -36,7 +36,7 @@ struct S _d_byte a; _d_int b; _d_long c; - S() { this->a = 0; this->b = 0; this->c = 0LL; } + S() : a(), b(), c() {} }; struct S2 @@ -45,7 +45,7 @@ struct S2 _d_int b; _d_long c; S2(_d_int a); - S2() { this->a = 42; this->b = 0; this->c = 0LL; } + S2() : a(42), b(), c() {} }; struct S3 @@ -54,7 +54,7 @@ struct S3 _d_int b; _d_long c; extern "C" S3(_d_int a); - S3() { this->a = 42; this->b = 0; this->c = 0LL; } + S3() : a(42), b(), c() {} }; struct @@ -71,7 +71,7 @@ Aligned _d_int b; _d_long c; Aligned(_d_int a); - Aligned() { this->a = 0; this->b = 0; this->c = 0LL; } + Aligned() : a(), b(), c() {} }; #if defined(__DMC__) #pragma pack(pop) @@ -97,12 +97,12 @@ struct A struct Inner { _d_int x; - Inner() { this->x = 0; } + Inner() : x() {} }; typedef Inner I; class C; - A() { this->a = 0; this->s = S(); } + A() : a(), s() {} }; diff --git a/test/compilable/extra-files/dtoh_TemplateDeclaration.out b/test/compilable/extra-files/dtoh_TemplateDeclaration.out index 4064f5cda5b8..c9d42e732592 100644 --- a/test/compilable/extra-files/dtoh_TemplateDeclaration.out +++ b/test/compilable/extra-files/dtoh_TemplateDeclaration.out @@ -40,6 +40,6 @@ struct A struct B { A<_d_int> x; - B() { } + B() : x() {} }; From 341de3579834e4b0760a43ee6dbf5a563318606d Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Thu, 14 Nov 2019 17:08:41 +0200 Subject: [PATCH 44/44] Add frontend.h dep to build.d --- src/build.d | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/build.d b/src/build.d index ccdd13b9e65b..f253315f1b7c 100755 --- a/src/build.d +++ b/src/build.d @@ -41,6 +41,7 @@ immutable rootDeps = [ &clean, &checkwhitespace, &runCxxUnittest, + &frontendH, &detab, &tolf, &zip, @@ -354,6 +355,51 @@ alias dmdDefault = makeDep!((builder, dep) => builder .deps([dmdExe(null, null), dmdConf]) ); +//alias frontendH = makeDep!((builder, dep) => builder +alias frontendH = makeDep!((builder, dep) { + //writeln("==="); + //writeln( + //env["DMD_PATH"], + //"-I.", + //"-J" ~ env["G"], + //"-J../res", + //"-version=NoBackend", + //"-HCf=./frontend.h", + //"-c", + //.sources.frontend); + //writeln(env.keys()); + //writeln(env["D"]); + //writeln(env["RES"]); + //writeln(.sources.lexer); + //writeln(.sources.lexer.filter!(s => s != "id.d")); + //writeln("==="); + + static string[] fileArray(string dir, string files) + { + return files.split.map!(e => dir.buildPath(e)).array; + } + + auto lexerSRCS = fileArray(env["D"], " + console.d entity.d errors.d filecache.d globals.d identifier.d lexer.d tokens.d utf.d"); + + builder + .name("frontend.h") + .description("Generate frontend.h") + .deps([dmdDefault]) + //.sources(.sources.frontendHeaders ~ .sources.dmd ~ .sources.root) + //.sources(.sources.frontend) + .command([ + env["DMD_PATH"], + "-I.", + "-J" ~ env["G"], + "-J../res", + "-version=NoBackend", + "-HCf=./dmd/frontend.h", + "-c"].chain(.sources.frontend, lexerSRCS).array + ); + //env["DMD_PATH"] = env["G"].buildPath("dmd").exeName; +}); + /// Dependency to run the DMD unittest executable. alias runDmdUnittest = makeDep!((builder, dep) { auto dmdUnittestExe = dmdExe("-unittest", ["-version=NoMain", "-unittest", "-main"]); @@ -384,7 +430,7 @@ alias runCxxUnittest = makeDep!((runCxxBuilder, runCxxDep) { .name("cxx-unittest") .description("Build the C++ unittests") .msg("(DMD) CXX-UNITTEST") - .deps([lexer, backend, cxxFrontend]) + .deps([lexer, backend, frontendH, cxxFrontend]) .sources(sources.dmd ~ sources.root) .target(env["G"].buildPath("cxx-unittest").exeName) .command([ env["HOST_DMD_RUN"], "-of=" ~ exeDep.target, "-vtls", "-J" ~ env["RES"], @@ -1037,7 +1083,7 @@ auto sourceFiles() aggregate.h aliasthis.h arraytypes.h attrib.h compiler.h complex_t.h cond.h ctfe.h declaration.h dsymbol.h doc.h enum.h errors.h expression.h globals.h hdrgen.h identifier.h id.h import.h init.h json.h mangle.h module.h mtype.h nspace.h objc.h scope.h - statement.h staticassert.h target.h template.h tokens.h version.h visitor.h + statement.h staticassert.h target.h template.h tokens.h version.h visitor.h frontend.h "), lexer: fileArray(env["D"], " console.d entity.d errors.d filecache.d globals.d id.d identifier.d lexer.d tokens.d utf.d