diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-08 01:46:34 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-08 01:46:34 +0000 |
commit | bab8a96f2f509218bc1a25d67bc182581d65e50e (patch) | |
tree | a994fe755cc4162606d8c860ed630e2d5b1d9aaf /clang/lib/Sema | |
parent | af3d4af4ebec2c519823a745665729ded3f9bbce (diff) | |
download | bcm5719-llvm-bab8a96f2f509218bc1a25d67bc182581d65e50e.tar.gz bcm5719-llvm-bab8a96f2f509218bc1a25d67bc182581d65e50e.zip |
Implement the Objective-C 'instancetype' type, which is an alias of
'id' that can be used (only!) via a contextual keyword as the result
type of an Objective-C message send. 'instancetype' then gives the
method a related result type, which we have already been inferring for
a variety of methods (new, alloc, init, self, retain). Addresses
<rdar://problem/9267640>.
llvm-svn: 139275
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 53 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 7 |
3 files changed, 47 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 3e657c70e6a..8dfdeb4b607 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -148,8 +148,13 @@ bool Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, << ResultTypeRange; } - Diag(Overridden->getLocation(), diag::note_related_result_type_overridden) - << Overridden->getMethodFamily(); + if (ObjCMethodFamily Family = Overridden->getMethodFamily()) + Diag(Overridden->getLocation(), + diag::note_related_result_type_overridden_family) + << Family; + else + Diag(Overridden->getLocation(), + diag::note_related_result_type_overridden); } return false; @@ -2261,16 +2266,22 @@ bool containsInvalidMethodImplAttribute(const AttrVec &A) { return false; } +namespace { + /// \brief Describes the compatibility of a result type with its method. + enum ResultTypeCompatibilityKind { + RTC_Compatible, + RTC_Incompatible, + RTC_Unknown + }; +} + /// \brief Check whether the declared result type of the given Objective-C /// method declaration is compatible with the method's class. /// -static bool +static ResultTypeCompatibilityKind CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, ObjCInterfaceDecl *CurrentClass) { QualType ResultType = Method->getResultType(); - SourceRange ResultTypeRange; - if (const TypeSourceInfo *ResultTypeInfo = Method->getResultTypeSourceInfo()) - ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange(); // If an Objective-C method inherits its related result type, then its // declared result type must be compatible with its own class type. The @@ -2280,23 +2291,27 @@ CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, // - it is id or qualified id, or if (ResultObjectType->isObjCIdType() || ResultObjectType->isObjCQualifiedIdType()) - return false; + return RTC_Compatible; if (CurrentClass) { if (ObjCInterfaceDecl *ResultClass = ResultObjectType->getInterfaceDecl()) { // - it is the same as the method's class type, or if (CurrentClass == ResultClass) - return false; + return RTC_Compatible; // - it is a superclass of the method's class type if (ResultClass->isSuperClassOf(CurrentClass)) - return false; + return RTC_Compatible; } + } else { + // Any Objective-C pointer type might be acceptable for a protocol + // method; we just don't know. + return RTC_Unknown; } } - return true; + return RTC_Incompatible; } namespace { @@ -2457,6 +2472,7 @@ Decl *Sema::ActOnMethodDeclaration( Decl *ClassDecl = cast<Decl>(OCD); QualType resultDeclType; + bool HasRelatedResultType = false; TypeSourceInfo *ResultTInfo = 0; if (ReturnType) { resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo); @@ -2468,6 +2484,8 @@ Decl *Sema::ActOnMethodDeclaration( << 0 << resultDeclType; return 0; } + + HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType()); } else { // get the type for "id". resultDeclType = Context.getObjCIdType(); Diag(MethodLoc, diag::warn_missing_method_return_type) @@ -2484,7 +2502,7 @@ Decl *Sema::ActOnMethodDeclaration( MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional : ObjCMethodDecl::Required, - false); + HasRelatedResultType); SmallVector<ParmVarDecl*, 16> Params; @@ -2604,9 +2622,8 @@ Decl *Sema::ActOnMethodDeclaration( CurrentClass = CatImpl->getClassInterface(); } - bool isRelatedResultTypeCompatible = - (getLangOptions().ObjCInferRelatedResultType && - !CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass)); + ResultTypeCompatibilityKind RTC + = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass); // Search for overridden methods and merge information down from them. OverrideSearch overrides(*this, ObjCMethod); @@ -2615,7 +2632,7 @@ Decl *Sema::ActOnMethodDeclaration( ObjCMethodDecl *overridden = *i; // Propagate down the 'related result type' bit from overridden methods. - if (isRelatedResultTypeCompatible && overridden->hasRelatedResultType()) + if (RTC != RTC_Incompatible && overridden->hasRelatedResultType()) ObjCMethod->SetRelatedResultType(); // Then merge the declarations. @@ -2633,8 +2650,10 @@ Decl *Sema::ActOnMethodDeclaration( if (getLangOptions().ObjCAutoRefCount) ARCError = CheckARCMethodDecl(*this, ObjCMethod); - if (!ARCError && isRelatedResultTypeCompatible && - !ObjCMethod->hasRelatedResultType()) { + // Infer the related result type when possible. + if (!ARCError && RTC == RTC_Compatible && + !ObjCMethod->hasRelatedResultType() && + LangOpts.ObjCInferRelatedResultType) { bool InferRelatedResultType = false; switch (ObjCMethod->getMethodFamily()) { case OMF_None: diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index aa9b4748a03..9f2696e1288 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -328,6 +328,10 @@ void Sema::EmitRelatedResultTypeNote(const Expr *E) { MsgSend->getType())) return; + if (!Context.hasSameUnqualifiedType(Method->getResultType(), + Context.getObjCInstanceType())) + return; + Diag(Method->getLocation(), diag::note_related_result_type_inferred) << Method->isInstanceMethod() << Method->getSelector() << MsgSend->getType(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index c89423037b4..e48704ca1df 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3053,6 +3053,13 @@ TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) { return CreateParsedType(T, TInfo); } +ParsedType Sema::ActOnObjCInstanceType(SourceLocation Loc) { + QualType T = Context.getObjCInstanceType(); + TypeSourceInfo *TInfo = Context.getTrivialTypeSourceInfo(T, Loc); + return CreateParsedType(T, TInfo); +} + + //===----------------------------------------------------------------------===// // Type Attribute Processing //===----------------------------------------------------------------------===// |