Skip to content

Commit 6b7f12c

Browse files
committed
Switch the initialization of Objective-C message parameters (as occurs
during message sends) over to the new initialization code and away from the C-only CheckSingleAssignmentConstraints. The enables the use of C++ types in method parameters and message arguments, as well as unifying more initialiation code overall. llvm-svn: 102035
1 parent 14b1d75 commit 6b7f12c

File tree

5 files changed

+41
-24
lines changed

5 files changed

+41
-24
lines changed

clang/lib/Sema/SemaExprObjC.cpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "Sema.h"
1515
#include "Lookup.h"
16+
#include "SemaInit.h"
1617
#include "clang/AST/ASTContext.h"
1718
#include "clang/AST/DeclObjC.h"
1819
#include "clang/AST/ExprObjC.h"
@@ -204,30 +205,23 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
204205
bool IsError = false;
205206
for (unsigned i = 0; i < NumNamedArgs; i++) {
206207
Expr *argExpr = Args[i];
208+
ParmVarDecl *Param = Method->param_begin()[i];
207209
assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
208210

209-
QualType lhsType = Method->param_begin()[i]->getType();
210-
QualType rhsType = argExpr->getType();
211-
212-
// If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
213-
if (lhsType->isArrayType())
214-
lhsType = Context.getArrayDecayedType(lhsType);
215-
else if (lhsType->isFunctionType())
216-
lhsType = Context.getPointerType(lhsType);
217-
218-
AssignConvertType Result =
219-
CheckSingleAssignmentConstraints(lhsType, argExpr);
220-
if (Result == Incompatible && !getLangOptions().CPlusPlus &&
221-
CheckTransparentUnionArgumentConstraints(lhsType, argExpr)
222-
== Sema::Compatible)
223-
Result = Compatible;
224-
225-
if (Args[i] != argExpr) // The expression was converted.
226-
Args[i] = argExpr; // Make sure we store the converted expression.
211+
if (RequireCompleteType(argExpr->getSourceRange().getBegin(),
212+
Param->getType(),
213+
PDiag(diag::err_call_incomplete_argument)
214+
<< argExpr->getSourceRange()))
215+
return true;
227216

228-
IsError |=
229-
DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
230-
argExpr, AA_Sending);
217+
InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
218+
OwningExprResult ArgE = PerformCopyInitialization(Entity,
219+
SourceLocation(),
220+
Owned(argExpr->Retain()));
221+
if (ArgE.isInvalid())
222+
IsError = true;
223+
else
224+
Args[i] = ArgE.takeAs<Expr>();
231225
}
232226

233227
// Promote additional arguments to variadic methods.

clang/lib/Sema/SemaInit.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3088,7 +3088,10 @@ getAssignmentAction(const InitializedEntity &Entity) {
30883088
return Sema::AA_Initializing;
30893089

30903090
case InitializedEntity::EK_Parameter:
3091-
// FIXME: Can we tell when we're sending vs. passing?
3091+
if (Entity.getDecl() &&
3092+
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
3093+
return Sema::AA_Sending;
3094+
30923095
return Sema::AA_Passing;
30933096

30943097
case InitializedEntity::EK_Result:

clang/lib/Sema/SemaInit.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,12 @@ class InitializedEntity {
142142
/// \brief Create the initialization entity for a parameter that is
143143
/// only known by its type.
144144
static InitializedEntity InitializeParameter(QualType Type) {
145-
return InitializedEntity(EK_Parameter, SourceLocation(), Type);
145+
InitializedEntity Entity;
146+
Entity.Kind = EK_Parameter;
147+
Entity.Type = Type;
148+
Entity.Parent = 0;
149+
Entity.VariableOrMember = 0;
150+
return Entity;
146151
}
147152

148153
/// \brief Create the initialization entity for the result of a function.

clang/test/SemaObjCXX/message.mm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,18 @@ + (int *)otherMethod {
7575
return [super method];
7676
}
7777
@end
78+
79+
struct String {
80+
String(const char *);
81+
};
82+
83+
struct MutableString : public String { };
84+
85+
// C++-specific parameter types
86+
@interface I5
87+
- method:(const String&)str1 other:(String&)str2;
88+
@end
89+
90+
void test_I5(I5 *i5, String s) {
91+
[i5 method:"hello" other:s];
92+
}

clang/test/SemaObjCXX/objc-pointer-conv.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ - (void) Meth : (I*) Arg;
3232
void Func (I* arg); // expected-note {{candidate function not viable: no known conversion from 'I const *' to 'I *' for 1st argument}}
3333

3434
void foo(const I *p, I* sel) {
35-
[sel Meth : p]; // expected-error {{sending 'I const *' to parameter of incompatible type 'I *'}}
35+
[sel Meth : p]; // expected-error {{cannot initialize a parameter of type 'I *' with an lvalue of type 'I const *'}}
3636
Func(p); // expected-error {{no matching function for call to 'Func'}}
3737
}
3838

0 commit comments

Comments
 (0)