diff dmd/declaration.c @ 336:aaade6ded589 trunk

[svn r357] Merged DMD 1.033
author lindquist
date Sat, 12 Jul 2008 19:38:31 +0200
parents 2b72433d5c8c
children 45a67b6f1310
line wrap: on
line diff
--- a/dmd/declaration.c	Sat Jul 12 17:04:36 2008 +0200
+++ b/dmd/declaration.c	Sat Jul 12 19:38:31 2008 +0200
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2007 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -39,7 +39,7 @@
 {
 }
 
-char *Declaration::kind()
+const char *Declaration::kind()
 {
     return "declaration";
 }
@@ -80,6 +80,76 @@
     return protection;
 }
 
+/*************************************
+ * Check to see if declaration can be modified in this context (sc).
+ * Issue error if not.
+ */
+
+#if DMDV2
+void Declaration::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 (1)
+	{
+	    FuncDeclaration *fd = NULL;
+	    if (s)
+		fd = s->isFuncDeclaration();
+	    if (fd &&
+		((fd->isCtorDeclaration() && storage_class & STCfield) ||
+		 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
+		fd->toParent() == toParent()
+	       )
+	    {
+		VarDeclaration *v = isVarDeclaration();
+		assert(v);
+		v->ctorinit = 1;
+		//printf("setting ctorinit\n");
+	    }
+	    else
+	    {
+		if (s)
+		{   s = s->toParent2();
+		    continue;
+		}
+		else
+		{
+		    const char *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)
+	{
+	    char *p = NULL;
+	    if (isConst())
+		p = "const";
+	    else if (isInvariant())
+		p = "invariant";
+	    else if (storage_class & STCmanifest)
+		p = "manifest constant";
+	    else if (!t->isAssignable())
+		p = "struct with immutable members";
+	    if (p)
+	    {	error(loc, "cannot modify %s", p);
+		halt();
+	    }
+	}
+    }
+}
+#endif
+
+
 /********************************* TupleDeclaration ****************************/
 
 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
@@ -97,7 +167,7 @@
     return NULL;
 }
 
-char *TupleDeclaration::kind()
+const char *TupleDeclaration::kind()
 {
     return "tuple";
 }
@@ -231,6 +301,7 @@
 	type = type->semantic(loc, sc);
 	if (sc->parent->isFuncDeclaration() && init)
 	    semantic2(sc);
+	storage_class |= sc->stc & STCdeprecated;
     }
     else if (sem == 1)
     {
@@ -257,7 +328,7 @@
     }
 }
 
-char *TypedefDeclaration::kind()
+const char *TypedefDeclaration::kind()
 {
     return "typedef";
 }
@@ -318,6 +389,7 @@
 
 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
 {
+    //printf("AliasDeclaration::syntaxCopy()\n");
     assert(!s);
     AliasDeclaration *sa;
     if (type)
@@ -466,7 +538,7 @@
     }
 }
 
-char *AliasDeclaration::kind()
+const char *AliasDeclaration::kind()
 {
     return "alias";
 }
@@ -601,7 +673,9 @@
 void VarDeclaration::semantic(Scope *sc)
 {
     //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
-    //printf("type = %s\n", type->toChars());
+    //printf(" type = %s\n", type ? type->toChars() : "null");
+    //printf(" stc = x%x\n", sc->stc);
+    //printf(" storage_class = x%x\n", storage_class);
     //printf("linkage = %d\n", sc->linkage);
     //if (strcmp(toChars(), "mul") == 0) halt();
 
@@ -629,6 +703,7 @@
 	    originalType = type;
 	type = type->semantic(loc, sc);
     }
+    //printf(" semantic type = %s\n", type ? type->toChars() : "null");
 
     type->checkDeprecated(loc, sc);
     linkage = sc->linkage;
@@ -636,7 +711,7 @@
     //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
     protection = sc->protection;
     //printf("sc->stc = %x\n", sc->stc);
-    //printf("storage_class = %x\n", storage_class);
+    //printf("storage_class = x%x\n", storage_class);
 
     Dsymbol *parent = toParent();
     FuncDeclaration *fd = parent->isFuncDeclaration();
@@ -749,6 +824,8 @@
 	    error("field not allowed in interface");
 	}
 
+	/* Templates cannot add fields to aggregates
+	 */
 	TemplateInstance *ti = parent->isTemplateInstance();
 	if (ti)
 	{
@@ -853,10 +930,6 @@
 	    // possibilities.
 	    if (fd && !isStatic() && !isConst() && !init->isVoidInitializer())
 	    {
-		Expression *e1;
-		Type *t;
-		int dim;
-
 		//printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
 		if (!ei)
 		{
@@ -874,15 +947,15 @@
 		    init = ei;
 		}
 
-		e1 = new VarExp(loc, this);
+		Expression *e1 = new VarExp(loc, this);
 
-		t = type->toBasetype();
+		Type *t = type->toBasetype();
 		if (t->ty == Tsarray)
 		{
 		    ei->exp = ei->exp->semantic(sc);
 		    if (!ei->exp->implicitConvTo(type))
 		    {
-			dim = ((TypeSArray *)t)->dim->toInteger();
+			int dim = ((TypeSArray *)t)->dim->toInteger();
 			// If multidimensional static array, treat as one large array
 			while (1)
 			{
@@ -974,7 +1047,7 @@
 	ei = init->isExpInitializer();
     else
     {
-	Expression *e = type->defaultInit();
+	Expression *e = type->defaultInit(loc);
 	if (e)
 	    ei = new ExpInitializer(loc, e);
 	else
@@ -1001,7 +1074,7 @@
     }
 }
 
-char *VarDeclaration::kind()
+const char *VarDeclaration::kind()
 {
     return "variable";
 }
@@ -1020,6 +1093,17 @@
 	buf->writestring("const ");
     if (storage_class & STCstatic)
 	buf->writestring("static ");
+    if (storage_class & STCauto)
+	buf->writestring("auto ");
+#if DMDV2
+    if (storage_class & STCmanifest)
+	buf->writestring("manifest ");
+    if (storage_class & STCinvariant)
+	buf->writestring("invariant ");
+    if (storage_class & STCtls)
+	buf->writestring("__thread ");
+#endif
+
     if (type)
 	type->toCBuffer(buf, ident, hgs);
     else
@@ -1052,15 +1136,18 @@
 }
 
 /************************************
- * Check to see if variable is a reference to an enclosing function
- * or not.
+ * Check to see if this variable is actually in an enclosing function
+ * rather than the current one.
  */
 
 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
 {
+    //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
     if (parent && !isDataseg() && parent != sc->parent)
     {
+	// The function that this variable is in
 	FuncDeclaration *fdv = toParent()->isFuncDeclaration();
+	// The current function
 	FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
 
 	if (fdv && fdthis)
@@ -1077,6 +1164,7 @@
 
 /*******************************
  * Does symbol go into data segment?
+ * Includes extern variables.
  */
 
 int VarDeclaration::isDataseg()
@@ -1201,7 +1289,7 @@
 
 /***************************** TypeInfoConstDeclaration **********************/
 
-#if V2
+#if DMDV2
 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
     : TypeInfoDeclaration(tinfo, 0)
 {
@@ -1210,7 +1298,7 @@
 
 /***************************** TypeInfoInvariantDeclaration **********************/
 
-#if V2
+#if DMDV2
 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
     : TypeInfoDeclaration(tinfo, 0)
 {