diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:18:08 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:18:08 +0000 |
commit | bab175ec4b075c8076ba14c762900392533f6ee4 (patch) | |
tree | 01f4f29419a2cb10abe13c1e63cd2a66068b0137 /lib/Sema/SemaDeclObjC.cpp | |
parent | 8b7a8012d223fac5d17d16a66bb39168a9a1dfc0 (diff) |
Notes
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 738de77cecb7b..d172c951e7494 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -11,22 +11,22 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaInternal.h" +#include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaInternal.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "TypeLocBuilder.h" using namespace clang; @@ -209,11 +209,11 @@ bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) { if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) { SourceRange ResultTypeRange = method->getReturnTypeSourceRange(); if (ResultTypeRange.isInvalid()) - Diag(method->getLocation(), diag::error_dealloc_bad_result_type) + Diag(method->getLocation(), diag::err_dealloc_bad_result_type) << method->getReturnType() << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)"); else - Diag(method->getLocation(), diag::error_dealloc_bad_result_type) + Diag(method->getLocation(), diag::err_dealloc_bad_result_type) << method->getReturnType() << FixItHint::CreateReplacement(ResultTypeRange, "void"); return true; @@ -1028,6 +1028,7 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc, /// typedef'ed use for a qualified super class and adds them to the list /// of the protocols. void Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, + SmallVectorImpl<SourceLocation> &ProtocolLocs, IdentifierInfo *SuperName, SourceLocation SuperLoc) { if (!SuperName) @@ -1040,8 +1041,14 @@ void Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) { QualType T = TDecl->getUnderlyingType(); if (T->isObjCObjectType()) - if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>()) + if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>()) { ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end()); + // FIXME: Consider whether this should be an invalid loc since the loc + // is not actually pointing to a protocol name reference but to the + // typedef reference. Note that the base class name loc is also pointing + // at the typedef. + ProtocolLocs.append(OPT->getNumProtocols(), SuperLoc); + } } } @@ -2353,7 +2360,7 @@ static bool CheckMethodOverrideParam(Sema &S, } if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy)) return true; - + if (!Warn) return false; unsigned DiagID = @@ -2741,7 +2748,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, } else { ObjCMethodDecl *ImpMethodDecl = IMPDecl->getInstanceMethod(I->getSelector()); - assert(CDecl->getInstanceMethod(I->getSelector()) && + assert(CDecl->getInstanceMethod(I->getSelector(), true/*AllowHidden*/) && "Expected to find the method through lookup as well"); // ImpMethodDecl may be null as in a @dynamic property. if (ImpMethodDecl) { @@ -2767,7 +2774,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, } else { ObjCMethodDecl *ImpMethodDecl = IMPDecl->getClassMethod(I->getSelector()); - assert(CDecl->getClassMethod(I->getSelector()) && + assert(CDecl->getClassMethod(I->getSelector(), true/*AllowHidden*/) && "Expected to find the method through lookup as well"); // ImpMethodDecl may be null as in a @dynamic property. if (ImpMethodDecl) { @@ -3217,7 +3224,7 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodList *ListWithSameDeclaration = nullptr; for (; List; Previous = List, List = List->getNext()) { // If we are building a module, keep all of the methods. - if (getLangOpts().CompilingModule) + if (getLangOpts().isCompilingModule()) continue; bool SameDeclaration = MatchTwoMethodDeclarations(Method, @@ -3853,6 +3860,18 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass); } + if (const ObjCInterfaceDecl *Super = IDecl->getSuperClass()) { + // An interface can subclass another interface with a + // objc_subclassing_restricted attribute when it has that attribute as + // well (because of interfaces imported from Swift). Therefore we have + // to check if we can subclass in the implementation as well. + if (IDecl->hasAttr<ObjCSubclassingRestrictedAttr>() && + Super->hasAttr<ObjCSubclassingRestrictedAttr>()) { + Diag(IC->getLocation(), diag::err_restricted_superclass_mismatch); + Diag(Super->getLocation(), diag::note_class_declared); + } + } + if (LangOpts.ObjCRuntime.isNonFragile()) { while (IDecl->getSuperClass()) { DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass()); @@ -3873,6 +3892,14 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, ImplMethodsVsClassMethods(S, CatImplClass, Cat); } } + } else if (const auto *IntfDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { + if (const ObjCInterfaceDecl *Super = IntfDecl->getSuperClass()) { + if (!IntfDecl->hasAttr<ObjCSubclassingRestrictedAttr>() && + Super->hasAttr<ObjCSubclassingRestrictedAttr>()) { + Diag(IntfDecl->getLocation(), diag::err_restricted_superclass_mismatch); + Diag(Super->getLocation(), diag::note_class_declared); + } + } } if (isInterfaceDeclKind) { // Reject invalid vardecls. @@ -4290,7 +4317,7 @@ Decl *Sema::ActOnMethodDeclaration( bool isVariadic, bool MethodDefinition) { // Make sure we can establish a context for the method. if (!CurContext->isObjCContainer()) { - Diag(MethodLoc, diag::error_missing_method_context); + Diag(MethodLoc, diag::err_missing_method_context); return nullptr; } ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); |