summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-22 16:44:27 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-22 16:44:27 +0000
commitc298ffcb8b48744b9af73f8319a5ceeccb3ea4de (patch)
treea4fe5d744488fcc65d053850a17b3b728c404217 /clang/lib/Sema/SemaExprObjC.cpp
parentf812506912d7432acde766d1ee93205843e5817c (diff)
downloadbcm5719-llvm-c298ffcb8b48744b9af73f8319a5ceeccb3ea4de.tar.gz
bcm5719-llvm-c298ffcb8b48744b9af73f8319a5ceeccb3ea4de.zip
Implement template instantiation for Objective-C++ message sends. We
support dependent receivers for class and instance messages, along with dependent message arguments (of course), and check as much as we can at template definition time. This commit also deals with a subtle aspect of template instantiation in Objective-C++, where the type 'T *' can morph from a dependent PointerType into a non-dependent ObjCObjectPointer type. llvm-svn: 102071
Diffstat (limited to 'clang/lib/Sema/SemaExprObjC.cpp')
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp41
1 files changed, 37 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index e6884bac333..71833f254c4 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -177,8 +177,12 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
QualType &ReturnType) {
if (!Method) {
// Apply default argument promotion as for (C99 6.5.2.2p6).
- for (unsigned i = 0; i != NumArgs; i++)
+ for (unsigned i = 0; i != NumArgs; i++) {
+ if (Args[i]->isTypeDependent())
+ continue;
+
DefaultArgumentPromotion(Args[i]);
+ }
unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
diag::warn_inst_method_not_found;
@@ -204,7 +208,12 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
bool IsError = false;
for (unsigned i = 0; i < NumNamedArgs; i++) {
+ // We can't do any type-checking on a type-dependent argument.
+ if (Args[i]->isTypeDependent())
+ continue;
+
Expr *argExpr = Args[i];
+
ParmVarDecl *Param = Method->param_begin()[i];
assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
@@ -226,8 +235,12 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
// Promote additional arguments to variadic methods.
if (Method->isVariadic()) {
- for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
+ for (unsigned i = NumNamedArgs; i < NumArgs; ++i) {
+ if (Args[i]->isTypeDependent())
+ continue;
+
IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
+ }
} else {
// Check for extra arguments to non-variadic methods.
if (NumArgs != NumNamedArgs) {
@@ -677,8 +690,16 @@ Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
SourceLocation SelectorLoc,
SourceLocation RBracLoc,
MultiExprArg ArgsIn) {
- assert(!ReceiverType->isDependentType() &&
- "Dependent class messages not yet implemented");
+ if (ReceiverType->isDependentType()) {
+ // If the receiver type is dependent, we can't type-check anything
+ // at this point. Build a dependent expression.
+ unsigned NumArgs = ArgsIn.size();
+ Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
+ assert(SuperLoc.isInvalid() && "Message to super with dependent type");
+ return Owned(ObjCMessageExpr::Create(Context, ReceiverType, LBracLoc,
+ ReceiverTypeInfo, Sel, /*Method=*/0,
+ Args, NumArgs, RBracLoc));
+ }
SourceLocation Loc = SuperLoc.isValid()? SuperLoc
: ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
@@ -802,6 +823,18 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
// and determine receiver type.
Expr *Receiver = ReceiverE.takeAs<Expr>();
if (Receiver) {
+ if (Receiver->isTypeDependent()) {
+ // If the receiver is type-dependent, we can't type-check anything
+ // at this point. Build a dependent expression.
+ unsigned NumArgs = ArgsIn.size();
+ Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
+ assert(SuperLoc.isInvalid() && "Message to super with dependent type");
+ return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy,
+ LBracLoc, Receiver, Sel,
+ /*Method=*/0, Args, NumArgs,
+ RBracLoc));
+ }
+
// If necessary, apply function/array conversion to the receiver.
// C99 6.7.5.3p[7,8].
DefaultFunctionArrayLvalueConversion(Receiver);
OpenPOWER on IntegriCloud