[analyzer] IvarInvalidation: correctly handle cases where only partial invalidators exist

 - If only partial invalidators exist and there are no full invalidators in @implementation, report every ivar that has
not been invalidated. (Previously, we reported the first Ivar in the list, which could actually have been invalidated
by a partial invalidator. The code assumed you cannot have only partial invalidators.)

- Do not report missing invalidation method declaration if a partial invalidation method declaration exists.

llvm-svn: 180170
diff --git a/clang/test/Analysis/objc_invalidation.m b/clang/test/Analysis/objc_invalidation.m
index a6f5ec3..6919fea 100644
--- a/clang/test/Analysis/objc_invalidation.m
+++ b/clang/test/Analysis/objc_invalidation.m
@@ -322,6 +322,47 @@
 #endif
 @end
 
+@interface SomeNotInvalidatedInPartial : SomeInvalidationImplementingObject {
+  SomeInvalidationImplementingObject *Ivar1;
+  SomeInvalidationImplementingObject *Ivar2;
+#if RUN_IVAR_INVALIDATION
+  // expected-warning@-2 {{Instance variable Ivar2 needs to be invalidated or set to nil}}
+#endif
+}
+-(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
+-(void)partialInvalidatorCallsPartial __attribute__((annotate("objc_instance_variable_invalidator_partial")));
+@end
+@implementation SomeNotInvalidatedInPartial {
+  SomeInvalidationImplementingObject *Ivar3;
+#if RUN_IVAR_INVALIDATION
+  // expected-warning@-2 {{Instance variable Ivar3 needs to be invalidated or set to nil}}
+#endif
+}
+-(void)partialInvalidator {
+  Ivar1 = 0;
+}
+-(void)partialInvalidatorCallsPartial {
+  [self partialInvalidator];
+}
+@end
+
+@interface OnlyPartialDeclsBase : NSObject
+-(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
+@end
+@implementation OnlyPartialDeclsBase
+-(void)partialInvalidator {}
+@end
+
+@interface OnlyPartialDecls : OnlyPartialDeclsBase {
+  SomeInvalidationImplementingObject *Ivar1;
+#if RUN_IVAR_INVALIDATION
+  // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for OnlyPartialDecls}}
+#endif
+}
+@end
+@implementation OnlyPartialDecls
+@end
+
 // False negative.
 @interface PartialCallsFull : SomeInvalidationImplementingObject {
   SomeInvalidationImplementingObject *Ivar1;