[cfe-commits] r144605 - in /cfe/trunk: include/clang/AST/BuiltinTypes.def include/clang/AST/Type.h include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaPseudoObject.cpp lib/Sema/SemaTemplateDeduction.cpp test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp test/SemaObjCXX/properties.mm

John McCall rjmccall at apple.com
Mon Nov 14 17:35:18 PST 2011


Author: rjmccall
Date: Mon Nov 14 19:35:18 2011
New Revision: 144605

URL: http://llvm.org/viewvc/llvm-project?rev=144605&view=rev
Log:
Resolve placeholder expressions before trying to deduce
'auto'.  Introduce a convenience method to make this a bit
easier, and use it elsewhere.


Modified:
    cfe/trunk/include/clang/AST/BuiltinTypes.def
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaPseudoObject.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
    cfe/trunk/test/SemaObjCXX/properties.mm

Modified: cfe/trunk/include/clang/AST/BuiltinTypes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/BuiltinTypes.def?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/BuiltinTypes.def (original)
+++ cfe/trunk/include/clang/AST/BuiltinTypes.def Mon Nov 14 19:35:18 2011
@@ -170,6 +170,9 @@
 //   &x->foo      # only if might be a static member function
 //   &Class::foo  # when a pointer-to-member; sub-expr also has this type
 // OverloadExpr::find can be used to analyze the expression.
+//
+// Overload should be the first placeholder type, or else change
+// BuiltinType::isNonOverloadPlaceholderType()
 PLACEHOLDER_TYPE(Overload, OverloadTy)
 
 // The type of a bound C++ non-static member function.

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Nov 14 19:35:18 2011
@@ -1367,6 +1367,10 @@
   /// isSpecificPlaceholderType - Test for a specific placeholder type.
   bool isSpecificPlaceholderType(unsigned K) const;
 
+  /// isNonOverloadPlaceholderType - Test for a placeholder type
+  /// other than Overload;  see BuiltinType::isNonOverloadPlaceholderType.
+  bool isNonOverloadPlaceholderType() const;
+
   /// isIntegerType() does *not* include complex integers (a GCC extension).
   /// isComplexIntegerType() can be used to test for complex integers.
   bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
@@ -1725,6 +1729,19 @@
     return isPlaceholderTypeKind(getKind());
   }
 
+  /// Determines whether this type is a placeholder type other than
+  /// Overload.  Most placeholder types require only syntactic
+  /// information about their context in order to be resolved (e.g.
+  /// whether it is a call expression), which means they can (and
+  /// should) be resolved in an earlier "phase" of analysis.
+  /// Overload expressions sometimes pick up further information
+  /// from their context, like whether the context expects a
+  /// specific function-pointer type, and so frequently need
+  /// special treatment.
+  bool isNonOverloadPlaceholderType() const {
+    return getKind() > Overload;
+  }
+
   static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
   static bool classof(const BuiltinType *) { return true; }
 };
@@ -4710,6 +4727,12 @@
   return false;
 }
 
+inline bool Type::isNonOverloadPlaceholderType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+    return BT->isNonOverloadPlaceholderType();
+  return false;
+}
+
 /// \brief Determines whether this is a type for which one can define
 /// an overloaded operator.
 inline bool Type::isOverloadableType() const {

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Nov 14 19:35:18 2011
@@ -4624,7 +4624,7 @@
                           FunctionDecl *&Specialization,
                           sema::TemplateDeductionInfo &Info);
 
-  bool DeduceAutoType(TypeSourceInfo *AutoType, Expr *Initializer,
+  bool DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
                       TypeSourceInfo *&Result);
 
   FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Nov 14 19:35:18 2011
@@ -3976,10 +3976,7 @@
   // Immediately handle non-overload placeholders.  Overloads can be
   // resolved contextually, but everything else here can't.
   for (unsigned I = 0; I != NumInit; ++I) {
-    if (const BuiltinType *pty
-          = InitList[I]->getType()->getAsPlaceholderType()) {
-      if (pty->getKind() == BuiltinType::Overload) continue;
-
+    if (InitList[I]->getType()->isNonOverloadPlaceholderType()) {
       ExprResult result = CheckPlaceholderExpr(InitList[I]);
 
       // Ignore failures; dropping the entire initializer list because

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Nov 14 19:35:18 2011
@@ -3795,17 +3795,14 @@
   setSequenceKind(NormalSequence);
 
   for (unsigned I = 0; I != NumArgs; ++I)
-    if (const BuiltinType *PlaceholderTy
-          = Args[I]->getType()->getAsPlaceholderType()) {
+    if (Args[I]->getType()->isNonOverloadPlaceholderType()) {
       // FIXME: should we be doing this here?
-      if (PlaceholderTy->getKind() != BuiltinType::Overload) {
-        ExprResult result = S.CheckPlaceholderExpr(Args[I]);
-        if (result.isInvalid()) {
-          SetFailed(FK_PlaceholderType);
-          return;
-        }
-        Args[I] = result.take();
+      ExprResult result = S.CheckPlaceholderExpr(Args[I]);
+      if (result.isInvalid()) {
+        SetFailed(FK_PlaceholderType);
+        return;
       }
+      Args[I] = result.take();
     }
 
 

Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
+++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Mon Nov 14 19:35:18 2011
@@ -775,12 +775,10 @@
                                         VK_RValue, OK_Ordinary, opcLoc);
 
   // Filter out non-overload placeholder types in the RHS.
-  if (const BuiltinType *PTy = RHS->getType()->getAsPlaceholderType()) {
-    if (PTy->getKind() != BuiltinType::Overload) {
-      ExprResult result = CheckPlaceholderExpr(RHS);
-      if (result.isInvalid()) return ExprError();
-      RHS = result.take();
-    }
+  if (RHS->getType()->isNonOverloadPlaceholderType()) {
+    ExprResult result = CheckPlaceholderExpr(RHS);
+    if (result.isInvalid()) return ExprError();
+    RHS = result.take();
   }
 
   Expr *opaqueRef = LHS->IgnoreParens();

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Nov 14 19:35:18 2011
@@ -3342,8 +3342,14 @@
 ///
 /// \returns true if deduction succeeded, false if it failed.
 bool
-Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *Init,
+Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
                      TypeSourceInfo *&Result) {
+  if (Init->getType()->isNonOverloadPlaceholderType()) {
+    ExprResult result = CheckPlaceholderExpr(Init);
+    if (result.isInvalid()) return false;
+    Init = result.take();
+  }
+
   if (Init->isTypeDependent()) {
     Result = Type;
     return true;

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp Mon Nov 14 19:35:18 2011
@@ -92,7 +92,8 @@
   template<typename T> T g(T);
 
   void f(X *x) {
-    auto value = x->method; // expected-error{{variable 'value' with type 'auto' has incompatible initializer of type '<bound member function type>'}}
+    // FIXME: we should really only get the first diagnostic here.
+    auto value = x->method; // expected-error {{reference to non-static member function must be called}} expected-error{{variable 'value' with type 'auto' has incompatible initializer of type '<bound member function type>'}}
     if (value) { }
 
     auto funcptr = &g<int>;

Modified: cfe/trunk/test/SemaObjCXX/properties.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/properties.mm?rev=144605&r1=144604&r2=144605&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/properties.mm (original)
+++ cfe/trunk/test/SemaObjCXX/properties.mm Mon Nov 14 19:35:18 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
 struct X { 
   void f() const;
@@ -19,6 +19,15 @@
 - (void)setx:(const X&)other { x_ = other; }
 - (void)method {
   self.x.f();
-} 
+}
 @end
 
+// rdar://problem/10444030
+ at interface Test2
+- (void) setY: (int) y;
+- (int) z;
+ at end
+void test2(Test2 *a) {
+  auto y = a.y; // expected-error {{expected getter method not found on object of type 'Test2 *'}} expected-error {{variable 'y' with type 'auto' has incompatible initializer of type}}
+  auto z = a.z;
+}





More information about the cfe-commits mailing list