changeset 215:a58d8f4b84df trunk

[svn r231] Changed: warnings are no longer treated as an error. Added some comments and cleaned up CallExp::toElem a tiny bit. Fixed: struct literals always reported inplace assignment even if they allocated a temporary. Fixed: passing stuff to a D-style vararg which did inplace assignment was generated suboptimal code.
author lindquist
date Tue, 03 Jun 2008 13:51:09 +0200
parents 629cfc1e7b77
children 3d022aa016ae
files dmd/cast.c dmd/func.c dmd/scope.c dmd/statement.c gen/functions.cpp gen/toir.cpp llvmdc.kdevelop.filelist tangotests/vararg3.d
diffstat 8 files changed, 153 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/cast.c	Fri May 30 19:32:56 2008 +0200
+++ b/dmd/cast.c	Tue Jun 03 13:51:09 2008 +0200
@@ -43,9 +43,8 @@
 	    if (e->op == TOKint64)
 		return e->implicitCastTo(sc, t);
 
-	    fprintf(stdmsg, "warning - ");
-	    error("implicit conversion of expression (%s) of type %s to %s can cause loss of data",
-		toChars(), type->toChars(), t->toChars());
+	    warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data",
+		loc.toChars(), toChars(), type->toChars(), t->toChars());
 	}
 	return castTo(sc, t);
     }
--- a/dmd/func.c	Fri May 30 19:32:56 2008 +0200
+++ b/dmd/func.c	Tue Jun 03 13:51:09 2008 +0200
@@ -308,7 +308,7 @@
 
 #if V2
 		if (!isOverride() && global.params.warnings)
-		    error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
+		    warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars() fdv->toPrettyChars());
 #endif
 
 		if (fdv->toParent() == parent)
@@ -1056,8 +1056,7 @@
 		    {   Expression *e;
 
 			if (global.params.warnings)
-			{   fprintf(stdmsg, "warning - ");
-			    error("no return at end of function");
+			{   warning("%s: no return at end of function", locToChars());
 			}
 
 			if (global.params.useAssert &&
--- a/dmd/scope.c	Fri May 30 19:32:56 2008 +0200
+++ b/dmd/scope.c	Tue Jun 03 13:51:09 2008 +0200
@@ -255,6 +255,7 @@
 		    sc->enclosing &&
 		    sc->enclosing->search(loc, ident, NULL))
 		{
+            // WTF ?
 		    if (global.params.warnings)
 			fprintf(stdmsg, "warning - ");
 		    error(s->loc, "array 'length' hides other 'length' name in outer scope");
--- a/dmd/statement.c	Fri May 30 19:32:56 2008 +0200
+++ b/dmd/statement.c	Tue Jun 03 13:51:09 2008 +0200
@@ -531,8 +531,7 @@
 
 	if (!falloff && global.params.warnings && !s->comeFrom())
 	{
-	    fprintf(stdmsg, "warning - ");
-	    s->error("statement is not reachable");
+	    warning("%s: statement is not reachable", s->loc.toChars());
 	}
 	falloff = s->fallOffEnd();
     }
@@ -2049,8 +2048,7 @@
     {	hasNoDefault = 1;
 
 	if (global.params.warnings)
-	{   fprintf(stdmsg, "warning - ");
-	    error("switch statement has no default");
+	{   warning("%s: switch statement has no default", loc.toChars());
 	}
 
 	// Generate runtime error if the default is hit
--- a/gen/functions.cpp	Fri May 30 19:32:56 2008 +0200
+++ b/gen/functions.cpp	Tue Jun 03 13:51:09 2008 +0200
@@ -799,7 +799,9 @@
     Logger::println("DtoVariadicArgument");
     LOG_SCOPE;
     DVarValue* vv = new DVarValue(argexp->type, dst, true);
+    gIR->exps.push_back(IRExp(NULL, argexp, vv));
     DtoAssign(vv, argexp->toElem(gIR));
+    gIR->exps.pop_back();
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/toir.cpp	Fri May 30 19:32:56 2008 +0200
+++ b/gen/toir.cpp	Tue Jun 03 13:51:09 2008 +0200
@@ -867,6 +867,8 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+// TODO: the method below could really use a cleanup/splitup
+
 DValue* CallExp::toElem(IRState* p)
 {
     Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars());
@@ -911,19 +913,22 @@
         assert(tf);
     }
 
-    // magic stuff
+    // handling of special intrinsics
     bool va_magic = false;
     bool va_intrinsic = false;
     DFuncValue* dfv = fn->isFunc();
     if (dfv && dfv->func) {
         FuncDeclaration* fndecl = dfv->func;
+        // vararg intrinsic
         if (fndecl->llvmInternal == LLVMva_intrinsic) {
             va_magic = true;
             va_intrinsic = true;
         }
+        // va_start instruction
         else if (fndecl->llvmInternal == LLVMva_start) {
             va_magic = true;
         }
+        // va_arg instruction
         else if (fndecl->llvmInternal == LLVMva_arg) {
             //Argument* fnarg = Argument::getNth(tf->parameters, 0);
             Expression* exp = (Expression*)arguments->data[0];
@@ -933,11 +938,14 @@
             if (DtoIsPassedByRef(t))
                 llt = getPtrToType(llt);
             // TODO
+            // issue a warning for broken va_arg instruction.
             if (strcmp(global.params.llvmArch, "x86") != 0) {
-                warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars());
+                warning("%s: va_arg for C variadic functions is probably broken for anything but x86", loc.toChars());
             }
+            // done
             return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
         }
+        // alloca
         else if (fndecl->llvmInternal == LLVMalloca) {
             //Argument* fnarg = Argument::getNth(tf->parameters, 0);
             Expression* exp = (Expression*)arguments->data[0];
@@ -945,6 +953,7 @@
             if (expv->getType()->toBasetype()->ty != Tint32)
                 expv = DtoCast(expv, Type::tint32);
             LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
+            // done
             return new DImValue(type, alloc);
         }
     }
@@ -965,6 +974,8 @@
 
     const llvm::FunctionType* llfnty = 0;
 
+    // TODO: review the stuff below, using the llvm type to choose seem like a bad idea. the D type should be used.
+    //
     // normal function call
     if (llvm::isa<llvm::FunctionType>(funcval->getType())) {
         llfnty = llvm::cast<llvm::FunctionType>(funcval->getType());
@@ -1082,110 +1093,107 @@
             llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty));
         }
     }
-    // regular arguments
+    // d variadic function
+    else if (tf->linkage == LINKd && tf->varargs == 1)
+    {
+        Logger::println("doing d-style variadic arguments");
+
+        size_t nimplicit = j;
+
+        std::vector<const LLType*> vtypes;
+
+        // number of non variadic args
+        int begin = tf->parameters->dim;
+        Logger::println("num non vararg params = %d", begin);
+
+        // build struct with argument types
+        for (int i=begin; i<arguments->dim; i++)
+        {
+            Argument* argu = Argument::getNth(tf->parameters, i);
+            Expression* argexp = (Expression*)arguments->data[i];
+            vtypes.push_back(DtoType(argexp->type));
+        }
+        const llvm::StructType* vtype = llvm::StructType::get(vtypes);
+        Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
+        LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
+
+        // store arguments in the struct
+        for (int i=begin,k=0; i<arguments->dim; i++,k++)
+        {
+            Expression* argexp = (Expression*)arguments->data[i];
+            if (global.params.llvmAnnotate)
+                DtoAnnotation(argexp->toChars());
+            DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp"));
+        }
+
+        // build type info array
+        assert(Type::typeinfo->ir.irStruct->constInit);
+        const LLType* typeinfotype = DtoType(Type::typeinfo->type);
+        const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
+
+        llvm::GlobalVariable* typeinfomem =
+            new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module);
+        Logger::cout() << "_arguments storage: " << *typeinfomem << '\n';
+
+        std::vector<LLConstant*> vtypeinfos;
+        for (int i=begin,k=0; i<arguments->dim; i++,k++)
+        {
+            Expression* argexp = (Expression*)arguments->data[i];
+            vtypeinfos.push_back(DtoTypeInfoOf(argexp->type));
+        }
+
+        // apply initializer
+        LLConstant* tiinits = llvm::ConstantArray::get(typeinfoarraytype, vtypeinfos);
+        typeinfomem->setInitializer(tiinits);
+
+        // put data in d-array
+        std::vector<LLConstant*> pinits;
+        pinits.push_back(DtoConstSize_t(vtype->getNumElements()));
+        pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype)));
+        const LLType* tiarrty = llfnty->getParamType(j)->getContainedType(0);
+        tiinits = llvm::ConstantStruct::get(pinits);
+        LLValue* typeinfoarrayparam = new llvm::GlobalVariable(tiarrty,
+            true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array", gIR->module);
+
+        // specify arguments
+        llargs[j] = typeinfoarrayparam;;
+        j++;
+        llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
+        j++;
+
+        // pass non variadic args
+        for (int i=0; i<begin; i++)
+        {
+            Argument* fnarg = Argument::getNth(tf->parameters, i);
+            DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
+            llargs[j] = argval->getRVal();
+            j++;
+        }
+
+        // make sure arg vector has the right size
+        llargs.resize(nimplicit+begin+2);
+    }
+    // normal function call
     else
     {
-        // d variadic function?
-        if (tf->linkage == LINKd && tf->varargs == 1)
-        {
-            Logger::println("doing d-style variadic arguments");
-
-            size_t nimplicit = j;
-
-            std::vector<const LLType*> vtypes;
-
-            // number of non variadic args
-            int begin = tf->parameters->dim;
-            Logger::println("num non vararg params = %d", begin);
-
-            // build struct with argument types
-            for (int i=begin; i<arguments->dim; i++)
-            {
-                Argument* argu = Argument::getNth(tf->parameters, i);
-                Expression* argexp = (Expression*)arguments->data[i];
-                vtypes.push_back(DtoType(argexp->type));
-            }
-            const llvm::StructType* vtype = llvm::StructType::get(vtypes);
-            Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
-            LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
-
-            // store arguments in the struct
-            for (int i=begin,k=0; i<arguments->dim; i++,k++)
-            {
-                Expression* argexp = (Expression*)arguments->data[i];
-                if (global.params.llvmAnnotate)
-                    DtoAnnotation(argexp->toChars());
-                DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp"));
-            }
-
-            // build type info array
-            assert(Type::typeinfo->ir.irStruct->constInit);
-            const LLType* typeinfotype = DtoType(Type::typeinfo->type);
-            const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
-
-            llvm::GlobalVariable* typeinfomem =
-                new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module);
-            Logger::cout() << "_arguments storage: " << *typeinfomem << '\n';
-
-            std::vector<LLConstant*> vtypeinfos;
-            for (int i=begin,k=0; i<arguments->dim; i++,k++)
-            {
-                Expression* argexp = (Expression*)arguments->data[i];
-                vtypeinfos.push_back(DtoTypeInfoOf(argexp->type));
+        Logger::println("doing normal arguments");
+        for (int i=0; i<arguments->dim; i++,j++) {
+            Argument* fnarg = Argument::getNth(tf->parameters, i);
+            if (global.params.llvmAnnotate)
+                DtoAnnotation(((Expression*)arguments->data[i])->toChars());
+            DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
+            llargs[j] = argval->getRVal();
+            if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) {
+                llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
             }
 
-            // apply initializer
-            LLConstant* tiinits = llvm::ConstantArray::get(typeinfoarraytype, vtypeinfos);
-            typeinfomem->setInitializer(tiinits);
-
-            // put data in d-array
-            std::vector<LLConstant*> pinits;
-            pinits.push_back(DtoConstSize_t(vtype->getNumElements()));
-            pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype)));
-            const LLType* tiarrty = llfnty->getParamType(j)->getContainedType(0);
-            tiinits = llvm::ConstantStruct::get(pinits);
-            LLValue* typeinfoarrayparam = new llvm::GlobalVariable(tiarrty,
-                true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array", gIR->module);
-
-            // specify arguments
-            llargs[j] = typeinfoarrayparam;;
-            j++;
-            llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
-            j++;
-
-            // pass non variadic args
-            for (int i=0; i<begin; i++)
-            {
-                Argument* fnarg = Argument::getNth(tf->parameters, i);
-                DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
-                llargs[j] = argval->getRVal();
-                j++;
-            }
-
-            // make sure arg vector has the right size
-            llargs.resize(nimplicit+begin+2);
-        }
-        // normal function
-        else {
-            Logger::println("doing normal arguments");
-            for (int i=0; i<arguments->dim; i++,j++) {
-                Argument* fnarg = Argument::getNth(tf->parameters, i);
-                if (global.params.llvmAnnotate)
-                    DtoAnnotation(((Expression*)arguments->data[i])->toChars());
-                DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
-                llargs[j] = argval->getRVal();
-                if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) {
-                    llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
-                }
-
-                // this hack is necessary :/
-                if (dfn && dfn->func && dfn->func->runTimeHack) {
-                    if (llfnty->getParamType(j) != NULL) {
-                        if (llargs[j]->getType() != llfnty->getParamType(j)) {
-                            Logger::println("llvmRunTimeHack==true - force casting argument");
-                            Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
-                            llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
-                        }
+            // this hack is necessary :/
+            if (dfn && dfn->func && dfn->func->runTimeHack) {
+                if (llfnty->getParamType(j) != NULL) {
+                    if (llargs[j]->getType() != llfnty->getParamType(j)) {
+                        Logger::println("llvmRunTimeHack==true - force casting argument");
+                        Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
+                        llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
                     }
                 }
             }
@@ -2720,11 +2728,13 @@
     const LLType* llt = DtoType(type);
 
     LLValue* mem = 0;
+    bool isinplace = true;
 
     // temporary struct literal
     if (!p->topexp() || p->topexp()->e2 != this)
     {
         sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
+        isinplace = false;
     }
     // already has memory
     else
@@ -2777,7 +2787,7 @@
         j++;
     }
 
-    return new DImValue(type, sptr, true);
+    return new DImValue(type, sptr, isinplace);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/llvmdc.kdevelop.filelist	Fri May 30 19:32:56 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Tue Jun 03 13:51:09 2008 +0200
@@ -748,6 +748,7 @@
 tangotests/a.d
 tangotests/aa1.d
 tangotests/aa2.d
+tangotests/align1.d
 tangotests/b.d
 tangotests/c.d
 tangotests/classes1.d
@@ -757,6 +758,7 @@
 tangotests/files1.d
 tangotests/h.d
 tangotests/i.d
+tangotests/ina1.d
 tangotests/j.d
 tangotests/k.d
 tangotests/l.d
@@ -777,6 +779,7 @@
 tangotests/vararg1.d
 tangotests/vararg2.d
 tangotests/vararg3.d
+tangotests/vararg4.d
 test
 test/a.d
 test/aa1.d
--- a/tangotests/vararg3.d	Fri May 30 19:32:56 2008 +0200
+++ b/tangotests/vararg3.d	Tue Jun 03 13:51:09 2008 +0200
@@ -35,6 +35,16 @@
     }
 }
 
+ struct TLA
+ {
+    char[3] acronym;
+
+    char[] toString()
+    {
+        return acronym;
+    }
+}
+
 void main()
 {
     User user = User("Bob Doe", "bd", 47);
@@ -81,6 +91,24 @@
     print("Mixed:\n");
     print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n');
     print(42, ' ', cast(byte)12, ' ', user, ' ', cast(short)1445, " foo\n");
+
+    print("International:\n");
+    print('æ','ø','å','\n');
+    print('Æ','Ø','Å','\n');
+    print("rød grød med fløde\n");
+    print("Heiße\n");
+
+    print("TLAs:\n");
+    TLA tla1 = TLA("FBI");
+    TLA tla2 = TLA("CIA");
+    TLA tla3 = TLA("TLA");
+    print(tla1);
+    print(tla2);
+    print(tla3, '\n');
+    print(tla1, tla2, tla3, '\n');
+    print(TLA("FBI"), TLA("CIA"), TLA("TLA"), '\n');
+
+    print("Done!\n");
 }
 
 private void* get_va_arg(TypeInfo ti, ref void* vp)