summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-26 20:47:02 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-26 20:47:02 +0000
commit9faee21f67f7e8afa8e191f6e1132e91c3eff512 (patch)
treeaf6a5cacc912f4673d1cbd73e413df6778a2e108 /clang
parent137d90c763200b85018e0cde4986d7306b8a15b0 (diff)
downloadbcm5719-llvm-9faee21f67f7e8afa8e191f6e1132e91c3eff512.tar.gz
bcm5719-llvm-9faee21f67f7e8afa8e191f6e1132e91c3eff512.zip
Implement template instantiation for ObjCPropertyRefExpr.
llvm-svn: 102379
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/ExprObjC.h5
-rw-r--r--clang/lib/Sema/TreeTransform.h49
-rw-r--r--clang/test/SemaObjCXX/instantiate-expr.mm27
3 files changed, 64 insertions, 17 deletions
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
index c62e91e31b3..406b905888d 100644
--- a/clang/include/clang/AST/ExprObjC.h
+++ b/clang/include/clang/AST/ExprObjC.h
@@ -233,8 +233,9 @@ private:
public:
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t, false, false), AsProperty(PD),
- IdLoc(l), Base(base) {
+ : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()),
+ AsProperty(PD), IdLoc(l), Base(base) {
}
explicit ObjCPropertyRefExpr(EmptyShell Empty)
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 695ff6e5242..946496ae12c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1829,7 +1829,37 @@ public:
R,
/*TemplateArgs=*/0);
}
-
+
+ /// \brief Build a new Objective-C property reference expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildObjCPropertyRefExpr(ExprArg BaseArg,
+ ObjCPropertyDecl *Property,
+ SourceLocation PropertyLoc) {
+ CXXScopeSpec SS;
+ Expr *Base = BaseArg.takeAs<Expr>();
+ LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
+ Sema::LookupMemberName);
+ bool IsArrow = false;
+ OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+ /*FIME:*/PropertyLoc,
+ SS, DeclPtrTy());
+ if (Result.isInvalid())
+ return getSema().ExprError();
+
+ if (Result.get())
+ return move(Result);
+
+ return getSema().BuildMemberReferenceExpr(getSema().Owned(Base),
+ Base->getType(),
+ /*FIXME:*/PropertyLoc, IsArrow,
+ SS,
+ /*FirstQualifierInScope=*/0,
+ R,
+ /*TemplateArgs=*/0);
+ }
+
/// \brief Build a new Objective-C "isa" expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -5866,9 +5896,20 @@ TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
template<typename Derived>
Sema::OwningExprResult
TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
- // FIXME: Implement this!
- assert(false && "Cannot transform Objective-C expressions yet");
- 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 property; it 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().RebuildObjCPropertyRefExpr(move(Base), E->getProperty(),
+ E->getLocation());
}
template<typename Derived>
diff --git a/clang/test/SemaObjCXX/instantiate-expr.mm b/clang/test/SemaObjCXX/instantiate-expr.mm
index 264ea634e87..c480ecfa887 100644
--- a/clang/test/SemaObjCXX/instantiate-expr.mm
+++ b/clang/test/SemaObjCXX/instantiate-expr.mm
@@ -4,36 +4,41 @@
@public
int ivar;
}
+@property int prop;
@end
typedef struct objc_object {
Class isa;
} *id;
-// Test instantiation of value-dependent ObjCIvarRefExpr and
-// ObjCIsaRefExpr nodes.
+// Test instantiation of value-dependent ObjCIvarRefExpr,
+// ObjCIsaRefExpr, and ObjCPropertyRefExpr nodes.
A *get_an_A(unsigned);
id get_an_id(unsigned);
-template<unsigned N, typename T, typename U>
-void f(U value) {
+template<unsigned N, typename T, typename U, typename V>
+void f(U value, V value2) {
get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+ get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}}
}
-template void f<6, Class>(int);
-template void f<7, Class>(int*); // expected-note{{in instantiation of}}
-template void f<8, int>(int); // expected-note{{in instantiation of}}
+template void f<6, Class>(int, int);
+template void f<7, Class>(int*, int); // expected-note{{in instantiation of}}
+template void f<8, Class>(int, double*); // expected-note{{in instantiation of}}
+template void f<9, int>(int, int); // expected-note{{in instantiation of}}
// Test instantiation of unresolved member reference expressions to an
// ivar reference.
-template<typename T, typename U>
-void f2(T ptr, U value) {
+template<typename T, typename U, typename V>
+void f2(T ptr, U value, V value2) {
ptr->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
+ ptr.prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
}
-template void f2(A*, int);
-template void f2(A*, int*); // expected-note{{instantiation of}}
+template void f2(A*, int, int);
+template void f2(A*, int*, int); // expected-note{{instantiation of}}
+template void f2(A*, int, double*); // expected-note{{instantiation of}}
// Test instantiation of unresolved member referfence expressions to
// an isa.
OpenPOWER on IntegriCloud