summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-12-05 07:07:03 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-12-05 07:07:03 +0000
commitb9a405b33e142533cef0defeb4840d8eaca91df8 (patch)
treedc41ca3c2a46b9bc02585b2adc39f293afef5406 /clang/lib/AST
parent7b4721048c08bcda241c5b1c97f8730b7b1301c0 (diff)
downloadbcm5719-llvm-b9a405b33e142533cef0defeb4840d8eaca91df8.tar.gz
bcm5719-llvm-b9a405b33e142533cef0defeb4840d8eaca91df8.zip
[objc] If an interface has no initializer marked as designated and introduces at least one new initializer,
don't assume that it inherits the designated initializers from the super class. If the assumption was wrong because a new initializer was a designated one that was not marked as such, we will emit misleading warnings for subclasses of the interface. llvm-svn: 196476
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/DeclObjC.cpp62
1 files changed, 48 insertions, 14 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 7fe73efc9eb..eaf34c1de1a 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -380,21 +380,61 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
}
-void ObjCInterfaceDecl::getDesignatedInitializers(
- llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
- assert(hasDefinition());
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
+const ObjCInterfaceDecl *
+ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
const ObjCInterfaceDecl *IFace = this;
while (IFace) {
- if (IFace->data().HasDesignatedInitializers)
+ if (IFace->hasDesignatedInitializers())
+ return IFace;
+ if (!IFace->inheritsDesignatedInitializers())
break;
IFace = IFace->getSuperClass();
}
+ return 0;
+}
+bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
+ switch (data().InheritedDesignatedInitializers) {
+ case DefinitionData::IDI_Inherited:
+ return true;
+ case DefinitionData::IDI_NotInherited:
+ return false;
+ case DefinitionData::IDI_Unknown: {
+ bool isIntroducingInitializers = false;
+ for (instmeth_iterator I = instmeth_begin(),
+ E = instmeth_end(); I != E; ++I) {
+ const ObjCMethodDecl *MD = *I;
+ if (MD->getMethodFamily() == OMF_init && !MD->isOverriding()) {
+ isIntroducingInitializers = true;
+ break;
+ }
+ }
+ // If the class introduced initializers we conservatively assume that we
+ // don't know if any of them is a designated initializer to avoid possible
+ // misleading warnings.
+ if (isIntroducingInitializers) {
+ data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
+ return false;
+ } else {
+ data().InheritedDesignatedInitializers = DefinitionData::IDI_Inherited;
+ return true;
+ }
+ }
+ }
+
+ llvm_unreachable("unexpected InheritedDesignatedInitializers value");
+}
+
+void ObjCInterfaceDecl::getDesignatedInitializers(
+ llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
+ assert(hasDefinition());
+ if (data().ExternallyCompleted)
+ LoadExternalDefinition();
+
+ const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
if (!IFace)
return;
+
for (instmeth_iterator I = IFace->instmeth_begin(),
E = IFace->instmeth_end(); I != E; ++I) {
const ObjCMethodDecl *MD = *I;
@@ -409,13 +449,7 @@ bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
if (data().ExternallyCompleted)
LoadExternalDefinition();
- const ObjCInterfaceDecl *IFace = this;
- while (IFace) {
- if (IFace->data().HasDesignatedInitializers)
- break;
- IFace = IFace->getSuperClass();
- }
-
+ const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
if (!IFace)
return false;
OpenPOWER on IntegriCloud