// FIXME: add support for derived types.
// FIXME: check default character kind.
bool Sema::CheckEquivalenceType(QualType ExpectedType, const Expr *E) {
  auto ObjectType = E->getType();
  if(ObjectType->isArrayType())
    ObjectType = ObjectType->asArrayType()->getElementType();

  if(ExpectedType->isCharacterType()) {
    if(!ObjectType->isCharacterType()) {
      Diags.Report(E->getLocation(),
                   diag::err_typecheck_expected_char_expr)
        << ObjectType << E->getSourceRange();
      return true;
    }
  } else if(ExpectedType->isBuiltinType()) {
    if(IsDefaultBuiltinOrDoublePrecisionType(ExpectedType)) {
      if(!IsDefaultBuiltinOrDoublePrecisionType(ObjectType)) {
        Diags.Report(E->getLocation(),
                     diag::err_typecheck_expected_default_kind_expr)
          << ObjectType << E->getSourceRange();
        return true;
      }
    } else {
      if(!AreTypesOfSameKind(ExpectedType, ObjectType)) {
        Diags.Report(E->getLocation(), diag::err_typecheck_expected_expr_of_type)
          << ExpectedType << ObjectType
          << E->getSourceRange();
        return true;
      }
    }
  }
  return false;
}
Exemplo n.º 2
0
void DataStmtEngine::VisitVarExpr(VarExpr *E) {
  if(CheckVar(E))
    return;
  auto VD = E->getVarDecl();
  auto Type = VD->getType();
  if(auto ATy = Type->asArrayType()) {
    uint64_t ArraySize;
    if(!ATy->EvaluateSize(ArraySize, Context)) {
      VisitExpr(E);
      return;
    }

    // Construct an array constructor expression for initializer
    SmallVector<Expr*, 32> Items(ArraySize);
    bool IsUsable = true;
    SourceLocation Loc;
    auto ElementType = ATy->getElementType();
    for(uint64_t I = 0; I < ArraySize; ++I) {
      if(!HasValues(E)) return;
      auto Val = getAndCheckAnyValue(ElementType, E);
      if(Val.isUsable()) {
        Items[I] = Val.get();
        if(!Loc.isValid())
          Loc = Val.get()->getLocation();
      }
      else IsUsable = false;
    }

    if(IsUsable) {
      VD->setInit(ArrayConstructorExpr::Create(Context, Loc,
                                               Items, Type));
    }
    return;
  }

  // single item
  auto Val = getAndCheckAnyValue(Type, E);
  if(Val.isUsable())
    VD->setInit(Val.get());
}