ExprResult
Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
- ExprResult PResult = CheckPlaceholderExpr(E, OpLoc);
- if (PResult.isInvalid()) return ExprError();
- E = PResult.take();
-
// Verify that the operand is valid.
bool isInvalid = false;
if (E->isTypeDependent()) {
} else if (E->getBitField()) { // C99 6.5.3.4p1.
Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0;
isInvalid = true;
+ } else if (E->getType()->isPlaceholderType()) {
+ ExprResult PE = CheckPlaceholderExpr(E, OpLoc);
+ if (PE.isInvalid()) return ExprError();
+ return CreateSizeOfAlignOfExpr(PE.take(), OpLoc, isSizeOf, R);
} else {
isInvalid = CheckSizeOfAlignOfOperand(E->getType(), OpLoc, R, true);
}
if (V->getType()->isArithmeticType())
return V->getType();
+ // Test for placeholders.
+ ExprResult PR = CheckPlaceholderExpr(V, Loc);
+ if (PR.isInvalid()) return QualType();
+ if (PR.take() != V) {
+ V = PR.take();
+ return CheckRealImagOperand(V, Loc, isReal);
+ }
+
// Reject anything else.
Diag(Loc, diag::err_realimag_invalid_type) << V->getType()
<< (isReal ? "__real" : "__imag");
// C99 does not support ++/-- on complex types, we allow as an extension.
Diag(OpLoc, diag::ext_integer_increment_complex)
<< ResType << Op->getSourceRange();
+ } else if (ResType->isPlaceholderType()) {
+ ExprResult PR = CheckPlaceholderExpr(Op, OpLoc);
+ if (PR.isInvalid()) return QualType();
+ return CheckIncrementDecrementOperand(PR.take(), OpLoc, isInc, isPrefix);
} else {
Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement)
<< ResType << int(isInc) << Op->getSourceRange();
if (OrigOp->getType() == Context.OverloadTy)
return Context.OverloadTy;
+ ExprResult PR = CheckPlaceholderExpr(OrigOp, OpLoc);
+ if (PR.isInvalid()) return QualType();
+ OrigOp = PR.take();
+
// Make sure to ignore parentheses in subsequent checks
Expr *op = OrigOp->IgnoreParens();
else if (const ObjCObjectPointerType *OPT =
OpTy->getAs<ObjCObjectPointerType>())
Result = OPT->getPointeeType();
+ else {
+ ExprResult PR = CheckPlaceholderExpr(Op, OpLoc);
+ if (PR.isInvalid()) return QualType();
+ if (PR.take() != Op) return CheckIndirectionOperand(PR.take(), OpLoc);
+ }
if (Result.isNull()) {
Diag(OpLoc, diag::err_typecheck_indirection_requires_pointer)
}
ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
- unsigned OpcIn,
- Expr *Input) {
+ unsigned OpcIn,
+ Expr *Input) {
UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn);
QualType resultType;
Opc == UO_Plus &&
resultType->isPointerType())
break;
+ else if (resultType->isPlaceholderType()) {
+ ExprResult PR = CheckPlaceholderExpr(Input, OpLoc);
+ if (PR.isInvalid()) return ExprError();
+ return CreateBuiltinUnaryOp(OpLoc, OpcIn, PR.take());
+ }
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
// C99 does not support '~' for complex conjugation.
Diag(OpLoc, diag::ext_integer_complement_complex)
<< resultType << Input->getSourceRange();
- else if (!resultType->hasIntegerRepresentation())
+ else if (resultType->hasIntegerRepresentation())
+ break;
+ else if (resultType->isPlaceholderType()) {
+ ExprResult PR = CheckPlaceholderExpr(Input, OpLoc);
+ if (PR.isInvalid()) return ExprError();
+ return CreateBuiltinUnaryOp(OpLoc, OpcIn, PR.take());
+ } else {
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
+ }
break;
case UO_LNot: // logical negation
// Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
resultType = Input->getType();
if (resultType->isDependentType())
break;
- if (!resultType->isScalarType()) // C99 6.5.3.3p1
+ if (resultType->isScalarType()) { // C99 6.5.3.3p1
+ // ok, fallthrough
+ } else if (resultType->isPlaceholderType()) {
+ ExprResult PR = CheckPlaceholderExpr(Input, OpLoc);
+ if (PR.isInvalid()) return ExprError();
+ return CreateBuiltinUnaryOp(OpLoc, OpcIn, PR.take());
+ } else {
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
+ }
- // Do not accept &f if f is overloaded
- // i.e. void f(int); void f(char); bool b = &f;
- if (resultType == Context.OverloadTy &&
- PerformContextuallyConvertToBool(Input))
- return ExprError(); // Diagnostic is uttered above
-
// LNot always has type int. C99 6.5.3.3p5.
// In C++, it's bool. C++ 5.3.1p8
resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy;
}
ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
- TypeSourceInfo *TInfo,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RParenLoc) {
+ TypeSourceInfo *TInfo,
+ OffsetOfComponent *CompPtr,
+ unsigned NumComponents,
+ SourceLocation RParenLoc) {
QualType ArgTy = TInfo->getType();
bool Dependent = ArgTy->isDependentType();
SourceRange TypeRange = TInfo->getTypeLoc().getLocalSourceRange();
}
ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
- SourceLocation BuiltinLoc,
- SourceLocation TypeLoc,
- ParsedType argty,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RPLoc) {
-
+ SourceLocation BuiltinLoc,
+ SourceLocation TypeLoc,
+ ParsedType argty,
+ OffsetOfComponent *CompPtr,
+ unsigned NumComponents,
+ SourceLocation RPLoc) {
+
TypeSourceInfo *ArgTInfo;
QualType ArgTy = GetTypeFromParser(argty, &ArgTInfo);
if (ArgTy.isNull())
ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- ParsedType arg1,ParsedType arg2,
- SourceLocation RPLoc) {
+ ParsedType arg1, ParsedType arg2,
+ SourceLocation RPLoc) {
TypeSourceInfo *argTInfo1;
QualType argT1 = GetTypeFromParser(arg1, &argTInfo1);
TypeSourceInfo *argTInfo2;
ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
- Expr *CondExpr,
- Expr *LHSExpr, Expr *RHSExpr,
- SourceLocation RPLoc) {
+ Expr *CondExpr,
+ Expr *LHSExpr, Expr *RHSExpr,
+ SourceLocation RPLoc) {
assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
QualType resType;
return Owned(E);
}
- Diag(Loc, diag::err_cannot_determine_declared_type_of_overloaded_function)
- << E->getSourceRange();
+ Diag(Loc, diag::err_ovl_unresolvable) << E->getSourceRange();
return ExprError();
}