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