コード例 #1
0
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();
  }
}
コード例 #2
0
ファイル: SpCandidate.cpp プロジェクト: afrog33k/tart
bool SpCandidate::isMoreSpecific(const SpCandidate * other) const {
  const Template * tm = def_->templateSignature();
  const Template * otm = other->def_->templateSignature();

  if (tm->typeParams()->size() != otm->typeParams()->size()) {
    return false;
  }

  bool same = true;
  size_t numParams = tm->typeParams()->size();
  for (size_t i = 0; i < numParams; ++i) {
    QualifiedType param = tm->typeParam(i);
    QualifiedType oparam = otm->typeParam(i);

    if (!TypeRelation::isEqual(param, oparam)) {
      same = false;
      if (!TypeRelation::isSubtype(param, oparam)) {
        if (oparam->typeClass() != Type::TypeVar) {
          return false;
        }

        // TODO: CanBind check here...
      }
    }
  }

  if (same) {
    // TODO A temporary kludge.
    if (!def_->hasUnboundTypeParams() && other->def_->hasUnboundTypeParams()) {
      return true;
    }
  }

  return !same;
}