]> granicus.if.org Git - clang/commitdiff
Progress.
authorJohn McCall <rjmccall@apple.com>
Tue, 12 Oct 2010 02:09:17 +0000 (02:09 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 12 Oct 2010 02:09:17 +0000 (02:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116287 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/Type.cpp
lib/Sema/SemaExpr.cpp
test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
test/SemaCXX/alignof-sizeof-reference.cpp
test/SemaCXX/decltype-overloaded-functions.cpp

index c06b08dd8bedf6847fb827f6dde7206cbdeee24b..d003b6d5edaee6fbe1f95a5e873ebd109db50615 100644 (file)
@@ -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">;
index 11afea044691685b393214177d683a91c24eeb3a..d924135ac65d1a5fcd1f1f1e9ab6eee5102a0063 100644 (file)
@@ -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.
index ef01cced876f60f1d19e3deaa8da7498180f5b0d..36b88672b3926e10da74df854730aaf578181ff1 100644 (file)
@@ -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()) {
@@ -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);
   }
@@ -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");
@@ -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();
@@ -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();
 
@@ -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)
@@ -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;
@@ -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());
@@ -6861,9 +6887,16 @@ 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).
@@ -6871,16 +6904,17 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     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;
@@ -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();
@@ -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())
@@ -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;
@@ -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;
@@ -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();
   }
 
index eea2c33ffe1bdabc5cef77e3a2b5c71cbb14e99a..543a86d4e35155db2b3f93bb6d37fcc3619ce47d 100644 (file)
@@ -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}}
 
 }
index eb5465cc19bb08dd2ea9c9008aba7c9180bc50ee..9ec8f0c90e17d1f05c11aea4c916bef5a6e70fcf 100644 (file)
@@ -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}}
index 945129c26a4c86d76bb819f01dd2f091e9fb2529..761edfc6393a3550be90a18f0b944927114eb073 100644 (file)
@@ -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}}
 }
index f1b29b0864399407a0535b358d4e7cb17fa766af..c11a47ecdf048c6ca9073fd58ef9efc79c3ee540 100644 (file)
@@ -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); };