summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-09-08 01:46:34 +0000
committerDouglas Gregor <dgregor@apple.com>2011-09-08 01:46:34 +0000
commitbab8a96f2f509218bc1a25d67bc182581d65e50e (patch)
treea994fe755cc4162606d8c860ed630e2d5b1d9aaf /clang/lib/Sema
parentaf3d4af4ebec2c519823a745665729ded3f9bbce (diff)
downloadbcm5719-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.cpp53
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp4
-rw-r--r--clang/lib/Sema/SemaType.cpp7
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
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud