diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-04-21 23:24:10 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-04-21 23:24:10 +0000 | 
| commit | 6b7f12c0396e18f51540c4901bb8ccbc35db1151 (patch) | |
| tree | 9224134beb04e1b481f52b802c9cd5fb6ba120df | |
| parent | 14b1d758c621145e26dc9476f0fa242b7c42930b (diff) | |
| download | bcm5719-llvm-6b7f12c0396e18f51540c4901bb8ccbc35db1151.tar.gz bcm5719-llvm-6b7f12c0396e18f51540c4901bb8ccbc35db1151.zip  | |
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
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 36 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.h | 7 | ||||
| -rw-r--r-- | clang/test/SemaObjCXX/message.mm | 15 | ||||
| -rw-r--r-- | clang/test/SemaObjCXX/objc-pointer-conv.mm | 2 | 
5 files changed, 41 insertions, 24 deletions
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 3af0cfc2c48..e6884bac333 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -13,6 +13,7 @@  #include "Sema.h"  #include "Lookup.h" +#include "SemaInit.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/DeclObjC.h"  #include "clang/AST/ExprObjC.h" @@ -204,30 +205,23 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,    bool IsError = false;    for (unsigned i = 0; i < NumNamedArgs; i++) {      Expr *argExpr = Args[i]; +    ParmVarDecl *Param = Method->param_begin()[i];      assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); -    QualType lhsType = Method->param_begin()[i]->getType(); -    QualType rhsType = argExpr->getType(); - -    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. -    if (lhsType->isArrayType()) -      lhsType = Context.getArrayDecayedType(lhsType); -    else if (lhsType->isFunctionType()) -      lhsType = Context.getPointerType(lhsType); - -    AssignConvertType Result = -      CheckSingleAssignmentConstraints(lhsType, argExpr); -    if (Result == Incompatible && !getLangOptions().CPlusPlus && -        CheckTransparentUnionArgumentConstraints(lhsType, argExpr) -        == Sema::Compatible) -      Result = Compatible; -         -    if (Args[i] != argExpr) // The expression was converted. -      Args[i] = argExpr; // Make sure we store the converted expression. +    if (RequireCompleteType(argExpr->getSourceRange().getBegin(), +                            Param->getType(), +                            PDiag(diag::err_call_incomplete_argument) +                              << argExpr->getSourceRange())) +      return true; -    IsError |= -      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, -                               argExpr, AA_Sending); +    InitializedEntity Entity = InitializedEntity::InitializeParameter(Param); +    OwningExprResult ArgE = PerformCopyInitialization(Entity, +                                                      SourceLocation(), +                                                      Owned(argExpr->Retain())); +    if (ArgE.isInvalid()) +      IsError = true; +    else +      Args[i] = ArgE.takeAs<Expr>();    }    // Promote additional arguments to variadic methods. diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index a015dd71042..6a9efbddbdf 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3088,7 +3088,10 @@ getAssignmentAction(const InitializedEntity &Entity) {      return Sema::AA_Initializing;    case InitializedEntity::EK_Parameter: -    // FIXME: Can we tell when we're sending vs. passing? +    if (Entity.getDecl() &&  +        isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext())) +      return Sema::AA_Sending; +      return Sema::AA_Passing;    case InitializedEntity::EK_Result: diff --git a/clang/lib/Sema/SemaInit.h b/clang/lib/Sema/SemaInit.h index bfbb0f4049c..ba11470d24a 100644 --- a/clang/lib/Sema/SemaInit.h +++ b/clang/lib/Sema/SemaInit.h @@ -142,7 +142,12 @@ public:    /// \brief Create the initialization entity for a parameter that is    /// only known by its type.    static InitializedEntity InitializeParameter(QualType Type) { -    return InitializedEntity(EK_Parameter, SourceLocation(), Type); +    InitializedEntity Entity; +    Entity.Kind = EK_Parameter; +    Entity.Type = Type; +    Entity.Parent = 0; +    Entity.VariableOrMember = 0; +    return Entity;    }    /// \brief Create the initialization entity for the result of a function. diff --git a/clang/test/SemaObjCXX/message.mm b/clang/test/SemaObjCXX/message.mm index 91b11f146cc..97ee499aff7 100644 --- a/clang/test/SemaObjCXX/message.mm +++ b/clang/test/SemaObjCXX/message.mm @@ -75,3 +75,18 @@ struct identity {    return [super method];  }  @end + +struct String { +  String(const char *); +}; + +struct MutableString : public String { }; + +// C++-specific parameter types +@interface I5 +- method:(const String&)str1 other:(String&)str2; +@end + +void test_I5(I5 *i5, String s) { +  [i5 method:"hello" other:s]; +} diff --git a/clang/test/SemaObjCXX/objc-pointer-conv.mm b/clang/test/SemaObjCXX/objc-pointer-conv.mm index 02ed58b0123..2504dcedb84 100644 --- a/clang/test/SemaObjCXX/objc-pointer-conv.mm +++ b/clang/test/SemaObjCXX/objc-pointer-conv.mm @@ -32,7 +32,7 @@ void RandomFunc(CFMDRef theDict, const void *key, const void *value);  void Func (I* arg);  // expected-note {{candidate function not viable: no known conversion from 'I const *' to 'I *' for 1st argument}}  void foo(const I *p, I* sel) { -  [sel Meth : p];	// expected-error {{sending 'I const *' to parameter of incompatible type 'I *'}} +  [sel Meth : p];	// expected-error {{cannot initialize a parameter of type 'I *' with an lvalue of type 'I const *'}}    Func(p);		// expected-error {{no matching function for call to 'Func'}}  }  | 

