[cfe-commits] r102382 - in /cfe/trunk: include/clang/AST/ExprObjC.h lib/Sema/TreeTransform.h test/SemaObjCXX/instantiate-expr.mm
Douglas Gregor
dgregor at apple.com
Mon Apr 26 14:04:54 PDT 2010
Author: dgregor
Date: Mon Apr 26 16:04:54 2010
New Revision: 102382
URL: http://llvm.org/viewvc/llvm-project?rev=102382&view=rev
Log:
Implement template instantiation for implicit property references in
Objective-C++. This is the last bit of (non-blocks-related) template
instantiation logic for Objective-C++. Yay!
Modified:
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/SemaObjCXX/instantiate-expr.mm
Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=102382&r1=102381&r2=102382&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Mon Apr 26 16:04:54 2010
@@ -299,7 +299,8 @@
QualType t,
ObjCMethodDecl *setter,
SourceLocation l, Expr *base)
- : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false),
+ : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()),
Setter(setter), Getter(getter), MemberLoc(l), Base(base),
InterfaceDecl(0), ClassLoc(SourceLocation()) {
}
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=102382&r1=102381&r2=102382&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Apr 26 16:04:54 2010
@@ -1860,6 +1860,26 @@
/*TemplateArgs=*/0);
}
+ /// \brief Build a new Objective-C implicit setter/getter reference
+ /// expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildObjCImplicitSetterGetterRefExpr(
+ ObjCMethodDecl *Getter,
+ QualType T,
+ ObjCMethodDecl *Setter,
+ SourceLocation NameLoc,
+ ExprArg Base) {
+ // Since these expressions can only be value-dependent, we do not need to
+ // perform semantic analysis again.
+ return getSema().Owned(
+ new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
+ Setter,
+ NameLoc,
+ Base.takeAs<Expr>()));
+ }
+
/// \brief Build a new Objective-C "isa" expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -5916,9 +5936,30 @@
Sema::OwningExprResult
TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *E) {
- // FIXME: Implement this!
- assert(false && "Cannot transform Objective-C expressions yet");
- return SemaRef.Owned(E->Retain());
+ // If this implicit setter/getter refers to class methods, it cannot have any
+ // dependent parts. Just retain the existing declaration.
+ if (E->getInterfaceDecl())
+ return SemaRef.Owned(E->Retain());
+
+ // Transform the base expression.
+ OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ // We don't need to transform the getters/setters; they will never change.
+
+ // If nothing changed, just retain the existing expression.
+ if (!getDerived().AlwaysRebuild() &&
+ Base.get() == E->getBase())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildObjCImplicitSetterGetterRefExpr(
+ E->getGetterMethod(),
+ E->getType(),
+ E->getSetterMethod(),
+ E->getLocation(),
+ move(Base));
+
}
template<typename Derived>
Modified: cfe/trunk/test/SemaObjCXX/instantiate-expr.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/instantiate-expr.mm?rev=102382&r1=102381&r2=102382&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/instantiate-expr.mm (original)
+++ cfe/trunk/test/SemaObjCXX/instantiate-expr.mm Mon Apr 26 16:04:54 2010
@@ -49,3 +49,25 @@
template void f3<Class>(id);
template void f3<int>(id); // expected-note{{instantiation of}}
+
+// Implicit setter/getter
+ at interface B
+- (int)foo;
+- (void)setFoo:(int)value;
+ at end
+
+template<typename T>
+void f4(B *b, T value) {
+ b.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+}
+
+template void f4(B*, int);
+template void f4(B*, int*); // expected-note{{in instantiation of function template specialization 'f4<int *>' requested here}}
+
+template<typename T, typename U>
+void f5(T ptr, U value) {
+ ptr.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+}
+
+template void f5(B*, int);
+template void f5(B*, int*); // expected-note{{in instantiation of function template specialization 'f5<B *, int *>' requested here}}
More information about the cfe-commits
mailing list