forked from OSchip/llvm-project
Implement template instantiation for ObjCPropertyRefExpr.
llvm-svn: 102379
This commit is contained in:
parent
137d90c763
commit
9faee21f67
|
@ -233,8 +233,9 @@ private:
|
||||||
public:
|
public:
|
||||||
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
|
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
|
||||||
SourceLocation l, Expr *base)
|
SourceLocation l, Expr *base)
|
||||||
: Expr(ObjCPropertyRefExprClass, t, false, false), AsProperty(PD),
|
: Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false,
|
||||||
IdLoc(l), Base(base) {
|
base->isValueDependent()),
|
||||||
|
AsProperty(PD), IdLoc(l), Base(base) {
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ObjCPropertyRefExpr(EmptyShell Empty)
|
explicit ObjCPropertyRefExpr(EmptyShell Empty)
|
||||||
|
|
|
@ -1830,6 +1830,36 @@ public:
|
||||||
/*TemplateArgs=*/0);
|
/*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.
|
/// \brief Build a new Objective-C "isa" expression.
|
||||||
///
|
///
|
||||||
/// By default, performs semantic analysis to build the new expression.
|
/// By default, performs semantic analysis to build the new expression.
|
||||||
|
@ -5866,9 +5896,20 @@ TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
Sema::OwningExprResult
|
Sema::OwningExprResult
|
||||||
TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
||||||
// FIXME: Implement this!
|
// Transform the base expression.
|
||||||
assert(false && "Cannot transform Objective-C expressions yet");
|
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 SemaRef.Owned(E->Retain());
|
||||||
|
|
||||||
|
return getDerived().RebuildObjCPropertyRefExpr(move(Base), E->getProperty(),
|
||||||
|
E->getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
|
|
|
@ -4,36 +4,41 @@
|
||||||
@public
|
@public
|
||||||
int ivar;
|
int ivar;
|
||||||
}
|
}
|
||||||
|
@property int prop;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef struct objc_object {
|
typedef struct objc_object {
|
||||||
Class isa;
|
Class isa;
|
||||||
} *id;
|
} *id;
|
||||||
|
|
||||||
// Test instantiation of value-dependent ObjCIvarRefExpr and
|
// Test instantiation of value-dependent ObjCIvarRefExpr,
|
||||||
// ObjCIsaRefExpr nodes.
|
// ObjCIsaRefExpr, and ObjCPropertyRefExpr nodes.
|
||||||
A *get_an_A(unsigned);
|
A *get_an_A(unsigned);
|
||||||
id get_an_id(unsigned);
|
id get_an_id(unsigned);
|
||||||
|
|
||||||
template<unsigned N, typename T, typename U>
|
template<unsigned N, typename T, typename U, typename V>
|
||||||
void f(U value) {
|
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)->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'}}
|
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<6, Class>(int, int);
|
||||||
template void f<7, Class>(int*); // expected-note{{in instantiation of}}
|
template void f<7, Class>(int*, int); // expected-note{{in instantiation of}}
|
||||||
template void f<8, 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
|
// Test instantiation of unresolved member reference expressions to an
|
||||||
// ivar reference.
|
// ivar reference.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U, typename V>
|
||||||
void f2(T ptr, U value) {
|
void f2(T ptr, U value, V value2) {
|
||||||
ptr->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
|
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, int);
|
||||||
template void f2(A*, int*); // expected-note{{instantiation of}}
|
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
|
// Test instantiation of unresolved member referfence expressions to
|
||||||
// an isa.
|
// an isa.
|
||||||
|
|
Loading…
Reference in New Issue