static QualifiedType returnInfoComplexField(CallExpr* call) { // for get real/imag primitives Type *t = call->get(1)->getValType(); if (t == dtComplex[COMPLEX_SIZE_64]) { return QualifiedType(dtReal[FLOAT_SIZE_32]->refType, QUAL_REF); } else if (t == dtComplex[COMPLEX_SIZE_128]) { return QualifiedType(dtReal[FLOAT_SIZE_64]->refType, QUAL_REF); } else { INT_FATAL( call, "unsupported complex size"); } return QualifiedType(dtUnknown); }
// NEEDS TO BE FINISHED WHEN PRIMITIVES ARE REDONE static QualifiedType returnInfoNumericUp(CallExpr* call) { Type* t1 = call->get(1)->typeInfo(); Type* t2 = call->get(2)->typeInfo(); if (is_int_type(t1) && is_real_type(t2)) return QualifiedType(t2, QUAL_VAL); if (is_real_type(t1) && is_int_type(t2)) return QualifiedType(t1, QUAL_VAL); if (is_int_type(t1) && is_bool_type(t2)) return QualifiedType(t1, QUAL_VAL); if (is_bool_type(t1) && is_int_type(t2)) return QualifiedType(t2, QUAL_VAL); return QualifiedType(t1, QUAL_VAL); }
static QualifiedType returnInfoVal(CallExpr* call) { AggregateType* ct = toAggregateType(call->get(1)->typeInfo()); if (ct) { if(ct->symbol->hasFlag(FLAG_REF)) { return QualifiedType(ct->getField(1)->type, QUAL_VAL); } else if(ct->symbol->hasFlag(FLAG_WIDE_REF)) { return QualifiedType(ct->getField(2)->type, QUAL_VAL); } } INT_FATAL(call, "attempt to get value type of non-reference type"); return QualifiedType(NULL); }
static QualifiedType returnInfoAsRef(CallExpr* call) { Type* t = call->get(1)->typeInfo(); if (isReferenceType(t)) { return QualifiedType(t, QUAL_REF); } else if (t->symbol->hasFlag(FLAG_WIDE_REF)) { return QualifiedType(t, QUAL_WIDE_REF); } else { if (!t->refType) INT_FATAL(call, "invalid attempt to get reference type"); return QualifiedType(t->refType, QUAL_REF); } }
static QualifiedType returnInfoArrayIndexValue(CallExpr* call) { Type* type = call->get(1)->typeInfo(); if (type->symbol->hasFlag(FLAG_WIDE_CLASS)) type = type->getField("addr")->type; if (!type->substitutions.n) INT_FATAL(call, "bad primitive"); // Is this conditional necessary? Can just assume condition is true? if (type->symbol->hasFlag(FLAG_DATA_CLASS)) { return QualifiedType(toTypeSymbol(getDataClassType(type->symbol))->type, QUAL_VAL); } else { return QualifiedType(toTypeSymbol(type->substitutions.v[0].value)->type, QUAL_VAL); } }
// BHARSH TODO: merge this with returnInfoAsRef and fix the WIDE_REF case... static QualifiedType returnInfoRef(CallExpr* call) { Type* t = call->get(1)->getValType(); if (!t->refType) INT_FATAL(call, "invalid attempt to get reference type"); return QualifiedType(t->refType, QUAL_REF); }
static QualifiedType returnInfoFirstDeref(CallExpr* call) { QualifiedType tmp = call->get(1)->qualType(); Type* type = tmp.type()->getValType(); // if it's a tuple, also remove references in the elements if (type->symbol->hasFlag(FLAG_TUPLE)) { type = computeNonRefTuple(type); } return QualifiedType(type, QUAL_VAL); }
static QualifiedType returnInfoCast(CallExpr* call) { Type* t1 = call->get(1)->typeInfo(); Type* t2 = call->get(2)->typeInfo(); if (t2->symbol->hasFlag(FLAG_WIDE_CLASS)) if (wideClassMap.get(t1)) t1 = wideClassMap.get(t1); if (t2->symbol->hasFlag(FLAG_WIDE_REF)) if (wideRefMap.get(t1)) t1 = wideRefMap.get(t1); return QualifiedType(t1); // what should qual be here? }
static QualifiedType returnInfoVal(CallExpr* call) { AggregateType* ct = toAggregateType(call->get(1)->typeInfo()); if (ct) { if (call->get(1)->isRef()) { if(ct->symbol->hasFlag(FLAG_REF)) { return QualifiedType(ct->getField(1)->type, QUAL_VAL); } else { return QualifiedType(ct, QUAL_VAL); } } else if (call->get(1)->isWideRef()) { if(ct->symbol->hasFlag(FLAG_WIDE_REF)) { return QualifiedType(ct->getField(2)->type, QUAL_VAL); } else { return QualifiedType(ct, QUAL_VAL); } } else if (ct->symbol->hasFlag(FLAG_WIDE_CLASS)) { // insertWideReferences will sometimes insert a PRIM_DEREF to a // wide class. There should probably be a better way of expressing the // desired pattern... return QualifiedType(ct, QUAL_VAL); } } INT_FATAL(call, "attempt to get value type of non-reference type"); return QualifiedType(NULL); }
QualifiedType AmbiguousTypeParamType::forType(QualifiedType base, const Type * match, unsigned paramIndex) { base = dealias(base); match = dealias(match); switch (base->typeClass()) { case Type::Class: case Type::Struct: case Type::Interface: case Type::Protocol: { const CompositeType * ctBase = static_cast<const CompositeType *>(base.type()); if (const CompositeType * ctMatch = dyn_cast_or_null<CompositeType>(match)) { if (ctMatch != NULL) { base = ctBase->findBaseSpecializing(ctMatch); if (!base) { return QualifiedType(); } } if (paramIndex >= base->numTypeParams()) { return QualifiedType(); } else { return base->typeParam(paramIndex); } } return QualifiedType(); } case Type::NAddress: case Type::NArray: case Type::FlexibleArray: { if (paramIndex == 0 && (match == NULL || base->typeClass() == match->typeClass())) { return base->typeParam(0); } return QualifiedType(); } case Type::Tuple: { if (match != NULL || paramIndex >= base->numTypeParams()) { return QualifiedType(); } else { return base->typeParam(paramIndex); } } case Type::AmbiguousParameter: case Type::AmbiguousResult: case Type::AmbiguousTypeParam: case Type::AmbiguousPhi: case Type::Assignment: { QualifiedTypeSet expansion; base.expand(expansion); if (expansion.size() == 1) { return forType(*expansion.begin(), match, paramIndex); } return new AmbiguousTypeParamType(base, match, paramIndex); } default: return QualifiedType(); } }
static QualifiedType returnInfoGetMember(CallExpr* call) { AggregateType* ct = toAggregateType(call->get(1)->typeInfo()); if (ct->symbol->hasFlag(FLAG_REF)) ct = toAggregateType(ct->getValType()); if (!ct) INT_FATAL(call, "bad member primitive"); SymExpr* sym = toSymExpr(call->get(2)); if (!sym) INT_FATAL(call, "bad member primitive"); VarSymbol* var = toVarSymbol(sym->var); if (!var) INT_FATAL(call, "bad member primitive"); if (var->immediate) { const char* name = var->immediate->v_string; for_fields(field, ct) { if (!strcmp(field->name, name)) return QualifiedType(field->type, QUAL_VAL); } } else return QualifiedType(var->type, QUAL_VAL);
static QualifiedType returnInfoSizeType(CallExpr* call) { return QualifiedType(SIZE_TYPE, QUAL_VAL); }
static QualifiedType returnInfoInt64(CallExpr* call) { return QualifiedType(dtInt[INT_SIZE_64], QUAL_VAL); }
static QualifiedType returnInfoUInt8(CallExpr* call) { return QualifiedType(dtUInt[INT_SIZE_8], QUAL_VAL); }
static QualifiedType returnInfoNodeID(CallExpr* call) { return QualifiedType(NODE_ID_TYPE, QUAL_VAL); }
static QualifiedType returnInfoLocaleID(CallExpr* call) { return QualifiedType(dtLocaleID, QUAL_VAL); }
static QualifiedType returnInfoStringCopy(CallExpr* call) { return QualifiedType(dtStringCopy, QUAL_VAL); }
static QualifiedType returnInfoBool(CallExpr* call) { return QualifiedType(dtBool, QUAL_VAL); }
static QualifiedType returnInfoCVoidPtr(CallExpr* call) { return QualifiedType(dtCVoidPtr, QUAL_VAL); }
static QualifiedType returnInfoVoid(CallExpr* call) { return QualifiedType(dtVoid, QUAL_VAL); }
static QualifiedType returnInfoUnknown(CallExpr* call) { return QualifiedType(dtUnknown); }
static QualifiedType returnInfoArrayIndex(CallExpr* call) { QualifiedType tmp = returnInfoArrayIndexValue(call); return QualifiedType(tmp.type()->refType, QUAL_REF); }
static QualifiedType returnInfoFirstDeref(CallExpr* call) { QualifiedType tmp = call->get(1)->qualType(); Type* type = tmp.type()->getValType(); return QualifiedType(type, QUAL_VAL); }
QualifiedType Expr::qualType() { INT_FATAL(this, "Illegal call to Expr::qualType()"); return QualifiedType(NULL); }