aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/NSAPI.cpp1
-rw-r--r--lib/Parse/ParseObjc.cpp1
-rw-r--r--lib/Sema/SemaDeclAttr.cpp19
-rw-r--r--lib/Sema/SemaDeclObjC.cpp31
4 files changed, 51 insertions, 1 deletions
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index 8f03711f4d..f5ea2c54ee 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -18,6 +18,7 @@ NSAPI::NSAPI(ASTContext &ctx)
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
static const char *ClassName[NumClassIds] = {
+ "NSObject",
"NSString",
"NSArray",
"NSMutableArray",
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index c664c64b67..11417fb66f 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -161,6 +161,7 @@ void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
/// __attribute__((deprecated))
/// __attribute__((unavailable))
/// __attribute__((objc_exception)) - used by NSException on 64-bit
+/// __attribute__((objc_root_class))
///
Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &attrs) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 081c93f8c2..77809e153f 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1593,6 +1593,22 @@ static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
Attr.getRange(), S.Context));
}
+static void handleObjCRootClassAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (!isa<ObjCInterfaceDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
+ return;
+ }
+
+ unsigned NumArgs = Attr.getNumArgs();
+ if (NumArgs > 0) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
+}
+
static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
if (!isa<ObjCInterfaceDecl>(D)) {
@@ -3658,6 +3674,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_objc_arc_weak_reference_unavailable:
handleArcWeakrefUnavailableAttr (S, D, Attr);
break;
+ case AttributeList::AT_objc_root_class:
+ handleObjCRootClassAttr(S, D, Attr);
+ break;
case AttributeList::AT_objc_requires_property_definitions:
handleObjCRequiresPropertyDefsAttr (S, D, Attr);
break;
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 6be9c7ceeb..a942d4979d 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -24,6 +24,7 @@
#include "clang/AST/ASTMutationListener.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Sema/DeclSpec.h"
+#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/DenseSet.h"
using namespace clang;
@@ -2371,11 +2372,39 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
AtomicPropertySetterGetterRules(IC, IDecl);
DiagnoseOwningPropertyGetterSynthesis(IC);
- if (LangOpts.ObjCNonFragileABI2)
+ bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
+ if (IDecl->getSuperClass() == NULL) {
+ // This class has no superclass, so check that it has been marked with
+ // __attribute((objc_root_class)).
+ if (!HasRootClassAttr) {
+ SourceLocation DeclLoc(IDecl->getLocation());
+ SourceLocation SuperClassLoc(PP.getLocForEndOfToken(DeclLoc));
+ Diag(DeclLoc, diag::warn_objc_root_class_missing)
+ << IDecl->getIdentifier();
+ // See if NSObject is in the current scope, and if it is, suggest
+ // adding " : NSObject " to the class declaration.
+ NamedDecl *IF = LookupSingleName(TUScope,
+ NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject),
+ DeclLoc, LookupOrdinaryName);
+ ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+ if (NSObjectDecl && NSObjectDecl->getDefinition()) {
+ Diag(SuperClassLoc, diag::note_objc_needs_superclass)
+ << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject ");
+ } else {
+ Diag(SuperClassLoc, diag::note_objc_needs_superclass);
+ }
+ }
+ } else if (HasRootClassAttr) {
+ // Complain that only root classes may have this attribute.
+ Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
+ }
+
+ if (LangOpts.ObjCNonFragileABI2) {
while (IDecl->getSuperClass()) {
DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
IDecl = IDecl->getSuperClass();
}
+ }
}
SetIvarInitializers(IC);
} else if (ObjCCategoryImplDecl* CatImplClass =