Mercurial > projects > ddmd
diff dmd/Declaration.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 2cc604139636 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/Declaration.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,311 @@ +module dmd.Declaration; + +import dmd.Dsymbol; +import dmd.Type; +import dmd.PROT; +import dmd.LINK; +import dmd.Identifier; +import dmd.Scope; +import dmd.Loc; +import dmd.STC; +import dmd.FuncDeclaration; +import dmd.VarDeclaration; +import dmd.OutBuffer; + +import std.stdio : writef; + +import core.stdc.ctype; +import core.stdc.stdio : sprintf; + +string mangle(Declaration sthis) +{ + scope OutBuffer buf = new OutBuffer(); + + string id; + Dsymbol s = sthis; + + //printf(".mangle(%s)\n", sthis.toChars()); + do + { + //printf("mangle: s = %p, '%s', parent = %p\n", s, s.toChars(), s.parent); + if (s.ident) + { + FuncDeclaration fd = s.isFuncDeclaration(); + if (s !is sthis && fd) + { + id = mangle(fd); + buf.prependstring(id); + goto L1; + } + else + { + id = s.ident.toChars(); + int len = id.length; + char tmp[len.sizeof * 3 + 1]; + buf.prependstring(id); + len = sprintf(tmp.ptr, "%d".ptr, len); + buf.prependstring(tmp[0..len]); + } + } + else + buf.prependstring("0"); + s = s.parent; + } while (s); + +// buf.prependstring("_D"); +L1: + //printf("deco = '%s'\n", sthis.type.deco ? sthis.type.deco : "null"); + //printf("sthis.type = %s\n", sthis.type.toChars()); + FuncDeclaration fd = sthis.isFuncDeclaration(); + if (fd && (fd.needThis() || fd.isNested())) + buf.writeByte(Type.needThisPrefix()); + if (sthis.type.deco) + buf.writestring(sthis.type.deco); + else + { +debug { + if (!fd.inferRetType) + writef("%s\n", fd.toChars()); +} + assert(fd.inferRetType); + } + + id = buf.extractString(); + return id; +} + +class Declaration : Dsymbol +{ + Type type; + Type originalType; // before semantic analysis + STC storage_class = STC.STCundefined; + PROT protection = PROT.PROTundefined; + LINK linkage = LINK.LINKdefault; + int inuse; // used to detect cycles + + this(Identifier id) + { + super(id); + } + + void semantic(Scope sc) + { + assert(false); + } + + string kind() + { + assert(false); + } + + uint size(Loc loc) + { + assert(false); + } + + /************************************* + * Check to see if declaration can be modified in this context (sc). + * Issue error if not. + */ + void checkModify(Loc loc, Scope sc, Type t) + { + if (sc.incontract && isParameter()) + error(loc, "cannot modify parameter '%s' in contract", toChars()); + + if (isCtorinit()) + { + // It's only modifiable if inside the right constructor + Dsymbol s = sc.func; + while (true) + { + FuncDeclaration fd = null; + if (s) + fd = s.isFuncDeclaration(); + if (fd && ((fd.isCtorDeclaration() && storage_class & STC.STCfield) || + (fd.isStaticCtorDeclaration() && !(storage_class & STC.STCfield))) && + fd.toParent() == toParent() + ) + { + VarDeclaration v = isVarDeclaration(); + assert(v); + v.ctorinit = 1; + //printf("setting ctorinit\n"); + } + else + { + if (s) + { + s = s.toParent2(); + continue; + } + else + { + string p = isStatic() ? "static " : ""; + error(loc, "can only initialize %sconst %s inside %sconstructor", p, toChars(), p); + } + } + break; + } + } + else + { + VarDeclaration v = isVarDeclaration(); + if (v && v.canassign == 0) + { + string p = null; + if (isConst()) + p = "const"; + else if (isInvariant()) + p = "immutable"; + else if (storage_class & STC.STCmanifest) + p = "enum"; + else if (!t.isAssignable()) + p = "struct with immutable members"; + if (p) + { + error(loc, "cannot modify %s", p); + } + } + } + } + + void emitComment(Scope sc) + { + assert(false); + } + + void toDocBuffer(OutBuffer buf) + { + assert(false); + } + + string mangle() + out (result) + { + try + { + int len = result.length; + + assert(len > 0); + //printf("mangle: '%s' => '%s'\n", toChars(), result); + for (int i = 0; i < len; i++) + { + assert(result[i] == '_' || result[i] == '@' || isalnum(result[i]) || result[i] & 0x80); + } + } catch { + writef("Incorrect mangle: '%s'\n", result); + assert(false); + } + } + body + { + //writef("Declaration.mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent.toChars() : "null", linkage); + if (!parent || parent.isModule() || linkage == LINK.LINKcpp) // if at global scope + { + // If it's not a D declaration, no mangling + switch (linkage) + { + case LINK.LINKd: + break; + + case LINK.LINKc: + case LINK.LINKwindows: + case LINK.LINKpascal: + return ident.toChars(); + + case LINK.LINKcpp: +version (CPP_MANGLE) { + return cpp_mangle(this); +} else { + // Windows C++ mangling is done by C++ back end + return ident.toChars(); +} + + case LINK.LINKdefault: + assert(false); + error("forward declaration"); + return ident.toChars(); + + default: + writef("'%s', linkage = %d\n", toChars(), linkage); + assert(0); + } + } + + string p = .mangle(this); + scope OutBuffer buf = new OutBuffer(); + buf.writestring("_D"); + buf.writestring(p); + p = buf.toChars(); + buf.data = null; + //writef("Declaration.mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent.toChars() : "null", linkage, p); + return p; + } + + int isStatic() { return storage_class & STC.STCstatic; } + + bool isStaticConstructor() + { + return false; + } + + bool isStaticDestructor() + { + return false; + } + + bool isDelete() + { + return false; + } + + bool isDataseg() + { + return false; + } + + bool isThreadlocal() + { + assert(false); + } + + bool isCodeseg() + { + return false; + } + + int isCtorinit() { return storage_class & STC.STCctorinit; } + + int isFinal() { return storage_class & STC.STCfinal; } + + bool isAbstract() { return (storage_class & STC.STCabstract) != 0; } + + bool isConst() { return (storage_class & STC.STCconst) != 0; } + + int isInvariant() { return storage_class & STC.STCinvariant; } + + int isAuto() { return storage_class & STC.STCauto; } + + int isScope() { return storage_class & (STC.STCscope | STC.STCauto); } + + int isSynchronized() { return storage_class & STC.STCsynchronized; } + + int isParameter() { return storage_class & STC.STCparameter; } + + bool isDeprecated() { return (storage_class & STC.STCdeprecated) != 0; } + + int isOverride() { return storage_class & STC.STCoverride; } + + int isIn() { return storage_class & STC.STCin; } + + int isOut() { return storage_class & STC.STCout; } + + int isRef() { return storage_class & STC.STCref; } + + PROT prot() + { + return protection; + } + + Declaration isDeclaration() { return this; } +} \ No newline at end of file