Skip to content

Commit

Permalink
Progress.
Browse files Browse the repository at this point in the history
llvm-svn: 116287
  • Loading branch information
rjmccall committed Oct 12, 2010
1 parent 85e6da1 commit 3622662
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 38 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,9 @@ def err_ovl_no_viable_subscript :
Error<"no viable overloaded operator[] for type %0">;
def err_ovl_no_oper :
Error<"type %0 does not provide a %select{subscript|call}1 operator">;
def err_ovl_unresolvable :
Error<"cannot resolve overloaded function from context">;


def err_ovl_no_viable_object_call : Error<
"no matching function for call to object of type %0">;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ bool Type::isArithmeticType() const {

bool Type::isScalarType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() != BuiltinType::Void;
return BT->getKind() != BuiltinType::Void && !BT->isPlaceholderType();
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
// Enums are scalar types, but only if they are defined. Incomplete enums
// are not treated as scalar types.
Expand Down
97 changes: 65 additions & 32 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2214,10 +2214,6 @@ Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
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()) {
Expand All @@ -2227,6 +2223,10 @@ Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
} 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);
}
Expand Down Expand Up @@ -2274,6 +2274,14 @@ QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {
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");
Expand Down Expand Up @@ -6223,6 +6231,10 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
// 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();
Expand Down Expand Up @@ -6337,6 +6349,10 @@ QualType Sema::CheckAddressOfOperand(Expr *OrigOp, SourceLocation OpLoc) {
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();

Expand Down Expand Up @@ -6483,6 +6499,11 @@ QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
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)
Expand Down Expand Up @@ -6809,8 +6830,8 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
}

ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
unsigned OpcIn,
Expr *Input) {
unsigned OpcIn,
Expr *Input) {
UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn);

QualType resultType;
Expand Down Expand Up @@ -6848,6 +6869,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
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());
Expand All @@ -6861,26 +6887,34 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
// 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).
DefaultFunctionArrayLvalueConversion(Input);
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;
Expand Down Expand Up @@ -6980,10 +7014,10 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
}

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();
Expand Down Expand Up @@ -7136,13 +7170,13 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
}

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())
Expand All @@ -7157,8 +7191,8 @@ ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,


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;
Expand Down Expand Up @@ -7186,9 +7220,9 @@ Sema::BuildTypesCompatibleExpr(SourceLocation BuiltinLoc,


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;
Expand Down Expand Up @@ -8124,8 +8158,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E, SourceLocation Loc) {
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();
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ namespace PR8181
{
void f() { }
void f(char) { }
bool b = !&f; //expected-error {{value of type '<overloaded function type>' is not contextually convertible to 'bool'}}
bool b = !&f; //expected-error {{cannot resolve overloaded function from context}}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ template <typename T> void g(T);
template <typename T> void g(T, T);

int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \
// expected-error{{cannot determine the type of an overloaded function}}
// expected-error{{cannot resolve overloaded function from context}}
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/alignof-sizeof-reference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ void test() {
void f();
void f(int);
void g() {
sizeof(&f); // expected-error{{cannot determine the type of an overloaded function}}
sizeof(&f); // expected-error{{cannot resolve overloaded function from context}}
}
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/decltype-overloaded-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

void f();
void f(int);
decltype(f) a; // expected-error{{cannot determine the type of an overloaded function}}
decltype(f) a; // expected-error{{cannot resolve overloaded function from context}}

template<typename T> struct S {
decltype(T::f) * f; // expected-error{{cannot determine the type of an overloaded function}}
decltype(T::f) * f; // expected-error{{cannot resolve overloaded function from context}}
};

struct K { void f(); void f(int); };
Expand Down

0 comments on commit 3622662

Please sign in to comment.