mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
clang-tidy: Add readability-else-after-return
This commit is contained in:
parent
9df487edff
commit
05d45350aa
22 changed files with 500 additions and 479 deletions
|
@ -1 +1 @@
|
||||||
Checks: -*,modernize-*,-modernize-redundant-void-arg,google-readability-braces-around-statements,google-explicit-constructor,google-readability-casting,misc-assert-side-effect,misc-assign-operator-signature,misc-inefficient-algorithm,misc-move-constructor-init,misc-non-copyable-objects,misc-sizeof-container,misc-undelegated-constructor,misc-unused-alias-decls,readability-container-size-empty,readability-redundant-string-cstr
|
Checks: -*,modernize-*,-modernize-redundant-void-arg,google-readability-braces-around-statements,google-explicit-constructor,google-readability-casting,misc-assert-side-effect,misc-assign-operator-signature,misc-inefficient-algorithm,misc-move-constructor-init,misc-non-copyable-objects,misc-sizeof-container,misc-undelegated-constructor,misc-unused-alias-decls,readability-container-size-empty,readability-else-after-return,readability-redundant-string-cstr
|
||||||
|
|
|
@ -98,7 +98,8 @@ bool Win64TargetABI::returnInArg(TypeFunction *tf) {
|
||||||
// (incl. 2x32-bit cfloat) are returned in a register (RAX, or
|
// (incl. 2x32-bit cfloat) are returned in a register (RAX, or
|
||||||
// XMM0 for single float/ifloat/double/idouble)
|
// XMM0 for single float/ifloat/double/idouble)
|
||||||
// * all other types are returned via struct-return (sret)
|
// * all other types are returned via struct-return (sret)
|
||||||
return (rt->ty == Tstruct && !((TypeStruct *)rt)->sym->isPOD()) ||
|
return (rt->ty == Tstruct &&
|
||||||
|
!(static_cast<TypeStruct *>(rt))->sym->isPOD()) ||
|
||||||
isPassedWithByvalSemantics(rt);
|
isPassedWithByvalSemantics(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,17 +105,15 @@ public:
|
||||||
}
|
}
|
||||||
// other ABI's follow C, which is cdouble and creal returned on the stack
|
// other ABI's follow C, which is cdouble and creal returned on the stack
|
||||||
// as well as structs (except for some OSX cases).
|
// as well as structs (except for some OSX cases).
|
||||||
else {
|
|
||||||
if (isMagicCLong(rt)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rt->ty == Tstruct) {
|
if (isMagicCLong(rt)) {
|
||||||
return !isOSX || returnOSXStructInArg((TypeStruct *)rt);
|
return false;
|
||||||
}
|
|
||||||
return (rt->ty == Tsarray || rt->ty == Tcomplex64 ||
|
|
||||||
rt->ty == Tcomplex80);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rt->ty == Tstruct) {
|
||||||
|
return !isOSX || returnOSXStructInArg((TypeStruct *)rt);
|
||||||
|
}
|
||||||
|
return (rt->ty == Tsarray || rt->ty == Tcomplex64 || rt->ty == Tcomplex80);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool passByVal(Type *t) override {
|
bool passByVal(Type *t) override {
|
||||||
|
|
|
@ -1021,13 +1021,16 @@ LLValue *DtoArrayLen(DValue *v) {
|
||||||
if (t->ty == Tarray) {
|
if (t->ty == Tarray) {
|
||||||
if (DSliceValue *s = v->isSlice()) {
|
if (DSliceValue *s = v->isSlice()) {
|
||||||
return s->len;
|
return s->len;
|
||||||
} else if (v->isNull()) {
|
}
|
||||||
|
if (v->isNull()) {
|
||||||
return DtoConstSize_t(0);
|
return DtoConstSize_t(0);
|
||||||
} else if (v->isLVal()) {
|
}
|
||||||
|
if (v->isLVal()) {
|
||||||
return DtoLoad(DtoGEPi(v->getLVal(), 0, 0), ".len");
|
return DtoLoad(DtoGEPi(v->getLVal(), 0, 0), ".len");
|
||||||
}
|
}
|
||||||
return gIR->ir->CreateExtractValue(v->getRVal(), 0, ".len");
|
return gIR->ir->CreateExtractValue(v->getRVal(), 0, ".len");
|
||||||
} else if (t->ty == Tsarray) {
|
}
|
||||||
|
if (t->ty == Tsarray) {
|
||||||
assert(!v->isSlice());
|
assert(!v->isSlice());
|
||||||
assert(!v->isNull());
|
assert(!v->isNull());
|
||||||
assert(v->type->toBasetype()->ty == Tsarray);
|
assert(v->type->toBasetype()->ty == Tsarray);
|
||||||
|
|
|
@ -531,13 +531,14 @@ typedef struct {
|
||||||
unsigned nOperands() {
|
unsigned nOperands() {
|
||||||
if (!operands[0]) {
|
if (!operands[0]) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!operands[1]) {
|
|
||||||
return 1;
|
|
||||||
} else if (!operands[2]) {
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
|
if (!operands[1]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!operands[2]) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
} AsmOpInfo;
|
} AsmOpInfo;
|
||||||
|
|
||||||
|
@ -2085,9 +2086,8 @@ struct AsmProcessor {
|
||||||
Token *peekToken() {
|
Token *peekToken() {
|
||||||
if (token->next) {
|
if (token->next) {
|
||||||
return token->next;
|
return token->next;
|
||||||
} else {
|
|
||||||
return &eof_tok;
|
|
||||||
}
|
}
|
||||||
|
return &eof_tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void expectEnd() {
|
void expectEnd() {
|
||||||
|
@ -2162,7 +2162,8 @@ struct AsmProcessor {
|
||||||
l = strcmp(opcode, opData[k].inMnemonic);
|
l = strcmp(opcode, opData[k].inMnemonic);
|
||||||
if (!l) {
|
if (!l) {
|
||||||
return opData[k].asmOp;
|
return opData[k].asmOp;
|
||||||
} else if (l < 0) {
|
}
|
||||||
|
if (l < 0) {
|
||||||
j = k;
|
j = k;
|
||||||
} else {
|
} else {
|
||||||
i = k + 1;
|
i = k + 1;
|
||||||
|
@ -3282,10 +3283,9 @@ struct AsmProcessor {
|
||||||
}
|
}
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
return e->ctfeInterpret();
|
return e->ctfeInterpret();
|
||||||
} else {
|
|
||||||
stmt->error("expected integer operand(s) for '%s'", Token::tochars[op]);
|
|
||||||
return newIntExp(0);
|
|
||||||
}
|
}
|
||||||
|
stmt->error("expected integer operand(s) for '%s'", Token::tochars[op]);
|
||||||
|
return newIntExp(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseOperand() {
|
void parseOperand() {
|
||||||
|
@ -3717,7 +3717,8 @@ struct AsmProcessor {
|
||||||
|
|
||||||
if (ident == Id::__LOCAL_SIZE) {
|
if (ident == Id::__LOCAL_SIZE) {
|
||||||
return new IdentifierExp(stmt->loc, ident);
|
return new IdentifierExp(stmt->loc, ident);
|
||||||
} else if (ident == Id::dollar) {
|
}
|
||||||
|
if (ident == Id::dollar) {
|
||||||
do_dollar:
|
do_dollar:
|
||||||
return new IdentifierExp(stmt->loc, ident);
|
return new IdentifierExp(stmt->loc, ident);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3772,7 +3773,8 @@ struct AsmProcessor {
|
||||||
}
|
}
|
||||||
invalidExpression();
|
invalidExpression();
|
||||||
return Handled;
|
return Handled;
|
||||||
} else if (token->value == TOKcolon) {
|
}
|
||||||
|
if (token->value == TOKcolon) {
|
||||||
nextToken();
|
nextToken();
|
||||||
if (operand->segmentPrefix != Reg_Invalid) {
|
if (operand->segmentPrefix != Reg_Invalid) {
|
||||||
stmt->error("too many segment prefixes");
|
stmt->error("too many segment prefixes");
|
||||||
|
@ -3782,9 +3784,8 @@ struct AsmProcessor {
|
||||||
stmt->error("'%s' is not a segment register", ident->string);
|
stmt->error("'%s' is not a segment register", ident->string);
|
||||||
}
|
}
|
||||||
return parseAsmExp();
|
return parseAsmExp();
|
||||||
} else {
|
|
||||||
return newRegExp(static_cast<Reg>(i));
|
|
||||||
}
|
}
|
||||||
|
return newRegExp(static_cast<Reg>(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct OptionValue : cl::OptionValueBase<DataType, false> {
|
struct OptionValue : cl::OptionValueBase<DataType, false> {
|
||||||
OptionValue() {}
|
OptionValue(){};
|
||||||
};
|
};
|
||||||
const OptionValue EmptyOptionValue;
|
const OptionValue EmptyOptionValue;
|
||||||
|
|
||||||
|
|
|
@ -209,14 +209,14 @@ DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {
|
||||||
return new DImValue(_to, rval);
|
return new DImValue(_to, rval);
|
||||||
}
|
}
|
||||||
// class -> bool
|
// class -> bool
|
||||||
else if (to->ty == Tbool) {
|
if (to->ty == Tbool) {
|
||||||
IF_LOG Logger::println("to bool");
|
IF_LOG Logger::println("to bool");
|
||||||
LLValue *llval = val->getRVal();
|
LLValue *llval = val->getRVal();
|
||||||
LLValue *zero = LLConstant::getNullValue(llval->getType());
|
LLValue *zero = LLConstant::getNullValue(llval->getType());
|
||||||
return new DImValue(_to, gIR->ir->CreateICmpNE(llval, zero));
|
return new DImValue(_to, gIR->ir->CreateICmpNE(llval, zero));
|
||||||
}
|
}
|
||||||
// class -> integer
|
// class -> integer
|
||||||
else if (to->isintegral()) {
|
if (to->isintegral()) {
|
||||||
IF_LOG Logger::println("to %s", to->toChars());
|
IF_LOG Logger::println("to %s", to->toChars());
|
||||||
|
|
||||||
// get class ptr
|
// get class ptr
|
||||||
|
@ -228,7 +228,7 @@ DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {
|
||||||
return DtoCastInt(loc, &im, _to);
|
return DtoCastInt(loc, &im, _to);
|
||||||
}
|
}
|
||||||
// class -> typeof(null)
|
// class -> typeof(null)
|
||||||
else if (to->ty == Tnull) {
|
if (to->ty == Tnull) {
|
||||||
IF_LOG Logger::println("to %s", to->toChars());
|
IF_LOG Logger::println("to %s", to->toChars());
|
||||||
return new DImValue(_to, LLConstant::getNullValue(DtoType(_to)));
|
return new DImValue(_to, LLConstant::getNullValue(DtoType(_to)));
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {
|
||||||
return DtoDynamicCastInterface(loc, val, _to);
|
return DtoDynamicCastInterface(loc, val, _to);
|
||||||
}
|
}
|
||||||
// class -> interface - static cast
|
// class -> interface - static cast
|
||||||
else if (it->isBaseOf(fc->sym, nullptr)) {
|
if (it->isBaseOf(fc->sym, nullptr)) {
|
||||||
Logger::println("static down cast");
|
Logger::println("static down cast");
|
||||||
|
|
||||||
// get the from class
|
// get the from class
|
||||||
|
@ -295,32 +295,29 @@ DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {
|
||||||
return new DImValue(_to, v);
|
return new DImValue(_to, v);
|
||||||
}
|
}
|
||||||
// class -> interface
|
// class -> interface
|
||||||
else {
|
|
||||||
Logger::println("from object");
|
Logger::println("from object");
|
||||||
return DtoDynamicCastObject(loc, val, _to);
|
return DtoDynamicCastObject(loc, val, _to);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// x -> class
|
// x -> class
|
||||||
else {
|
|
||||||
Logger::println("to class");
|
Logger::println("to class");
|
||||||
// interface -> class
|
// interface -> class
|
||||||
if (fc->sym->isInterfaceDeclaration()) {
|
if (fc->sym->isInterfaceDeclaration()) {
|
||||||
Logger::println("interface cast");
|
Logger::println("interface cast");
|
||||||
return DtoDynamicCastInterface(loc, val, _to);
|
return DtoDynamicCastInterface(loc, val, _to);
|
||||||
}
|
|
||||||
// class -> class - static down cast
|
|
||||||
else if (tc->sym->isBaseOf(fc->sym, nullptr)) {
|
|
||||||
Logger::println("static down cast");
|
|
||||||
LLType *tolltype = DtoType(_to);
|
|
||||||
LLValue *rval = DtoBitCast(val->getRVal(), tolltype);
|
|
||||||
return new DImValue(_to, rval);
|
|
||||||
}
|
|
||||||
// class -> class - dynamic up cast
|
|
||||||
else {
|
|
||||||
Logger::println("dynamic up cast");
|
|
||||||
return DtoDynamicCastObject(loc, val, _to);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// class -> class - static down cast
|
||||||
|
if (tc->sym->isBaseOf(fc->sym, nullptr)) {
|
||||||
|
Logger::println("static down cast");
|
||||||
|
LLType *tolltype = DtoType(_to);
|
||||||
|
LLValue *rval = DtoBitCast(val->getRVal(), tolltype);
|
||||||
|
return new DImValue(_to, rval);
|
||||||
|
}
|
||||||
|
// class -> class - dynamic up cast
|
||||||
|
|
||||||
|
Logger::println("dynamic up cast");
|
||||||
|
return DtoDynamicCastObject(loc, val, _to);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -423,9 +423,8 @@ LLValue *DtoComplexEquals(Loc &loc, TOK op, DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
if (op == TOKequal) {
|
if (op == TOKequal) {
|
||||||
return gIR->ir->CreateAnd(b1, b2);
|
return gIR->ir->CreateAnd(b1, b2);
|
||||||
} else {
|
|
||||||
return gIR->ir->CreateOr(b1, b2);
|
|
||||||
}
|
}
|
||||||
|
return gIR->ir->CreateOr(b1, b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -452,7 +451,8 @@ DValue *DtoCastComplex(Loc &loc, DValue *val, Type *_to) {
|
||||||
|
|
||||||
LLValue *pair = DtoAggrPair(DtoType(_to), re, im);
|
LLValue *pair = DtoAggrPair(DtoType(_to), re, im);
|
||||||
return new DImValue(_to, pair);
|
return new DImValue(_to, pair);
|
||||||
} else if (to->isimaginary()) {
|
}
|
||||||
|
if (to->isimaginary()) {
|
||||||
// FIXME: this loads both values, even when we only need one
|
// FIXME: this loads both values, even when we only need one
|
||||||
LLValue *v = val->getRVal();
|
LLValue *v = val->getRVal();
|
||||||
LLValue *impart = gIR->ir->CreateExtractValue(v, 1, ".im_part");
|
LLValue *impart = gIR->ir->CreateExtractValue(v, 1, ".im_part");
|
||||||
|
@ -472,10 +472,12 @@ DValue *DtoCastComplex(Loc &loc, DValue *val, Type *_to) {
|
||||||
}
|
}
|
||||||
auto im = new DImValue(extractty, impart);
|
auto im = new DImValue(extractty, impart);
|
||||||
return DtoCastFloat(loc, im, to);
|
return DtoCastFloat(loc, im, to);
|
||||||
} else if (to->ty == Tbool) {
|
}
|
||||||
|
if (to->ty == Tbool) {
|
||||||
return new DImValue(
|
return new DImValue(
|
||||||
_to, DtoComplexEquals(loc, TOKnotequal, val, DtoNullValue(vty)));
|
_to, DtoComplexEquals(loc, TOKnotequal, val, DtoNullValue(vty)));
|
||||||
} else if (to->isfloating() || to->isintegral()) {
|
}
|
||||||
|
if (to->isfloating() || to->isintegral()) {
|
||||||
// FIXME: this loads both values, even when we only need one
|
// FIXME: this loads both values, even when we only need one
|
||||||
LLValue *v = val->getRVal();
|
LLValue *v = val->getRVal();
|
||||||
LLValue *repart = gIR->ir->CreateExtractValue(v, 0, ".re_part");
|
LLValue *repart = gIR->ir->CreateExtractValue(v, 0, ".re_part");
|
||||||
|
@ -495,9 +497,7 @@ DValue *DtoCastComplex(Loc &loc, DValue *val, Type *_to) {
|
||||||
}
|
}
|
||||||
auto re = new DImValue(extractty, repart);
|
auto re = new DImValue(extractty, repart);
|
||||||
return DtoCastFloat(loc, re, to);
|
return DtoCastFloat(loc, re, to);
|
||||||
} else {
|
|
||||||
error(loc, "Don't know how to cast %s to %s", vty->toChars(),
|
|
||||||
to->toChars());
|
|
||||||
fatal();
|
|
||||||
}
|
}
|
||||||
|
error(loc, "Don't know how to cast %s to %s", vty->toChars(), to->toChars());
|
||||||
|
fatal();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ Module *ldc::DIBuilder::getDefinedModule(Dsymbol *s) {
|
||||||
return IR->dmodule;
|
return IR->dmodule;
|
||||||
}
|
}
|
||||||
// array operations as well
|
// array operations as well
|
||||||
else if (FuncDeclaration *fd = s->isFuncDeclaration()) {
|
if (FuncDeclaration *fd = s->isFuncDeclaration()) {
|
||||||
if (fd->isArrayOp && (willInline() || !isDruntimeArrayOp(fd))) {
|
if (fd->isArrayOp && (willInline() || !isDruntimeArrayOp(fd))) {
|
||||||
return IR->dmodule;
|
return IR->dmodule;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,8 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type, bool derefclass) {
|
||||||
|
|
||||||
if (t->ty == Tvoid || t->ty == Tnull) {
|
if (t->ty == Tvoid || t->ty == Tnull) {
|
||||||
return DBuilder.createUnspecifiedType(t->toChars());
|
return DBuilder.createUnspecifiedType(t->toChars());
|
||||||
} else if (t->isintegral() || t->isfloating()) {
|
}
|
||||||
|
if (t->isintegral() || t->isfloating()) {
|
||||||
if (t->ty == Tvector) {
|
if (t->ty == Tvector) {
|
||||||
return CreateVectorType(type);
|
return CreateVectorType(type);
|
||||||
}
|
}
|
||||||
|
@ -556,19 +557,26 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type, bool derefclass) {
|
||||||
return CreateEnumType(type);
|
return CreateEnumType(type);
|
||||||
}
|
}
|
||||||
return CreateBasicType(type);
|
return CreateBasicType(type);
|
||||||
} else if (t->ty == Tpointer) {
|
}
|
||||||
|
if (t->ty == Tpointer) {
|
||||||
return CreatePointerType(type);
|
return CreatePointerType(type);
|
||||||
} else if (t->ty == Tarray) {
|
}
|
||||||
|
if (t->ty == Tarray) {
|
||||||
return CreateArrayType(type);
|
return CreateArrayType(type);
|
||||||
} else if (t->ty == Tsarray) {
|
}
|
||||||
|
if (t->ty == Tsarray) {
|
||||||
return CreateSArrayType(type);
|
return CreateSArrayType(type);
|
||||||
} else if (t->ty == Taarray) {
|
}
|
||||||
|
if (t->ty == Taarray) {
|
||||||
return CreateAArrayType(type);
|
return CreateAArrayType(type);
|
||||||
} else if (t->ty == Tstruct || t->ty == Tclass) {
|
}
|
||||||
|
if (t->ty == Tstruct || t->ty == Tclass) {
|
||||||
return CreateCompositeType(type);
|
return CreateCompositeType(type);
|
||||||
} else if (t->ty == Tfunction) {
|
}
|
||||||
|
if (t->ty == Tfunction) {
|
||||||
return CreateFunctionType(type);
|
return CreateFunctionType(type);
|
||||||
} else if (t->ty == Tdelegate) {
|
}
|
||||||
|
if (t->ty == Tdelegate) {
|
||||||
return CreateDelegateType(type);
|
return CreateDelegateType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,295 +625,290 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
return llvm::DISubprogram();
|
return llvm::DISubprogram();
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Logger::println("D to dwarf subprogram");
|
|
||||||
LOG_SCOPE;
|
|
||||||
|
|
||||||
ldc::DICompileUnit CU(GetCU());
|
|
||||||
assert(
|
|
||||||
CU &&
|
|
||||||
"Compilation unit missing or corrupted in DIBuilder::EmitSubProgram");
|
|
||||||
|
|
||||||
ldc::DIFile file(CreateFile(fd->loc));
|
|
||||||
|
|
||||||
// Create subroutine type
|
|
||||||
ldc::DISubroutineType DIFnType =
|
|
||||||
CreateFunctionType(static_cast<TypeFunction *>(fd->type));
|
|
||||||
|
|
||||||
// FIXME: duplicates ?
|
|
||||||
return DBuilder.createFunction(CU, // context
|
|
||||||
fd->toPrettyChars(), // name
|
|
||||||
mangleExact(fd), // linkage name
|
|
||||||
file, // file
|
|
||||||
fd->loc.linnum, // line no
|
|
||||||
DIFnType, // type
|
|
||||||
fd->protection ==
|
|
||||||
PROTprivate, // is local to unit
|
|
||||||
true, // isdefinition
|
|
||||||
fd->loc.linnum, // FIXME: scope line
|
|
||||||
DIFlags::FlagPrototyped, // Flags
|
|
||||||
isOptimizationEnabled(), // isOptimized
|
|
||||||
getIrFunc(fd)->func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function * Fn,
|
Logger::println("D to dwarf subprogram");
|
||||||
llvm::StringRef prettyname) {
|
LOG_SCOPE;
|
||||||
if (!global.params.symdebug) {
|
|
||||||
|
ldc::DICompileUnit CU(GetCU());
|
||||||
|
assert(CU &&
|
||||||
|
"Compilation unit missing or corrupted in DIBuilder::EmitSubProgram");
|
||||||
|
|
||||||
|
ldc::DIFile file(CreateFile(fd->loc));
|
||||||
|
|
||||||
|
// Create subroutine type
|
||||||
|
ldc::DISubroutineType DIFnType =
|
||||||
|
CreateFunctionType(static_cast<TypeFunction *>(fd->type));
|
||||||
|
|
||||||
|
// FIXME: duplicates ?
|
||||||
|
return DBuilder.createFunction(CU, // context
|
||||||
|
fd->toPrettyChars(), // name
|
||||||
|
mangleExact(fd), // linkage name
|
||||||
|
file, // file
|
||||||
|
fd->loc.linnum, // line no
|
||||||
|
DIFnType, // type
|
||||||
|
fd->protection ==
|
||||||
|
PROTprivate, // is local to unit
|
||||||
|
true, // isdefinition
|
||||||
|
fd->loc.linnum, // FIXME: scope line
|
||||||
|
DIFlags::FlagPrototyped, // Flags
|
||||||
|
isOptimizationEnabled(), // isOptimized
|
||||||
|
getIrFunc(fd)->func);
|
||||||
|
}
|
||||||
|
|
||||||
|
ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
||||||
|
llvm::StringRef prettyname) {
|
||||||
|
if (!global.params.symdebug) {
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
return llvm::DISubprogram();
|
return llvm::DISubprogram();
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
Logger::println("D to dwarf subprogram");
|
Logger::println("D to dwarf subprogram");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
ldc::DICompileUnit CU(GetCU());
|
ldc::DICompileUnit CU(GetCU());
|
||||||
assert(
|
assert(CU &&
|
||||||
CU &&
|
"Compilation unit missing or corrupted in DIBuilder::EmitSubProgram");
|
||||||
"Compilation unit missing or corrupted in DIBuilder::EmitSubProgram");
|
|
||||||
|
|
||||||
Loc loc(IR->dmodule->srcfile->toChars(), 0, 0);
|
Loc loc(IR->dmodule->srcfile->toChars(), 0, 0);
|
||||||
ldc::DIFile file(CreateFile(loc));
|
ldc::DIFile file(CreateFile(loc));
|
||||||
|
|
||||||
// Create "dummy" subroutine type for the return type
|
// Create "dummy" subroutine type for the return type
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
llvm::SmallVector<llvm::Metadata *, 1> Elts;
|
llvm::SmallVector<llvm::Metadata *, 1> Elts;
|
||||||
#else
|
#else
|
||||||
llvm::SmallVector<llvm::Value *, 1> Elts;
|
llvm::SmallVector<llvm::Value *, 1> Elts;
|
||||||
#endif
|
#endif
|
||||||
Elts.push_back(CreateTypeDescription(Type::tvoid, true));
|
Elts.push_back(CreateTypeDescription(Type::tvoid, true));
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
|
llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
|
||||||
#elif LDC_LLVM_VER >= 306
|
#elif LDC_LLVM_VER >= 306
|
||||||
llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
|
llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
|
||||||
#else
|
#else
|
||||||
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
|
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
|
||||||
#endif
|
#endif
|
||||||
#if LDC_LLVM_VER >= 308
|
#if LDC_LLVM_VER >= 308
|
||||||
ldc::DISubroutineType DIFnType =
|
ldc::DISubroutineType DIFnType = DBuilder.createSubroutineType(EltTypeArray);
|
||||||
DBuilder.createSubroutineType(EltTypeArray);
|
|
||||||
#else
|
#else
|
||||||
ldc::DISubroutineType DIFnType =
|
ldc::DISubroutineType DIFnType =
|
||||||
DBuilder.createSubroutineType(file, EltTypeArray);
|
DBuilder.createSubroutineType(file, EltTypeArray);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: duplicates ?
|
// FIXME: duplicates ?
|
||||||
return DBuilder.createFunction(CU, // context
|
return DBuilder.createFunction(CU, // context
|
||||||
prettyname, // name
|
prettyname, // name
|
||||||
Fn->getName(), // linkage name
|
Fn->getName(), // linkage name
|
||||||
file, // file
|
file, // file
|
||||||
0, // line no
|
0, // line no
|
||||||
DIFnType, // return type. TODO: fill it up
|
DIFnType, // return type. TODO: fill it up
|
||||||
true, // is local to unit
|
true, // is local to unit
|
||||||
true, // isdefinition
|
true, // isdefinition
|
||||||
0, // FIXME: scope line
|
0, // FIXME: scope line
|
||||||
DIFlags::FlagPrototyped |
|
DIFlags::FlagPrototyped |
|
||||||
DIFlags::FlagArtificial,
|
DIFlags::FlagArtificial,
|
||||||
isOptimizationEnabled(), // isOptimized
|
isOptimizationEnabled(), // isOptimized
|
||||||
Fn);
|
Fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitFuncStart(FuncDeclaration * fd) {
|
void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::println("D to dwarf funcstart");
|
Logger::println("D to dwarf funcstart");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
|
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
|
||||||
EmitStopPoint(fd->loc);
|
EmitStopPoint(fd->loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration * fd) {
|
void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::println("D to dwarf funcend");
|
Logger::println("D to dwarf funcend");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
|
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
|
||||||
EmitStopPoint(fd->endloc);
|
EmitStopPoint(fd->endloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitBlockStart(Loc & loc) {
|
void ldc::DIBuilder::EmitBlockStart(Loc &loc) {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::println("D to dwarf block start");
|
Logger::println("D to dwarf block start");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
ldc::DILexicalBlock block =
|
ldc::DILexicalBlock block =
|
||||||
DBuilder.createLexicalBlock(GetCurrentScope(), // scope
|
DBuilder.createLexicalBlock(GetCurrentScope(), // scope
|
||||||
CreateFile(loc), // file
|
CreateFile(loc), // file
|
||||||
loc.linnum, // line
|
loc.linnum, // line
|
||||||
loc.linnum ? loc.charnum : 0 // column
|
loc.linnum ? loc.charnum : 0 // column
|
||||||
#if LDC_LLVM_VER == 305
|
#if LDC_LLVM_VER == 305
|
||||||
,
|
,
|
||||||
0 // DWARF path discriminator value
|
0 // DWARF path discriminator value
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
IR->func()->diLexicalBlocks.push(block);
|
IR->func()->diLexicalBlocks.push(block);
|
||||||
EmitStopPoint(loc);
|
EmitStopPoint(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitBlockEnd() {
|
void ldc::DIBuilder::EmitBlockEnd() {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::println("D to dwarf block end");
|
Logger::println("D to dwarf block end");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
IrFunction *fn = IR->func();
|
IrFunction *fn = IR->func();
|
||||||
assert(!fn->diLexicalBlocks.empty());
|
assert(!fn->diLexicalBlocks.empty());
|
||||||
fn->diLexicalBlocks.pop();
|
fn->diLexicalBlocks.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitStopPoint(Loc & loc) {
|
void ldc::DIBuilder::EmitStopPoint(Loc &loc) {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we already have a location set and the current loc is invalid
|
// If we already have a location set and the current loc is invalid
|
||||||
// (line 0), then we can just ignore it (see GitHub issue #998 for why we
|
// (line 0), then we can just ignore it (see GitHub issue #998 for why we
|
||||||
// cannot do this in all cases).
|
// cannot do this in all cases).
|
||||||
if (!loc.linnum &&
|
if (!loc.linnum &&
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
IR->ir->getCurrentDebugLocation()
|
IR->ir->getCurrentDebugLocation()
|
||||||
#else
|
#else
|
||||||
!IR->ir->getCurrentDebugLocation().isUnknown()
|
!IR->ir->getCurrentDebugLocation().isUnknown()
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned charnum = (loc.linnum ? loc.charnum : 0);
|
unsigned charnum = (loc.linnum ? loc.charnum : 0);
|
||||||
Logger::println("D to dwarf stoppoint at line %u, column %u", loc.linnum,
|
Logger::println("D to dwarf stoppoint at line %u, column %u", loc.linnum,
|
||||||
charnum);
|
charnum);
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
IR->ir->SetCurrentDebugLocation(
|
IR->ir->SetCurrentDebugLocation(
|
||||||
llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()));
|
llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitValue(llvm::Value * val, VarDeclaration * vd) {
|
void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) {
|
||||||
auto sub = IR->func()->variableMap.find(vd);
|
auto sub = IR->func()->variableMap.find(vd);
|
||||||
if (sub == IR->func()->variableMap.end()) {
|
if (sub == IR->func()->variableMap.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ldc::DILocalVariable debugVariable = sub->second;
|
ldc::DILocalVariable debugVariable = sub->second;
|
||||||
if (!global.params.symdebug || !debugVariable) {
|
if (!global.params.symdebug || !debugVariable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Instruction *instr =
|
llvm::Instruction *instr =
|
||||||
DBuilder.insertDbgValueIntrinsic(val, 0, debugVariable,
|
DBuilder.insertDbgValueIntrinsic(val, 0, debugVariable,
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
DBuilder.createExpression(),
|
DBuilder.createExpression(),
|
||||||
#endif
|
#endif
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
IR->ir->getCurrentDebugLocation(),
|
IR->ir->getCurrentDebugLocation(),
|
||||||
#endif
|
#endif
|
||||||
IR->scopebb());
|
IR->scopebb());
|
||||||
instr->setDebugLoc(IR->ir->getCurrentDebugLocation());
|
instr->setDebugLoc(IR->ir->getCurrentDebugLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitLocalVariable(
|
void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
llvm::Value * ll, VarDeclaration * vd, Type * type, bool isThisPtr,
|
Type *type, bool isThisPtr,
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
llvm::ArrayRef<int64_t> addr
|
llvm::ArrayRef<int64_t> addr
|
||||||
#else
|
#else
|
||||||
llvm::ArrayRef<llvm::Value *> addr
|
llvm::ArrayRef<llvm::Value *> addr
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::println("D to dwarf local variable");
|
Logger::println("D to dwarf local variable");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
auto &variableMap = IR->func()->variableMap;
|
auto &variableMap = IR->func()->variableMap;
|
||||||
auto sub = variableMap.find(vd);
|
auto sub = variableMap.find(vd);
|
||||||
if (sub != variableMap.end()) {
|
if (sub != variableMap.end()) {
|
||||||
return; // ensure that the debug variable is created only once
|
return; // ensure that the debug variable is created only once
|
||||||
}
|
}
|
||||||
|
|
||||||
// get type description
|
// get type description
|
||||||
ldc::DIType TD = CreateTypeDescription(type ? type : vd->type, true);
|
ldc::DIType TD = CreateTypeDescription(type ? type : vd->type, true);
|
||||||
if (static_cast<llvm::MDNode *>(TD) == nullptr) {
|
if (static_cast<llvm::MDNode *>(TD) == nullptr) {
|
||||||
return; // unsupported
|
return; // unsupported
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vd->storage_class & (STCref | STCout)) {
|
if (vd->storage_class & (STCref | STCout)) {
|
||||||
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type,
|
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD);
|
||||||
TD);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// get variable description
|
// get variable description
|
||||||
assert(!vd->isDataseg() && "static variable");
|
assert(!vd->isDataseg() && "static variable");
|
||||||
|
|
||||||
#if LDC_LLVM_VER < 308
|
#if LDC_LLVM_VER < 308
|
||||||
unsigned tag;
|
unsigned tag;
|
||||||
if (vd->isParameter()) {
|
if (vd->isParameter()) {
|
||||||
tag = llvm::dwarf::DW_TAG_arg_variable;
|
tag = llvm::dwarf::DW_TAG_arg_variable;
|
||||||
} else {
|
} else {
|
||||||
tag = llvm::dwarf::DW_TAG_auto_variable;
|
tag = llvm::dwarf::DW_TAG_auto_variable;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ldc::DILocalVariable debugVariable;
|
ldc::DILocalVariable debugVariable;
|
||||||
unsigned Flags = 0;
|
unsigned Flags = 0;
|
||||||
if (isThisPtr) {
|
if (isThisPtr) {
|
||||||
Flags |= DIFlags::FlagArtificial | DIFlags::FlagObjectPointer;
|
Flags |= DIFlags::FlagArtificial | DIFlags::FlagObjectPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDC_LLVM_VER < 306
|
#if LDC_LLVM_VER < 306
|
||||||
if (addr.empty()) {
|
if (addr.empty()) {
|
||||||
#endif
|
#endif
|
||||||
#if LDC_LLVM_VER >= 308
|
#if LDC_LLVM_VER >= 308
|
||||||
if (vd->isParameter()) {
|
if (vd->isParameter()) {
|
||||||
FuncDeclaration *fd = vd->parent->isFuncDeclaration();
|
FuncDeclaration *fd = vd->parent->isFuncDeclaration();
|
||||||
assert(fd);
|
assert(fd);
|
||||||
int argNo;
|
int argNo;
|
||||||
if (fd->vthis == vd)
|
if (fd->vthis == vd)
|
||||||
argNo = 0;
|
argNo = 0;
|
||||||
else {
|
else {
|
||||||
assert(fd->parameters);
|
assert(fd->parameters);
|
||||||
for (argNo = 0; argNo < fd->parameters->dim; argNo++)
|
for (argNo = 0; argNo < fd->parameters->dim; argNo++)
|
||||||
if ((*fd->parameters)[argNo] == vd)
|
if ((*fd->parameters)[argNo] == vd)
|
||||||
break;
|
break;
|
||||||
assert(argNo < fd->parameters->dim);
|
assert(argNo < fd->parameters->dim);
|
||||||
if (fd->vthis)
|
if (fd->vthis)
|
||||||
argNo++;
|
argNo++;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugVariable =
|
debugVariable =
|
||||||
DBuilder.createParameterVariable(GetCurrentScope(), // scope
|
DBuilder.createParameterVariable(GetCurrentScope(), // scope
|
||||||
vd->toChars(), // name
|
vd->toChars(), // name
|
||||||
argNo + 1,
|
argNo + 1,
|
||||||
CreateFile(vd->loc), // file
|
CreateFile(vd->loc), // file
|
||||||
vd->loc.linnum, // line num
|
vd->loc.linnum, // line num
|
||||||
TD, // type
|
TD, // type
|
||||||
true, // preserve
|
true, // preserve
|
||||||
Flags // flags
|
Flags // flags
|
||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
debugVariable =
|
debugVariable = DBuilder.createAutoVariable(GetCurrentScope(), // scope
|
||||||
DBuilder.createAutoVariable(GetCurrentScope(), // scope
|
vd->toChars(), // name
|
||||||
vd->toChars(), // name
|
CreateFile(vd->loc), // file
|
||||||
CreateFile(vd->loc), // file
|
vd->loc.linnum, // line num
|
||||||
vd->loc.linnum, // line num
|
TD, // type
|
||||||
TD, // type
|
true, // preserve
|
||||||
true, // preserve
|
Flags // flags
|
||||||
Flags // flags
|
);
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
debugVariable = DBuilder.createLocalVariable(tag, // tag
|
debugVariable = DBuilder.createLocalVariable(tag, // tag
|
||||||
GetCurrentScope(), // scope
|
GetCurrentScope(), // scope
|
||||||
|
@ -918,63 +921,63 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
#if LDC_LLVM_VER < 306
|
#if LDC_LLVM_VER < 306
|
||||||
} else {
|
} else {
|
||||||
debugVariable =
|
debugVariable = DBuilder.createComplexVariable(tag, // tag
|
||||||
DBuilder.createComplexVariable(tag, // tag
|
GetCurrentScope(), // scope
|
||||||
GetCurrentScope(), // scope
|
vd->toChars(), // name
|
||||||
vd->toChars(), // name
|
CreateFile(vd->loc), // file
|
||||||
CreateFile(vd->loc), // file
|
vd->loc.linnum, // line num
|
||||||
vd->loc.linnum, // line num
|
TD, // type
|
||||||
TD, // type
|
addr);
|
||||||
addr);
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
variableMap[vd] = debugVariable;
|
variableMap[vd] = debugVariable;
|
||||||
|
|
||||||
// declare
|
// declare
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
Declare(vd->loc, ll, debugVariable,
|
Declare(vd->loc, ll, debugVariable, addr.empty()
|
||||||
addr.empty() ? DBuilder.createExpression()
|
? DBuilder.createExpression()
|
||||||
: DBuilder.createExpression(addr));
|
: DBuilder.createExpression(addr));
|
||||||
#else
|
#else
|
||||||
Declare(vd->loc, ll, debugVariable);
|
Declare(vd->loc, ll, debugVariable);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ldc::DIGlobalVariable ldc::DIBuilder::EmitGlobalVariable(
|
ldc::DIGlobalVariable
|
||||||
llvm::GlobalVariable * ll, VarDeclaration * vd) {
|
ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *ll,
|
||||||
if (!global.params.symdebug) {
|
VarDeclaration *vd) {
|
||||||
|
if (!global.params.symdebug) {
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
return llvm::DIGlobalVariable();
|
return llvm::DIGlobalVariable();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
Logger::println("D to dwarf global_variable");
|
Logger::println("D to dwarf global_variable");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(vd->isDataseg() ||
|
assert(vd->isDataseg() ||
|
||||||
(vd->storage_class & (STCconst | STCimmutable) && vd->init));
|
(vd->storage_class & (STCconst | STCimmutable) && vd->init));
|
||||||
|
|
||||||
return DBuilder.createGlobalVariable(
|
return DBuilder.createGlobalVariable(
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
GetCU(), // context
|
GetCU(), // context
|
||||||
#endif
|
#endif
|
||||||
vd->toChars(), // name
|
vd->toChars(), // name
|
||||||
mangle(vd), // linkage name
|
mangle(vd), // linkage name
|
||||||
CreateFile(vd->loc), // file
|
CreateFile(vd->loc), // file
|
||||||
vd->loc.linnum, // line num
|
vd->loc.linnum, // line num
|
||||||
CreateTypeDescription(vd->type, false), // type
|
CreateTypeDescription(vd->type, false), // type
|
||||||
vd->protection == PROTprivate, // is local to unit
|
vd->protection == PROTprivate, // is local to unit
|
||||||
ll // value
|
ll // value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::Finalize() {
|
void ldc::DIBuilder::Finalize() {
|
||||||
if (!global.params.symdebug) {
|
if (!global.params.symdebug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBuilder.finalize();
|
DBuilder.finalize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,8 @@ void DtoResolveFunction(FuncDeclaration *fdecl) {
|
||||||
fdecl->ir.setDefined();
|
fdecl->ir.setDefined();
|
||||||
return; // this gets mapped to an instruction so a declaration makes
|
return; // this gets mapped to an instruction so a declaration makes
|
||||||
// no sence
|
// no sence
|
||||||
} else if (tempdecl->llvmInternal == LLVMva_start) {
|
}
|
||||||
|
if (tempdecl->llvmInternal == LLVMva_start) {
|
||||||
Logger::println("magic va_start found");
|
Logger::println("magic va_start found");
|
||||||
fdecl->llvmInternal = LLVMva_start;
|
fdecl->llvmInternal = LLVMva_start;
|
||||||
} else if (tempdecl->llvmInternal == LLVMintrinsic) {
|
} else if (tempdecl->llvmInternal == LLVMintrinsic) {
|
||||||
|
@ -1001,7 +1002,8 @@ int binary(const char *p, const char **tab, int high) {
|
||||||
l = strcmp(p, tab[k]);
|
l = strcmp(p, tab[k]);
|
||||||
if (!l) {
|
if (!l) {
|
||||||
return k;
|
return k;
|
||||||
} else if (l < 0) {
|
}
|
||||||
|
if (l < 0) {
|
||||||
j = k;
|
j = k;
|
||||||
} else {
|
} else {
|
||||||
i = k + 1;
|
i = k + 1;
|
||||||
|
|
|
@ -26,7 +26,7 @@ IRScope::IRScope() : builder(gIR->context()) { begin = nullptr; }
|
||||||
|
|
||||||
IRScope::IRScope(llvm::BasicBlock *b) : begin(b), builder(b) {}
|
IRScope::IRScope(llvm::BasicBlock *b) : begin(b), builder(b) {}
|
||||||
|
|
||||||
const IRScope &IRScope::operator=(const IRScope &rhs) {
|
IRScope &IRScope::operator=(const IRScope &rhs) {
|
||||||
begin = rhs.begin;
|
begin = rhs.begin;
|
||||||
builder.SetInsertPoint(begin);
|
builder.SetInsertPoint(begin);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -387,20 +387,18 @@ DValue *DtoNullValue(Type *type, Loc loc) {
|
||||||
}
|
}
|
||||||
// integer, floating, pointer, assoc array, delegate and class have no special
|
// integer, floating, pointer, assoc array, delegate and class have no special
|
||||||
// representation
|
// representation
|
||||||
else if (basetype->isintegral() || basetype->isfloating() ||
|
if (basetype->isintegral() || basetype->isfloating() || basety == Tpointer ||
|
||||||
basety == Tpointer || basety == Tclass || basety == Tdelegate ||
|
basety == Tclass || basety == Tdelegate || basety == Taarray) {
|
||||||
basety == Taarray) {
|
|
||||||
return new DConstValue(type, LLConstant::getNullValue(lltype));
|
return new DConstValue(type, LLConstant::getNullValue(lltype));
|
||||||
}
|
}
|
||||||
// dynamic array
|
// dynamic array
|
||||||
else if (basety == Tarray) {
|
if (basety == Tarray) {
|
||||||
LLValue *len = DtoConstSize_t(0);
|
LLValue *len = DtoConstSize_t(0);
|
||||||
LLValue *ptr = getNullPtr(DtoPtrToType(basetype->nextOf()));
|
LLValue *ptr = getNullPtr(DtoPtrToType(basetype->nextOf()));
|
||||||
return new DSliceValue(type, len, ptr);
|
return new DSliceValue(type, len, ptr);
|
||||||
} else {
|
|
||||||
error(loc, "null not known for type '%s'", type->toChars());
|
|
||||||
fatal();
|
|
||||||
}
|
}
|
||||||
|
error(loc, "null not known for type '%s'", type->toChars());
|
||||||
|
fatal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
|
@ -544,14 +542,14 @@ DValue *DtoCastFloat(Loc &loc, DValue *val, Type *to) {
|
||||||
DValue *DtoCastDelegate(Loc &loc, DValue *val, Type *to) {
|
DValue *DtoCastDelegate(Loc &loc, DValue *val, Type *to) {
|
||||||
if (to->toBasetype()->ty == Tdelegate) {
|
if (to->toBasetype()->ty == Tdelegate) {
|
||||||
return DtoPaintType(loc, val, to);
|
return DtoPaintType(loc, val, to);
|
||||||
} else if (to->toBasetype()->ty == Tbool) {
|
}
|
||||||
|
if (to->toBasetype()->ty == Tbool) {
|
||||||
return new DImValue(
|
return new DImValue(
|
||||||
to, DtoDelegateEquals(TOKnotequal, val->getRVal(), nullptr));
|
to, DtoDelegateEquals(TOKnotequal, val->getRVal(), nullptr));
|
||||||
} else {
|
|
||||||
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(),
|
|
||||||
to->toChars());
|
|
||||||
fatal();
|
|
||||||
}
|
}
|
||||||
|
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(),
|
||||||
|
to->toChars());
|
||||||
|
fatal();
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *DtoCastVector(Loc &loc, DValue *val, Type *to) {
|
DValue *DtoCastVector(Loc &loc, DValue *val, Type *to) {
|
||||||
|
@ -570,30 +568,29 @@ DValue *DtoCastVector(Loc &loc, DValue *val, Type *to) {
|
||||||
IF_LOG Logger::cout() << "src: " << *vector << "to type: " << *tolltype
|
IF_LOG Logger::cout() << "src: " << *vector << "to type: " << *tolltype
|
||||||
<< " (casting address)\n";
|
<< " (casting address)\n";
|
||||||
return new DVarValue(to, DtoBitCast(vector, getPtrToType(tolltype)));
|
return new DVarValue(to, DtoBitCast(vector, getPtrToType(tolltype)));
|
||||||
} else {
|
|
||||||
LLValue *vector = val->getRVal();
|
|
||||||
IF_LOG Logger::cout() << "src: " << *vector << "to type: " << *tolltype
|
|
||||||
<< " (creating temporary)\n";
|
|
||||||
LLValue *array = DtoAlloca(to);
|
|
||||||
|
|
||||||
TypeSArray *st = static_cast<TypeSArray *>(totype);
|
|
||||||
|
|
||||||
for (int i = 0, n = st->dim->toInteger(); i < n; ++i) {
|
|
||||||
LLValue *lelem = DtoExtractElement(vector, i);
|
|
||||||
DImValue elem(type->elementType(), lelem);
|
|
||||||
lelem = DtoCast(loc, &elem, to->nextOf())->getRVal();
|
|
||||||
DtoStore(lelem, DtoGEPi(array, 0, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DImValue(to, array);
|
|
||||||
}
|
}
|
||||||
} else if (totype->ty == Tvector && to->size() == val->getType()->size()) {
|
LLValue *vector = val->getRVal();
|
||||||
return new DImValue(to, DtoBitCast(val->getRVal(), tolltype));
|
IF_LOG Logger::cout() << "src: " << *vector << "to type: " << *tolltype
|
||||||
} else {
|
<< " (creating temporary)\n";
|
||||||
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(),
|
LLValue *array = DtoAlloca(to);
|
||||||
to->toChars());
|
|
||||||
fatal();
|
TypeSArray *st = static_cast<TypeSArray *>(totype);
|
||||||
|
|
||||||
|
for (int i = 0, n = st->dim->toInteger(); i < n; ++i) {
|
||||||
|
LLValue *lelem = DtoExtractElement(vector, i);
|
||||||
|
DImValue elem(type->elementType(), lelem);
|
||||||
|
lelem = DtoCast(loc, &elem, to->nextOf())->getRVal();
|
||||||
|
DtoStore(lelem, DtoGEPi(array, 0, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DImValue(to, array);
|
||||||
}
|
}
|
||||||
|
if (totype->ty == Tvector && to->size() == val->getType()->size()) {
|
||||||
|
return new DImValue(to, DtoBitCast(val->getRVal(), tolltype));
|
||||||
|
}
|
||||||
|
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(),
|
||||||
|
to->toChars());
|
||||||
|
fatal();
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *DtoCast(Loc &loc, DValue *val, Type *to) {
|
DValue *DtoCast(Loc &loc, DValue *val, Type *to) {
|
||||||
|
@ -607,7 +604,8 @@ DValue *DtoCast(Loc &loc, DValue *val, Type *to) {
|
||||||
IF_LOG Logger::println("Casting AA to pointer.");
|
IF_LOG Logger::println("Casting AA to pointer.");
|
||||||
LLValue *rval = DtoBitCast(val->getRVal(), DtoType(to));
|
LLValue *rval = DtoBitCast(val->getRVal(), DtoType(to));
|
||||||
return new DImValue(to, rval);
|
return new DImValue(to, rval);
|
||||||
} else if (totype->ty == Tbool) {
|
}
|
||||||
|
if (totype->ty == Tbool) {
|
||||||
IF_LOG Logger::println("Casting AA to bool.");
|
IF_LOG Logger::println("Casting AA to bool.");
|
||||||
LLValue *rval = val->getRVal();
|
LLValue *rval = val->getRVal();
|
||||||
LLValue *zero = LLConstant::getNullValue(rval->getType());
|
LLValue *zero = LLConstant::getNullValue(rval->getType());
|
||||||
|
@ -625,29 +623,37 @@ DValue *DtoCast(Loc &loc, DValue *val, Type *to) {
|
||||||
|
|
||||||
if (fromtype->ty == Tvector) {
|
if (fromtype->ty == Tvector) {
|
||||||
return DtoCastVector(loc, val, to);
|
return DtoCastVector(loc, val, to);
|
||||||
} else if (fromtype->isintegral()) {
|
|
||||||
return DtoCastInt(loc, val, to);
|
|
||||||
} else if (fromtype->iscomplex()) {
|
|
||||||
return DtoCastComplex(loc, val, to);
|
|
||||||
} else if (fromtype->isfloating()) {
|
|
||||||
return DtoCastFloat(loc, val, to);
|
|
||||||
} else if (fromtype->ty == Tclass) {
|
|
||||||
return DtoCastClass(loc, val, to);
|
|
||||||
} else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
|
|
||||||
return DtoCastArray(loc, val, to);
|
|
||||||
} else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) {
|
|
||||||
return DtoCastPtr(loc, val, to);
|
|
||||||
} else if (fromtype->ty == Tdelegate) {
|
|
||||||
return DtoCastDelegate(loc, val, to);
|
|
||||||
} else if (fromtype->ty == Tnull) {
|
|
||||||
return DtoNullValue(to, loc);
|
|
||||||
} else if (fromtype->ty == totype->ty) {
|
|
||||||
return val;
|
|
||||||
} else {
|
|
||||||
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(),
|
|
||||||
to->toChars());
|
|
||||||
fatal();
|
|
||||||
}
|
}
|
||||||
|
if (fromtype->isintegral()) {
|
||||||
|
return DtoCastInt(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->iscomplex()) {
|
||||||
|
return DtoCastComplex(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->isfloating()) {
|
||||||
|
return DtoCastFloat(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->ty == Tclass) {
|
||||||
|
return DtoCastClass(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
|
||||||
|
return DtoCastArray(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) {
|
||||||
|
return DtoCastPtr(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->ty == Tdelegate) {
|
||||||
|
return DtoCastDelegate(loc, val, to);
|
||||||
|
}
|
||||||
|
if (fromtype->ty == Tnull) {
|
||||||
|
return DtoNullValue(to, loc);
|
||||||
|
}
|
||||||
|
if (fromtype->ty == totype->ty) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(),
|
||||||
|
to->toChars());
|
||||||
|
fatal();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -664,18 +670,19 @@ DValue *DtoPaintType(Loc &loc, DValue *val, Type *to) {
|
||||||
if (DSliceValue *slice = val->isSlice()) {
|
if (DSliceValue *slice = val->isSlice()) {
|
||||||
return new DSliceValue(to, slice->len,
|
return new DSliceValue(to, slice->len,
|
||||||
DtoBitCast(slice->ptr, DtoType(elem)));
|
DtoBitCast(slice->ptr, DtoType(elem)));
|
||||||
} else if (val->isLVal()) {
|
}
|
||||||
|
if (val->isLVal()) {
|
||||||
LLValue *ptr = val->getLVal();
|
LLValue *ptr = val->getLVal();
|
||||||
ptr = DtoBitCast(ptr, DtoType(at->pointerTo()));
|
ptr = DtoBitCast(ptr, DtoType(at->pointerTo()));
|
||||||
return new DVarValue(to, ptr);
|
return new DVarValue(to, ptr);
|
||||||
} else {
|
|
||||||
LLValue *len, *ptr;
|
|
||||||
len = DtoArrayLen(val);
|
|
||||||
ptr = DtoArrayPtr(val);
|
|
||||||
ptr = DtoBitCast(ptr, DtoType(elem));
|
|
||||||
return new DImValue(to, DtoAggrPair(len, ptr));
|
|
||||||
}
|
}
|
||||||
} else if (from->ty == Tdelegate) {
|
LLValue *len, *ptr;
|
||||||
|
len = DtoArrayLen(val);
|
||||||
|
ptr = DtoArrayPtr(val);
|
||||||
|
ptr = DtoBitCast(ptr, DtoType(elem));
|
||||||
|
return new DImValue(to, DtoAggrPair(len, ptr));
|
||||||
|
}
|
||||||
|
if (from->ty == Tdelegate) {
|
||||||
Type *dgty = to->toBasetype();
|
Type *dgty = to->toBasetype();
|
||||||
assert(dgty->ty == Tdelegate);
|
assert(dgty->ty == Tdelegate);
|
||||||
if (val->isLVal()) {
|
if (val->isLVal()) {
|
||||||
|
@ -684,26 +691,24 @@ DValue *DtoPaintType(Loc &loc, DValue *val, Type *to) {
|
||||||
ptr = DtoBitCast(ptr, DtoPtrToType(dgty));
|
ptr = DtoBitCast(ptr, DtoPtrToType(dgty));
|
||||||
IF_LOG Logger::cout() << "dg ptr: " << *ptr << '\n';
|
IF_LOG Logger::cout() << "dg ptr: " << *ptr << '\n';
|
||||||
return new DVarValue(to, ptr);
|
return new DVarValue(to, ptr);
|
||||||
} else {
|
|
||||||
LLValue *dg = val->getRVal();
|
|
||||||
LLValue *context = gIR->ir->CreateExtractValue(dg, 0, ".context");
|
|
||||||
LLValue *funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
|
|
||||||
funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1));
|
|
||||||
LLValue *aggr = DtoAggrPair(context, funcptr);
|
|
||||||
IF_LOG Logger::cout() << "dg: " << *aggr << '\n';
|
|
||||||
return new DImValue(to, aggr);
|
|
||||||
}
|
}
|
||||||
} else if (from->ty == Tpointer || from->ty == Tclass ||
|
LLValue *dg = val->getRVal();
|
||||||
from->ty == Taarray) {
|
LLValue *context = gIR->ir->CreateExtractValue(dg, 0, ".context");
|
||||||
|
LLValue *funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
|
||||||
|
funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1));
|
||||||
|
LLValue *aggr = DtoAggrPair(context, funcptr);
|
||||||
|
IF_LOG Logger::cout() << "dg: " << *aggr << '\n';
|
||||||
|
return new DImValue(to, aggr);
|
||||||
|
}
|
||||||
|
if (from->ty == Tpointer || from->ty == Tclass || from->ty == Taarray) {
|
||||||
Type *b = to->toBasetype();
|
Type *b = to->toBasetype();
|
||||||
assert(b->ty == Tpointer || b->ty == Tclass || b->ty == Taarray);
|
assert(b->ty == Tpointer || b->ty == Tclass || b->ty == Taarray);
|
||||||
LLValue *ptr = DtoBitCast(val->getRVal(), DtoType(b));
|
LLValue *ptr = DtoBitCast(val->getRVal(), DtoType(b));
|
||||||
return new DImValue(to, ptr);
|
return new DImValue(to, ptr);
|
||||||
} else {
|
|
||||||
// assert(!val->isLVal()); TODO: what is it needed for?
|
|
||||||
assert(DtoType(to) == DtoType(to));
|
|
||||||
return new DImValue(to, val->getRVal());
|
|
||||||
}
|
}
|
||||||
|
// assert(!val->isLVal()); TODO: what is it needed for?
|
||||||
|
assert(DtoType(to) == DtoType(to));
|
||||||
|
return new DImValue(to, val->getRVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
|
@ -977,7 +982,7 @@ DValue *DtoDeclarationExp(Dsymbol *declaration) {
|
||||||
return new DVarValue(vd->type, vd, getIrValue(vd));
|
return new DVarValue(vd->type, vd, getIrValue(vd));
|
||||||
}
|
}
|
||||||
// struct declaration
|
// struct declaration
|
||||||
else if (StructDeclaration *s = declaration->isStructDeclaration()) {
|
if (StructDeclaration *s = declaration->isStructDeclaration()) {
|
||||||
Logger::println("StructDeclaration");
|
Logger::println("StructDeclaration");
|
||||||
Declaration_codegen(s);
|
Declaration_codegen(s);
|
||||||
}
|
}
|
||||||
|
@ -1281,7 +1286,8 @@ bool hasUnalignedFields(Type *t) {
|
||||||
if (t->ty == Tsarray) {
|
if (t->ty == Tsarray) {
|
||||||
assert(t->nextOf()->size() % t->nextOf()->alignsize() == 0);
|
assert(t->nextOf()->size() % t->nextOf()->alignsize() == 0);
|
||||||
return hasUnalignedFields(t->nextOf());
|
return hasUnalignedFields(t->nextOf());
|
||||||
} else if (t->ty != Tstruct) {
|
}
|
||||||
|
if (t->ty != Tstruct) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,8 +1305,8 @@ bool hasUnalignedFields(Type *t) {
|
||||||
unsigned a = f->type->alignsize() - 1;
|
unsigned a = f->type->alignsize() - 1;
|
||||||
if (((f->offset + a) & ~a) != f->offset) {
|
if (((f->offset + a) & ~a) != f->offset) {
|
||||||
return true;
|
return true;
|
||||||
} else if (f->type->toBasetype()->ty == Tstruct &&
|
}
|
||||||
hasUnalignedFields(f->type)) {
|
if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1336,9 +1342,8 @@ Type *stripModifiers(Type *type, bool transitive) {
|
||||||
|
|
||||||
if (transitive) {
|
if (transitive) {
|
||||||
return type->unqualify(MODimmutable | MODconst | MODwild);
|
return type->unqualify(MODimmutable | MODconst | MODwild);
|
||||||
} else {
|
|
||||||
return type->castMod(0);
|
|
||||||
}
|
}
|
||||||
|
return type->castMod(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1486,13 +1491,13 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
|
||||||
return new DVarValue(type, vd, v);
|
return new DVarValue(type, vd, v);
|
||||||
}
|
}
|
||||||
// _argptr
|
// _argptr
|
||||||
else if (vd->ident == Id::_argptr && gIR->func()->_argptr) {
|
if (vd->ident == Id::_argptr && gIR->func()->_argptr) {
|
||||||
Logger::println("Id::_argptr");
|
Logger::println("Id::_argptr");
|
||||||
LLValue *v = gIR->func()->_argptr;
|
LLValue *v = gIR->func()->_argptr;
|
||||||
return new DVarValue(type, vd, v);
|
return new DVarValue(type, vd, v);
|
||||||
}
|
}
|
||||||
// _dollar
|
// _dollar
|
||||||
else if (vd->ident == Id::dollar) {
|
if (vd->ident == Id::dollar) {
|
||||||
Logger::println("Id::dollar");
|
Logger::println("Id::dollar");
|
||||||
LLValue *val = nullptr;
|
LLValue *val = nullptr;
|
||||||
if (isIrVarCreated(vd) && (val = getIrValue(vd))) {
|
if (isIrVarCreated(vd) && (val = getIrValue(vd))) {
|
||||||
|
@ -1504,7 +1509,7 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
|
||||||
return new DImValue(type, val);
|
return new DImValue(type, val);
|
||||||
}
|
}
|
||||||
// typeinfo
|
// typeinfo
|
||||||
else if (TypeInfoDeclaration *tid = vd->isTypeInfoDeclaration()) {
|
if (TypeInfoDeclaration *tid = vd->isTypeInfoDeclaration()) {
|
||||||
Logger::println("TypeInfoDeclaration");
|
Logger::println("TypeInfoDeclaration");
|
||||||
DtoResolveTypeInfo(tid);
|
DtoResolveTypeInfo(tid);
|
||||||
assert(getIrValue(tid));
|
assert(getIrValue(tid));
|
||||||
|
@ -1516,12 +1521,12 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
|
||||||
return new DImValue(type, m);
|
return new DImValue(type, m);
|
||||||
}
|
}
|
||||||
// nested variable
|
// nested variable
|
||||||
else if (vd->nestedrefs.dim) {
|
if (vd->nestedrefs.dim) {
|
||||||
Logger::println("nested variable");
|
Logger::println("nested variable");
|
||||||
return DtoNestedVariable(loc, type, vd);
|
return DtoNestedVariable(loc, type, vd);
|
||||||
}
|
}
|
||||||
// function parameter
|
// function parameter
|
||||||
else if (vd->isParameter()) {
|
if (vd->isParameter()) {
|
||||||
IF_LOG {
|
IF_LOG {
|
||||||
Logger::println("function param");
|
Logger::println("function param");
|
||||||
Logger::println("type: %s", vd->type->toChars());
|
Logger::println("type: %s", vd->type->toChars());
|
||||||
|
@ -1530,18 +1535,21 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
|
||||||
if (fd && fd != gIR->func()->decl) {
|
if (fd && fd != gIR->func()->decl) {
|
||||||
Logger::println("nested parameter");
|
Logger::println("nested parameter");
|
||||||
return DtoNestedVariable(loc, type, vd);
|
return DtoNestedVariable(loc, type, vd);
|
||||||
} else if (vd->storage_class & STClazy) {
|
}
|
||||||
|
if (vd->storage_class & STClazy) {
|
||||||
Logger::println("lazy parameter");
|
Logger::println("lazy parameter");
|
||||||
assert(type->ty == Tdelegate);
|
assert(type->ty == Tdelegate);
|
||||||
return new DVarValue(type, getIrValue(vd));
|
return new DVarValue(type, getIrValue(vd));
|
||||||
} else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) ||
|
|
||||||
llvm::isa<llvm::AllocaInst>(getIrValue(vd))) {
|
|
||||||
return new DVarValue(type, vd, getIrValue(vd));
|
|
||||||
} else if (llvm::isa<llvm::Argument>(getIrValue(vd))) {
|
|
||||||
return new DImValue(type, getIrValue(vd));
|
|
||||||
} else {
|
|
||||||
llvm_unreachable("Unexpected parameter value.");
|
|
||||||
}
|
}
|
||||||
|
if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) ||
|
||||||
|
llvm::isa<llvm::AllocaInst>(getIrValue(vd))) {
|
||||||
|
return new DVarValue(type, vd, getIrValue(vd));
|
||||||
|
}
|
||||||
|
if (llvm::isa<llvm::Argument>(getIrValue(vd))) {
|
||||||
|
return new DImValue(type, getIrValue(vd));
|
||||||
|
}
|
||||||
|
llvm_unreachable("Unexpected parameter value.");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Logger::println("a normal variable");
|
Logger::println("a normal variable");
|
||||||
|
|
||||||
|
@ -1637,7 +1645,7 @@ llvm::Constant *DtoConstSymbolAddress(Loc &loc, Declaration *decl) {
|
||||||
return llc;
|
return llc;
|
||||||
}
|
}
|
||||||
// static function
|
// static function
|
||||||
else if (FuncDeclaration *fd = decl->isFuncDeclaration()) {
|
if (FuncDeclaration *fd = decl->isFuncDeclaration()) {
|
||||||
DtoResolveFunction(fd);
|
DtoResolveFunction(fd);
|
||||||
return getIrFunc(fd)->func;
|
return getIrFunc(fd)->func;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,8 @@ void undent() {
|
||||||
Stream cout() {
|
Stream cout() {
|
||||||
if (_enabled) {
|
if (_enabled) {
|
||||||
return Stream(std::cout << indent_str);
|
return Stream(std::cout << indent_str);
|
||||||
} else {
|
|
||||||
return Stream(nullptr);
|
|
||||||
}
|
}
|
||||||
|
return Stream(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
|
@ -96,11 +96,13 @@ public:
|
||||||
if (!vd && !fd && !ed) {
|
if (!vd && !fd && !ed) {
|
||||||
visit(static_cast<Statement *>(stmt));
|
visit(static_cast<Statement *>(stmt));
|
||||||
return;
|
return;
|
||||||
} else if (vd && !(vd->storage_class & (STCstatic | STCmanifest))) {
|
}
|
||||||
|
if (vd && !(vd->storage_class & (STCstatic | STCmanifest))) {
|
||||||
error(vd->loc, "non-static variable '%s' not allowed in naked function",
|
error(vd->loc, "non-static variable '%s' not allowed in naked function",
|
||||||
vd->toChars());
|
vd->toChars());
|
||||||
return;
|
return;
|
||||||
} else if (fd && !fd->isStatic()) {
|
}
|
||||||
|
if (fd && !fd->isStatic()) {
|
||||||
error(fd->loc,
|
error(fd->loc,
|
||||||
"non-static nested function '%s' not allowed in naked function",
|
"non-static nested function '%s' not allowed in naked function",
|
||||||
fd->toChars());
|
fd->toChars());
|
||||||
|
|
|
@ -75,7 +75,8 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
int cmp = name.compare(ldcIntrinsic[k].name);
|
int cmp = name.compare(ldcIntrinsic[k].name);
|
||||||
if (!cmp) {
|
if (!cmp) {
|
||||||
return ldcIntrinsic[k].pragma;
|
return ldcIntrinsic[k].pragma;
|
||||||
} else if (cmp < 0) {
|
}
|
||||||
|
if (cmp < 0) {
|
||||||
j = k;
|
j = k;
|
||||||
} else {
|
} else {
|
||||||
i = k + 1;
|
i = k + 1;
|
||||||
|
@ -87,8 +88,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_global_crt_ctor [, priority]) { funcdecl(s) }
|
// pragma(LDC_global_crt_ctor [, priority]) { funcdecl(s) }
|
||||||
else if (ident == Id::LDC_global_crt_ctor ||
|
if (ident == Id::LDC_global_crt_ctor || ident == Id::LDC_global_crt_dtor) {
|
||||||
ident == Id::LDC_global_crt_dtor) {
|
|
||||||
dinteger_t priority;
|
dinteger_t priority;
|
||||||
if (args) {
|
if (args) {
|
||||||
if (args->dim != 1 || !parseIntExp(expr, priority)) {
|
if (args->dim != 1 || !parseIntExp(expr, priority)) {
|
||||||
|
@ -110,7 +110,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_no_typeinfo) { typedecl(s) }
|
// pragma(LDC_no_typeinfo) { typedecl(s) }
|
||||||
else if (ident == Id::LDC_no_typeinfo) {
|
if (ident == Id::LDC_no_typeinfo) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -119,7 +119,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_no_moduleinfo) ;
|
// pragma(LDC_no_moduleinfo) ;
|
||||||
else if (ident == Id::LDC_no_moduleinfo) {
|
if (ident == Id::LDC_no_moduleinfo) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -129,7 +129,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_alloca) { funcdecl(s) }
|
// pragma(LDC_alloca) { funcdecl(s) }
|
||||||
else if (ident == Id::LDC_alloca) {
|
if (ident == Id::LDC_alloca) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -138,7 +138,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_va_start) { templdecl(s) }
|
// pragma(LDC_va_start) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_va_start) {
|
if (ident == Id::LDC_va_start) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -147,7 +147,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_va_copy) { funcdecl(s) }
|
// pragma(LDC_va_copy) { funcdecl(s) }
|
||||||
else if (ident == Id::LDC_va_copy) {
|
if (ident == Id::LDC_va_copy) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -156,7 +156,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_va_end) { funcdecl(s) }
|
// pragma(LDC_va_end) { funcdecl(s) }
|
||||||
else if (ident == Id::LDC_va_end) {
|
if (ident == Id::LDC_va_end) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -165,7 +165,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_va_arg) { templdecl(s) }
|
// pragma(LDC_va_arg) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_va_arg) {
|
if (ident == Id::LDC_va_arg) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -174,7 +174,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_fence) { funcdecl(s) }
|
// pragma(LDC_fence) { funcdecl(s) }
|
||||||
else if (ident == Id::LDC_fence) {
|
if (ident == Id::LDC_fence) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -183,7 +183,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_atomic_load) { templdecl(s) }
|
// pragma(LDC_atomic_load) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_atomic_load) {
|
if (ident == Id::LDC_atomic_load) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -192,7 +192,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_atomic_store) { templdecl(s) }
|
// pragma(LDC_atomic_store) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_atomic_store) {
|
if (ident == Id::LDC_atomic_store) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -201,7 +201,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_atomic_cmp_xchg) { templdecl(s) }
|
// pragma(LDC_atomic_cmp_xchg) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_atomic_cmp_xchg) {
|
if (ident == Id::LDC_atomic_cmp_xchg) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -210,7 +210,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_atomic_rmw, "string") { templdecl(s) }
|
// pragma(LDC_atomic_rmw, "string") { templdecl(s) }
|
||||||
else if (ident == Id::LDC_atomic_rmw) {
|
if (ident == Id::LDC_atomic_rmw) {
|
||||||
if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) {
|
if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) {
|
||||||
error(Loc(), "requires exactly 1 string literal parameter");
|
error(Loc(), "requires exactly 1 string literal parameter");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -219,7 +219,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_verbose);
|
// pragma(LDC_verbose);
|
||||||
else if (ident == Id::LDC_verbose) {
|
if (ident == Id::LDC_verbose) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -229,7 +229,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_inline_asm) { templdecl(s) }
|
// pragma(LDC_inline_asm) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_inline_asm) {
|
if (ident == Id::LDC_inline_asm) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -238,7 +238,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_inline_ir) { templdecl(s) }
|
// pragma(LDC_inline_ir) { templdecl(s) }
|
||||||
else if (ident == Id::LDC_inline_ir) {
|
if (ident == Id::LDC_inline_ir) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -247,7 +247,7 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pragma(LDC_extern_weak) { vardecl(s) }
|
// pragma(LDC_extern_weak) { vardecl(s) }
|
||||||
else if (ident == Id::LDC_extern_weak) {
|
if (ident == Id::LDC_extern_weak) {
|
||||||
if (args && args->dim > 0) {
|
if (args && args->dim > 0) {
|
||||||
error(Loc(), "takes no parameters");
|
error(Loc(), "takes no parameters");
|
||||||
fatal();
|
fatal();
|
||||||
|
|
|
@ -68,11 +68,12 @@ unsigned Target::critsecsize() {
|
||||||
#else
|
#else
|
||||||
if (global.params.targetTriple.isOSWindows()) {
|
if (global.params.targetTriple.isOSWindows()) {
|
||||||
return global.params.is64bit ? 40 : 24;
|
return global.params.is64bit ? 40 : 24;
|
||||||
} else if (global.params.targetTriple.getOS() == llvm::Triple::FreeBSD) {
|
|
||||||
return sizeof(size_t);
|
|
||||||
} else {
|
|
||||||
return sizeof(pthread_mutex_t);
|
|
||||||
}
|
}
|
||||||
|
if (global.params.targetTriple.getOS() == llvm::Triple::FreeBSD) {
|
||||||
|
return sizeof(size_t);
|
||||||
|
}
|
||||||
|
return sizeof(pthread_mutex_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ TypeFunction *DtoTypeFunction(DValue *fnval) {
|
||||||
Type *type = fnval->getType()->toBasetype();
|
Type *type = fnval->getType()->toBasetype();
|
||||||
if (type->ty == Tfunction) {
|
if (type->ty == Tfunction) {
|
||||||
return static_cast<TypeFunction *>(type);
|
return static_cast<TypeFunction *>(type);
|
||||||
} else if (type->ty == Tdelegate) {
|
}
|
||||||
|
if (type->ty == Tdelegate) {
|
||||||
// FIXME: There is really no reason why the function type should be
|
// FIXME: There is really no reason why the function type should be
|
||||||
// unmerged at this stage, but the frontend still seems to produce such
|
// unmerged at this stage, but the frontend still seems to produce such
|
||||||
// cases; for example for the uint(uint) next type of the return type of
|
// cases; for example for the uint(uint) next type of the return type of
|
||||||
|
@ -71,16 +72,16 @@ LLValue *DtoCallableValue(DValue *fn) {
|
||||||
Type *type = fn->getType()->toBasetype();
|
Type *type = fn->getType()->toBasetype();
|
||||||
if (type->ty == Tfunction) {
|
if (type->ty == Tfunction) {
|
||||||
return fn->getRVal();
|
return fn->getRVal();
|
||||||
} else if (type->ty == Tdelegate) {
|
}
|
||||||
|
if (type->ty == Tdelegate) {
|
||||||
if (fn->isLVal()) {
|
if (fn->isLVal()) {
|
||||||
LLValue *dg = fn->getLVal();
|
LLValue *dg = fn->getLVal();
|
||||||
LLValue *funcptr = DtoGEPi(dg, 0, 1);
|
LLValue *funcptr = DtoGEPi(dg, 0, 1);
|
||||||
return DtoLoad(funcptr, ".funcptr");
|
return DtoLoad(funcptr, ".funcptr");
|
||||||
} else {
|
|
||||||
LLValue *dg = fn->getRVal();
|
|
||||||
assert(isaStruct(dg));
|
|
||||||
return gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
|
|
||||||
}
|
}
|
||||||
|
LLValue *dg = fn->getRVal();
|
||||||
|
assert(isaStruct(dg));
|
||||||
|
return gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_unreachable("Not a callable type.");
|
llvm_unreachable("Not a callable type.");
|
||||||
|
@ -91,7 +92,8 @@ LLValue *DtoCallableValue(DValue *fn) {
|
||||||
LLFunctionType *DtoExtractFunctionType(LLType *type) {
|
LLFunctionType *DtoExtractFunctionType(LLType *type) {
|
||||||
if (LLFunctionType *fty = isaFunction(type)) {
|
if (LLFunctionType *fty = isaFunction(type)) {
|
||||||
return fty;
|
return fty;
|
||||||
} else if (LLPointerType *pty = isaPointer(type)) {
|
}
|
||||||
|
if (LLPointerType *pty = isaPointer(type)) {
|
||||||
if (LLFunctionType *fty = isaFunction(pty->getElementType())) {
|
if (LLFunctionType *fty = isaFunction(pty->getElementType())) {
|
||||||
return fty;
|
return fty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -746,7 +746,7 @@ public:
|
||||||
|
|
||||||
Type *t = isType(e->obj);
|
Type *t = isType(e->obj);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
visit((Expression *)e);
|
visit(static_cast<Expression *>(e));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
gen/toir.cpp
10
gen/toir.cpp
|
@ -1068,7 +1068,8 @@ public:
|
||||||
Logger::println("is field");
|
Logger::println("is field");
|
||||||
result = v;
|
result = v;
|
||||||
return;
|
return;
|
||||||
} else if (DFuncValue *fv = v->isFunc()) {
|
}
|
||||||
|
if (DFuncValue *fv = v->isFunc()) {
|
||||||
Logger::println("is func");
|
Logger::println("is func");
|
||||||
// Logger::println("FuncDeclaration");
|
// Logger::println("FuncDeclaration");
|
||||||
FuncDeclaration *fd = fv->func;
|
FuncDeclaration *fd = fv->func;
|
||||||
|
@ -1076,7 +1077,8 @@ public:
|
||||||
DtoResolveFunction(fd);
|
DtoResolveFunction(fd);
|
||||||
result = new DFuncValue(fd, getIrFunc(fd)->func);
|
result = new DFuncValue(fd, getIrFunc(fd)->func);
|
||||||
return;
|
return;
|
||||||
} else if (v->isIm()) {
|
}
|
||||||
|
if (v->isIm()) {
|
||||||
Logger::println("is immediate");
|
Logger::println("is immediate");
|
||||||
result = v;
|
result = v;
|
||||||
return;
|
return;
|
||||||
|
@ -1234,7 +1236,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// regular this expr
|
// regular this expr
|
||||||
else if (VarDeclaration *vd = e->var->isVarDeclaration()) {
|
if (VarDeclaration *vd = e->var->isVarDeclaration()) {
|
||||||
LLValue *v;
|
LLValue *v;
|
||||||
Dsymbol *vdparent = vd->toParent2();
|
Dsymbol *vdparent = vd->toParent2();
|
||||||
Identifier *ident = p->func()->decl->ident;
|
Identifier *ident = p->func()->decl->ident;
|
||||||
|
@ -2189,7 +2191,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// also structs
|
// also structs
|
||||||
else if (t1->ty == Tstruct) {
|
if (t1->ty == Tstruct) {
|
||||||
result = new DImValue(e->type, DtoStructEquals(e->op, l, r));
|
result = new DImValue(e->type, DtoStructEquals(e->op, l, r));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,14 +413,16 @@ LLConstant *DtoConstFP(Type *t, longdouble value) {
|
||||||
if (llty == LLType::getFloatTy(gIR->context()) ||
|
if (llty == LLType::getFloatTy(gIR->context()) ||
|
||||||
llty == LLType::getDoubleTy(gIR->context())) {
|
llty == LLType::getDoubleTy(gIR->context())) {
|
||||||
return LLConstantFP::get(llty, value);
|
return LLConstantFP::get(llty, value);
|
||||||
} else if (llty == LLType::getX86_FP80Ty(gIR->context())) {
|
}
|
||||||
|
if (llty == LLType::getX86_FP80Ty(gIR->context())) {
|
||||||
uint64_t bits[] = {0, 0};
|
uint64_t bits[] = {0, 0};
|
||||||
bits[0] = *reinterpret_cast<uint64_t *>(&value);
|
bits[0] = *reinterpret_cast<uint64_t *>(&value);
|
||||||
bits[1] =
|
bits[1] =
|
||||||
*reinterpret_cast<uint16_t *>(reinterpret_cast<uint64_t *>(&value) + 1);
|
*reinterpret_cast<uint16_t *>(reinterpret_cast<uint64_t *>(&value) + 1);
|
||||||
return LLConstantFP::get(gIR->context(), APFloat(APFloat::x87DoubleExtended,
|
return LLConstantFP::get(gIR->context(), APFloat(APFloat::x87DoubleExtended,
|
||||||
APInt(80, 2, bits)));
|
APInt(80, 2, bits)));
|
||||||
} else if (llty == LLType::getPPC_FP128Ty(gIR->context())) {
|
}
|
||||||
|
if (llty == LLType::getPPC_FP128Ty(gIR->context())) {
|
||||||
uint64_t bits[] = {0, 0};
|
uint64_t bits[] = {0, 0};
|
||||||
bits[0] = *reinterpret_cast<uint64_t *>(&value);
|
bits[0] = *reinterpret_cast<uint64_t *>(&value);
|
||||||
bits[1] =
|
bits[1] =
|
||||||
|
@ -685,7 +687,7 @@ LLStructType *DtoMutexType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FreeBSD
|
// FreeBSD
|
||||||
else if (global.params.targetTriple.getOS() == llvm::Triple::FreeBSD) {
|
if (global.params.targetTriple.getOS() == llvm::Triple::FreeBSD) {
|
||||||
// Just a pointer
|
// Just a pointer
|
||||||
return LLStructType::get(gIR->context(), DtoSize_t());
|
return LLStructType::get(gIR->context(), DtoSize_t());
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ TypeInfoDeclaration *createUnqualified(Type *t) {
|
||||||
case Ttuple:
|
case Ttuple:
|
||||||
return TypeInfoTupleDeclaration::create(t);
|
return TypeInfoTupleDeclaration::create(t);
|
||||||
case Tclass:
|
case Tclass:
|
||||||
if (((TypeClass *)t)->sym->isInterfaceDeclaration()) {
|
if ((static_cast<TypeClass *>(t))->sym->isInterfaceDeclaration()) {
|
||||||
return TypeInfoInterfaceDeclaration::create(t);
|
return TypeInfoInterfaceDeclaration::create(t);
|
||||||
} else {
|
} else {
|
||||||
return TypeInfoClassDeclaration::create(t);
|
return TypeInfoClassDeclaration::create(t);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 37f5b7ea9e25dd405eca8b3b71565fa3014b7cd9
|
Subproject commit 0dc960aa0b3ad26da8ebbf843b911a0c9b257cee
|
Loading…
Add table
Add a link
Reference in a new issue