mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +03:00
[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.
This commit is contained in:
parent
d50cb50aaf
commit
590d44d302
8 changed files with 153 additions and 113 deletions
|
@ -43,9 +43,8 @@ Expression *Expression::implicitCastTo(Scope *sc, Type *t)
|
||||||
if (e->op == TOKint64)
|
if (e->op == TOKint64)
|
||||||
return e->implicitCastTo(sc, t);
|
return e->implicitCastTo(sc, t);
|
||||||
|
|
||||||
fprintf(stdmsg, "warning - ");
|
warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data",
|
||||||
error("implicit conversion of expression (%s) of type %s to %s can cause loss of data",
|
loc.toChars(), toChars(), type->toChars(), t->toChars());
|
||||||
toChars(), type->toChars(), t->toChars());
|
|
||||||
}
|
}
|
||||||
return castTo(sc, t);
|
return castTo(sc, t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,7 +308,7 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||||
|
|
||||||
#if V2
|
#if V2
|
||||||
if (!isOverride() && global.params.warnings)
|
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
|
#endif
|
||||||
|
|
||||||
if (fdv->toParent() == parent)
|
if (fdv->toParent() == parent)
|
||||||
|
@ -1056,8 +1056,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||||
{ Expression *e;
|
{ Expression *e;
|
||||||
|
|
||||||
if (global.params.warnings)
|
if (global.params.warnings)
|
||||||
{ fprintf(stdmsg, "warning - ");
|
{ warning("%s: no return at end of function", locToChars());
|
||||||
error("no return at end of function");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.params.useAssert &&
|
if (global.params.useAssert &&
|
||||||
|
|
|
@ -255,6 +255,7 @@ Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
|
||||||
sc->enclosing &&
|
sc->enclosing &&
|
||||||
sc->enclosing->search(loc, ident, NULL))
|
sc->enclosing->search(loc, ident, NULL))
|
||||||
{
|
{
|
||||||
|
// WTF ?
|
||||||
if (global.params.warnings)
|
if (global.params.warnings)
|
||||||
fprintf(stdmsg, "warning - ");
|
fprintf(stdmsg, "warning - ");
|
||||||
error(s->loc, "array 'length' hides other 'length' name in outer scope");
|
error(s->loc, "array 'length' hides other 'length' name in outer scope");
|
||||||
|
|
|
@ -531,8 +531,7 @@ int CompoundStatement::fallOffEnd()
|
||||||
|
|
||||||
if (!falloff && global.params.warnings && !s->comeFrom())
|
if (!falloff && global.params.warnings && !s->comeFrom())
|
||||||
{
|
{
|
||||||
fprintf(stdmsg, "warning - ");
|
warning("%s: statement is not reachable", s->loc.toChars());
|
||||||
s->error("statement is not reachable");
|
|
||||||
}
|
}
|
||||||
falloff = s->fallOffEnd();
|
falloff = s->fallOffEnd();
|
||||||
}
|
}
|
||||||
|
@ -2049,8 +2048,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
|
||||||
{ hasNoDefault = 1;
|
{ hasNoDefault = 1;
|
||||||
|
|
||||||
if (global.params.warnings)
|
if (global.params.warnings)
|
||||||
{ fprintf(stdmsg, "warning - ");
|
{ warning("%s: switch statement has no default", loc.toChars());
|
||||||
error("switch statement has no default");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate runtime error if the default is hit
|
// Generate runtime error if the default is hit
|
||||||
|
|
|
@ -799,7 +799,9 @@ void DtoVariadicArgument(Expression* argexp, LLValue* dst)
|
||||||
Logger::println("DtoVariadicArgument");
|
Logger::println("DtoVariadicArgument");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
DVarValue* vv = new DVarValue(argexp->type, dst, true);
|
DVarValue* vv = new DVarValue(argexp->type, dst, true);
|
||||||
|
gIR->exps.push_back(IRExp(NULL, argexp, vv));
|
||||||
DtoAssign(vv, argexp->toElem(gIR));
|
DtoAssign(vv, argexp->toElem(gIR));
|
||||||
|
gIR->exps.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
216
gen/toir.cpp
216
gen/toir.cpp
|
@ -867,6 +867,8 @@ DValue* ModAssignExp::toElem(IRState* p)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: the method below could really use a cleanup/splitup
|
||||||
|
|
||||||
DValue* CallExp::toElem(IRState* p)
|
DValue* CallExp::toElem(IRState* p)
|
||||||
{
|
{
|
||||||
Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars());
|
Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||||
|
@ -911,19 +913,22 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
assert(tf);
|
assert(tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// magic stuff
|
// handling of special intrinsics
|
||||||
bool va_magic = false;
|
bool va_magic = false;
|
||||||
bool va_intrinsic = false;
|
bool va_intrinsic = false;
|
||||||
DFuncValue* dfv = fn->isFunc();
|
DFuncValue* dfv = fn->isFunc();
|
||||||
if (dfv && dfv->func) {
|
if (dfv && dfv->func) {
|
||||||
FuncDeclaration* fndecl = dfv->func;
|
FuncDeclaration* fndecl = dfv->func;
|
||||||
|
// vararg intrinsic
|
||||||
if (fndecl->llvmInternal == LLVMva_intrinsic) {
|
if (fndecl->llvmInternal == LLVMva_intrinsic) {
|
||||||
va_magic = true;
|
va_magic = true;
|
||||||
va_intrinsic = true;
|
va_intrinsic = true;
|
||||||
}
|
}
|
||||||
|
// va_start instruction
|
||||||
else if (fndecl->llvmInternal == LLVMva_start) {
|
else if (fndecl->llvmInternal == LLVMva_start) {
|
||||||
va_magic = true;
|
va_magic = true;
|
||||||
}
|
}
|
||||||
|
// va_arg instruction
|
||||||
else if (fndecl->llvmInternal == LLVMva_arg) {
|
else if (fndecl->llvmInternal == LLVMva_arg) {
|
||||||
//Argument* fnarg = Argument::getNth(tf->parameters, 0);
|
//Argument* fnarg = Argument::getNth(tf->parameters, 0);
|
||||||
Expression* exp = (Expression*)arguments->data[0];
|
Expression* exp = (Expression*)arguments->data[0];
|
||||||
|
@ -933,11 +938,14 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
if (DtoIsPassedByRef(t))
|
if (DtoIsPassedByRef(t))
|
||||||
llt = getPtrToType(llt);
|
llt = getPtrToType(llt);
|
||||||
// TODO
|
// TODO
|
||||||
|
// issue a warning for broken va_arg instruction.
|
||||||
if (strcmp(global.params.llvmArch, "x86") != 0) {
|
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"));
|
return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
|
||||||
}
|
}
|
||||||
|
// alloca
|
||||||
else if (fndecl->llvmInternal == LLVMalloca) {
|
else if (fndecl->llvmInternal == LLVMalloca) {
|
||||||
//Argument* fnarg = Argument::getNth(tf->parameters, 0);
|
//Argument* fnarg = Argument::getNth(tf->parameters, 0);
|
||||||
Expression* exp = (Expression*)arguments->data[0];
|
Expression* exp = (Expression*)arguments->data[0];
|
||||||
|
@ -945,6 +953,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
if (expv->getType()->toBasetype()->ty != Tint32)
|
if (expv->getType()->toBasetype()->ty != Tint32)
|
||||||
expv = DtoCast(expv, Type::tint32);
|
expv = DtoCast(expv, Type::tint32);
|
||||||
LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
|
LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
|
||||||
|
// done
|
||||||
return new DImValue(type, alloc);
|
return new DImValue(type, alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -965,6 +974,8 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
|
|
||||||
const llvm::FunctionType* llfnty = 0;
|
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
|
// normal function call
|
||||||
if (llvm::isa<llvm::FunctionType>(funcval->getType())) {
|
if (llvm::isa<llvm::FunctionType>(funcval->getType())) {
|
||||||
llfnty = llvm::cast<llvm::FunctionType>(funcval->getType());
|
llfnty = llvm::cast<llvm::FunctionType>(funcval->getType());
|
||||||
|
@ -1082,110 +1093,107 @@ DValue* CallExp::toElem(IRState* p)
|
||||||
llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty));
|
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
|
else
|
||||||
{
|
{
|
||||||
// d variadic function?
|
Logger::println("doing normal arguments");
|
||||||
if (tf->linkage == LINKd && tf->varargs == 1)
|
for (int i=0; i<arguments->dim; i++,j++) {
|
||||||
{
|
Argument* fnarg = Argument::getNth(tf->parameters, i);
|
||||||
Logger::println("doing d-style variadic arguments");
|
if (global.params.llvmAnnotate)
|
||||||
|
DtoAnnotation(((Expression*)arguments->data[i])->toChars());
|
||||||
size_t nimplicit = j;
|
DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
|
||||||
|
llargs[j] = argval->getRVal();
|
||||||
std::vector<const LLType*> vtypes;
|
if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) {
|
||||||
|
llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
|
||||||
// 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
|
// this hack is necessary :/
|
||||||
assert(Type::typeinfo->ir.irStruct->constInit);
|
if (dfn && dfn->func && dfn->func->runTimeHack) {
|
||||||
const LLType* typeinfotype = DtoType(Type::typeinfo->type);
|
if (llfnty->getParamType(j) != NULL) {
|
||||||
const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
|
if (llargs[j]->getType() != llfnty->getParamType(j)) {
|
||||||
|
Logger::println("llvmRunTimeHack==true - force casting argument");
|
||||||
llvm::GlobalVariable* typeinfomem =
|
Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
|
||||||
new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module);
|
llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
|
||||||
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
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2720,11 +2728,13 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
||||||
const LLType* llt = DtoType(type);
|
const LLType* llt = DtoType(type);
|
||||||
|
|
||||||
LLValue* mem = 0;
|
LLValue* mem = 0;
|
||||||
|
bool isinplace = true;
|
||||||
|
|
||||||
// temporary struct literal
|
// temporary struct literal
|
||||||
if (!p->topexp() || p->topexp()->e2 != this)
|
if (!p->topexp() || p->topexp()->e2 != this)
|
||||||
{
|
{
|
||||||
sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
|
sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
|
||||||
|
isinplace = false;
|
||||||
}
|
}
|
||||||
// already has memory
|
// already has memory
|
||||||
else
|
else
|
||||||
|
@ -2777,7 +2787,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DImValue(type, sptr, true);
|
return new DImValue(type, sptr, isinplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -748,6 +748,7 @@ tangotests
|
||||||
tangotests/a.d
|
tangotests/a.d
|
||||||
tangotests/aa1.d
|
tangotests/aa1.d
|
||||||
tangotests/aa2.d
|
tangotests/aa2.d
|
||||||
|
tangotests/align1.d
|
||||||
tangotests/b.d
|
tangotests/b.d
|
||||||
tangotests/c.d
|
tangotests/c.d
|
||||||
tangotests/classes1.d
|
tangotests/classes1.d
|
||||||
|
@ -757,6 +758,7 @@ tangotests/f.d
|
||||||
tangotests/files1.d
|
tangotests/files1.d
|
||||||
tangotests/h.d
|
tangotests/h.d
|
||||||
tangotests/i.d
|
tangotests/i.d
|
||||||
|
tangotests/ina1.d
|
||||||
tangotests/j.d
|
tangotests/j.d
|
||||||
tangotests/k.d
|
tangotests/k.d
|
||||||
tangotests/l.d
|
tangotests/l.d
|
||||||
|
@ -777,6 +779,7 @@ tangotests/templ1.d
|
||||||
tangotests/vararg1.d
|
tangotests/vararg1.d
|
||||||
tangotests/vararg2.d
|
tangotests/vararg2.d
|
||||||
tangotests/vararg3.d
|
tangotests/vararg3.d
|
||||||
|
tangotests/vararg4.d
|
||||||
test
|
test
|
||||||
test/a.d
|
test/a.d
|
||||||
test/aa1.d
|
test/aa1.d
|
||||||
|
|
|
@ -35,6 +35,16 @@ class Obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TLA
|
||||||
|
{
|
||||||
|
char[3] acronym;
|
||||||
|
|
||||||
|
char[] toString()
|
||||||
|
{
|
||||||
|
return acronym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
User user = User("Bob Doe", "bd", 47);
|
User user = User("Bob Doe", "bd", 47);
|
||||||
|
@ -81,6 +91,24 @@ void main()
|
||||||
print("Mixed:\n");
|
print("Mixed:\n");
|
||||||
print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n');
|
print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n');
|
||||||
print(42, ' ', cast(byte)12, ' ', user, ' ', cast(short)1445, " foo\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)
|
private void* get_va_arg(TypeInfo ti, ref void* vp)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue