[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