mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 19:49:36 +00:00
A bunch-o changes to fix <rdar://problem/5716046> incomplete implementation of ObjC class warning is incomplete
As part of this fix, I made a low-level change to the text diagnostics machinery (to basically avoid printing duplicate source lines/carets when you have multiple diagnostics that refer to the same exact place). For now, this only happens with we don't have a source range (could be extended to support source ranges as well). llvm-svn: 46897
This commit is contained in:
parent
f2bd1387b0
commit
a369922449
@ -159,7 +159,10 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags,
|
||||
|
||||
llvm::cerr << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";
|
||||
|
||||
if (!NoCaretDiagnostics && Pos.isValid()) {
|
||||
if (!NoCaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) && !Ranges)) {
|
||||
// Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
|
||||
LastLoc = Pos;
|
||||
|
||||
// Get the line of the source file.
|
||||
std::string SourceLine(LineStart, LineEnd);
|
||||
|
||||
|
@ -23,6 +23,7 @@ class SourceManager;
|
||||
|
||||
class TextDiagnosticPrinter : public TextDiagnostics {
|
||||
FullSourceLoc LastWarningLoc;
|
||||
FullSourceLoc LastLoc;
|
||||
public:
|
||||
TextDiagnosticPrinter() {}
|
||||
|
||||
|
@ -270,7 +270,8 @@ private:
|
||||
|
||||
/// CheckProtocolMethodDefs - This routine checks unimpletented methods
|
||||
/// Declared in protocol, and those referenced by it.
|
||||
void CheckProtocolMethodDefs(ObjCProtocolDecl *PDecl,
|
||||
void CheckProtocolMethodDefs(SourceLocation ImpLoc,
|
||||
ObjCProtocolDecl *PDecl,
|
||||
bool& IncompleteImpl,
|
||||
const llvm::DenseSet<Selector> &InsMap,
|
||||
const llvm::DenseSet<Selector> &ClsMap);
|
||||
|
@ -457,21 +457,25 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
|
||||
Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
|
||||
}
|
||||
|
||||
/// CheckProtocolMethodDefs - This routine checks unimpletented methods
|
||||
/// CheckProtocolMethodDefs - This routine checks unimplemented methods
|
||||
/// Declared in protocol, and those referenced by it.
|
||||
void Sema::CheckProtocolMethodDefs(ObjCProtocolDecl *PDecl,
|
||||
void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
|
||||
ObjCProtocolDecl *PDecl,
|
||||
bool& IncompleteImpl,
|
||||
const llvm::DenseSet<Selector> &InsMap,
|
||||
const llvm::DenseSet<Selector> &ClsMap) {
|
||||
const llvm::DenseSet<Selector> &InsMap,
|
||||
const llvm::DenseSet<Selector> &ClsMap) {
|
||||
// check unimplemented instance methods.
|
||||
for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
|
||||
E = PDecl->instmeth_end(); I != E; ++I) {
|
||||
ObjCMethodDecl *method = *I;
|
||||
if (!InsMap.count(method->getSelector()) &&
|
||||
method->getImplementationControl() != ObjCMethodDecl::Optional) {
|
||||
Diag(method->getLocation(), diag::warn_undef_method_impl,
|
||||
if (!IncompleteImpl) {
|
||||
Diag(ImpLoc, diag::warn_incomplete_impl);
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
Diag(ImpLoc, diag::warn_undef_method_impl,
|
||||
method->getSelector().getName());
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
}
|
||||
// check unimplemented class methods
|
||||
@ -480,15 +484,18 @@ void Sema::CheckProtocolMethodDefs(ObjCProtocolDecl *PDecl,
|
||||
ObjCMethodDecl *method = *I;
|
||||
if (!ClsMap.count(method->getSelector()) &&
|
||||
method->getImplementationControl() != ObjCMethodDecl::Optional) {
|
||||
Diag(method->getLocation(), diag::warn_undef_method_impl,
|
||||
if (!IncompleteImpl) {
|
||||
Diag(ImpLoc, diag::warn_incomplete_impl);
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
Diag(ImpLoc, diag::warn_undef_method_impl,
|
||||
method->getSelector().getName());
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
}
|
||||
// Check on this protocols's referenced protocols, recursively
|
||||
ObjCProtocolDecl** RefPDecl = PDecl->getReferencedProtocols();
|
||||
for (unsigned i = 0; i < PDecl->getNumReferencedProtocols(); i++)
|
||||
CheckProtocolMethodDefs(RefPDecl[i], IncompleteImpl, InsMap, ClsMap);
|
||||
CheckProtocolMethodDefs(ImpLoc, RefPDecl[i], IncompleteImpl, InsMap, ClsMap);
|
||||
}
|
||||
|
||||
void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
|
||||
@ -504,9 +511,12 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
|
||||
for (ObjCInterfaceDecl::instmeth_iterator I = IDecl->instmeth_begin(),
|
||||
E = IDecl->instmeth_end(); I != E; ++I)
|
||||
if (!InsMap.count((*I)->getSelector())) {
|
||||
Diag((*I)->getLocation(), diag::warn_undef_method_impl,
|
||||
if (!IncompleteImpl) {
|
||||
Diag(IMPDecl->getLocation(), diag::warn_incomplete_impl);
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
Diag(IMPDecl->getLocation(), diag::warn_undef_method_impl,
|
||||
(*I)->getSelector().getName());
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
|
||||
llvm::DenseSet<Selector> ClsMap;
|
||||
@ -519,20 +529,20 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
|
||||
for (ObjCInterfaceDecl::classmeth_iterator I = IDecl->classmeth_begin(),
|
||||
E = IDecl->classmeth_end(); I != E; ++I)
|
||||
if (!ClsMap.count((*I)->getSelector())) {
|
||||
Diag((*I)->getLocation(), diag::warn_undef_method_impl,
|
||||
if (!IncompleteImpl) {
|
||||
Diag(IMPDecl->getLocation(), diag::warn_incomplete_impl);
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
Diag(IMPDecl->getLocation(), diag::warn_undef_method_impl,
|
||||
(*I)->getSelector().getName());
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
|
||||
// Check the protocol list for unimplemented methods in the @implementation
|
||||
// class.
|
||||
ObjCProtocolDecl** protocols = IDecl->getReferencedProtocols();
|
||||
for (unsigned i = 0; i < IDecl->getNumIntfRefProtocols(); i++)
|
||||
CheckProtocolMethodDefs(protocols[i], IncompleteImpl, InsMap, ClsMap);
|
||||
|
||||
if (IncompleteImpl)
|
||||
Diag(IMPDecl->getLocation(), diag::warn_incomplete_impl_class,
|
||||
IMPDecl->getName());
|
||||
CheckProtocolMethodDefs(IMPDecl->getLocation(), protocols[i],
|
||||
IncompleteImpl, InsMap, ClsMap);
|
||||
}
|
||||
|
||||
/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
|
||||
@ -550,9 +560,12 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
|
||||
for (ObjCCategoryDecl::instmeth_iterator I = CatClassDecl->instmeth_begin(),
|
||||
E = CatClassDecl->instmeth_end(); I != E; ++I)
|
||||
if (!InsMap.count((*I)->getSelector())) {
|
||||
Diag((*I)->getLocation(), diag::warn_undef_method_impl,
|
||||
if (!IncompleteImpl) {
|
||||
Diag(CatImplDecl->getLocation(), diag::warn_incomplete_impl);
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
Diag(CatImplDecl->getLocation(), diag::warn_undef_method_impl,
|
||||
(*I)->getSelector().getName());
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
llvm::DenseSet<Selector> ClsMap;
|
||||
// Check and see if class methods in category interface have been
|
||||
@ -565,9 +578,12 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
|
||||
for (ObjCCategoryDecl::classmeth_iterator I = CatClassDecl->classmeth_begin(),
|
||||
E = CatClassDecl->classmeth_end(); I != E; ++I)
|
||||
if (!ClsMap.count((*I)->getSelector())) {
|
||||
Diag((*I)->getLocation(), diag::warn_undef_method_impl,
|
||||
if (!IncompleteImpl) {
|
||||
Diag(CatImplDecl->getLocation(), diag::warn_incomplete_impl);
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
Diag(CatImplDecl->getLocation(), diag::warn_undef_method_impl,
|
||||
(*I)->getSelector().getName());
|
||||
IncompleteImpl = true;
|
||||
}
|
||||
|
||||
// Check the protocol list for unimplemented methods in the @implementation
|
||||
@ -575,11 +591,9 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
|
||||
ObjCProtocolDecl** protocols = CatClassDecl->getReferencedProtocols();
|
||||
for (unsigned i = 0; i < CatClassDecl->getNumReferencedProtocols(); i++) {
|
||||
ObjCProtocolDecl* PDecl = protocols[i];
|
||||
CheckProtocolMethodDefs(PDecl, IncompleteImpl, InsMap, ClsMap);
|
||||
CheckProtocolMethodDefs(CatImplDecl->getLocation(), PDecl, IncompleteImpl,
|
||||
InsMap, ClsMap);
|
||||
}
|
||||
if (IncompleteImpl)
|
||||
Diag(CatImplDecl->getLocation(), diag::warn_incomplete_impl_category,
|
||||
CatClassDecl->getName());
|
||||
}
|
||||
|
||||
/// ActOnForwardClassDeclaration -
|
||||
|
@ -446,10 +446,8 @@ DIAG(err_conflicting_ivar_type, ERROR,
|
||||
"conflicting instance variable type")
|
||||
DIAG(warn_undef_method_impl, WARNING,
|
||||
"method definition for '%0' not found")
|
||||
DIAG(warn_incomplete_impl_class, WARNING,
|
||||
"incomplete implementation of class '%0'")
|
||||
DIAG(warn_incomplete_impl_category, WARNING,
|
||||
"incomplete implementation of category '%0'")
|
||||
DIAG(warn_incomplete_impl, WARNING,
|
||||
"incomplete implementation")
|
||||
DIAG(error_duplicate_method_decl, ERROR,
|
||||
"duplicate declaration of method '%0'")
|
||||
DIAG(err_previous_declaration, ERROR,
|
||||
|
@ -4,23 +4,27 @@
|
||||
@end
|
||||
|
||||
@protocol P
|
||||
- (void) Pmeth; // expected-warning {{method definition for 'Pmeth' not found}}
|
||||
- (void) Pmeth1; // expected-warning {{method definition for 'Pmeth1' not found}}
|
||||
- (void) Pmeth;
|
||||
- (void) Pmeth1;
|
||||
@end
|
||||
|
||||
@interface MyClass1(CAT) <P>
|
||||
- (void) meth2; // expected-warning {{method definition for 'meth2' not found}}
|
||||
- (void) meth2;
|
||||
@end
|
||||
|
||||
@implementation MyClass1(CAT) // expected-warning {{incomplete implementation of category 'CAT'}}
|
||||
@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \
|
||||
expected-warning {{method definition for 'meth2' not found}} \
|
||||
expected-warning {{method definition for 'Pmeth' not found}}
|
||||
- (void) Pmeth1{}
|
||||
@end
|
||||
|
||||
@interface MyClass1(DOG) <P>
|
||||
- (void)ppp; // expected-warning {{method definition for 'ppp' not found}}
|
||||
- (void)ppp;
|
||||
@end
|
||||
|
||||
@implementation MyClass1(DOG) // expected-warning {{incomplete implementation of category 'DOG'}}
|
||||
@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \
|
||||
expected-warning {{method definition for 'ppp' not found}} \
|
||||
expected-warning {{method definition for 'Pmeth1' not found}}
|
||||
- (void) Pmeth {}
|
||||
@end
|
||||
|
||||
|
@ -3,12 +3,12 @@
|
||||
@interface INTF
|
||||
- (void) meth;
|
||||
- (void) meth : (int) arg1;
|
||||
- (int) int_meth; // expected-warning {{method definition for 'int_meth' not found}}
|
||||
+ (int) cls_meth; // expected-warning {{method definition for 'cls_meth' not found}}
|
||||
+ (void) cls_meth1 : (int) arg1; // expected-warning {{method definition for 'cls_meth1:' not found}}
|
||||
- (int) int_meth;
|
||||
+ (int) cls_meth;
|
||||
+ (void) cls_meth1 : (int) arg1;
|
||||
@end
|
||||
|
||||
@implementation INTF // expected-warning {{incomplete implementation of class 'INTF'}}
|
||||
@implementation INTF // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}}
|
||||
- (void) meth {}
|
||||
- (void) meth : (int) arg2{}
|
||||
- (void) cls_meth1 : (int) arg2{}
|
||||
@ -17,12 +17,12 @@
|
||||
@interface INTF1
|
||||
- (void) meth;
|
||||
- (void) meth : (int) arg1;
|
||||
- (int) int_meth; // expected-warning {{method definition for 'int_meth' not found}}
|
||||
+ (int) cls_meth; // expected-warning {{method definition for 'cls_meth' not found}}
|
||||
+ (void) cls_meth1 : (int) arg1; // expected-warning {{method definition for 'cls_meth1:' not found}}
|
||||
- (int) int_meth;
|
||||
+ (int) cls_meth;
|
||||
+ (void) cls_meth1 : (int) arg1;
|
||||
@end
|
||||
|
||||
@implementation INTF1 // expected-warning {{incomplete implementation of class 'INTF1'}}
|
||||
@implementation INTF1 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}}
|
||||
- (void) meth {}
|
||||
- (void) meth : (int) arg2{}
|
||||
- (void) cls_meth1 : (int) arg2{}
|
||||
|
@ -1,31 +1,40 @@
|
||||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
@protocol P1
|
||||
- (void) P1proto; // expected-warning {{method definition for 'P1proto' not found}}
|
||||
+ (void) ClsP1Proto; // expected-warning {{method definition for 'ClsP1Proto' not found}}
|
||||
- (void) P1proto;
|
||||
+ (void) ClsP1Proto;
|
||||
- (void) DefP1proto;
|
||||
@end
|
||||
@protocol P2
|
||||
- (void) P2proto; // expected-warning {{method definition for 'P2proto' not found}}
|
||||
+ (void) ClsP2Proto; // expected-warning {{method definition for 'ClsP2Proto' not found}}
|
||||
- (void) P2proto;
|
||||
+ (void) ClsP2Proto;
|
||||
@end
|
||||
|
||||
@protocol P3<P2>
|
||||
- (void) P3proto; // expected-warning {{method definition for 'P3proto' not found}}
|
||||
+ (void) ClsP3Proto; // expected-warning {{method definition for 'ClsP3Proto' not found}}
|
||||
- (void) P3proto;
|
||||
+ (void) ClsP3Proto;
|
||||
+ (void) DefClsP3Proto;
|
||||
@end
|
||||
|
||||
@protocol PROTO<P1, P3>
|
||||
- (void) meth; // expected-warning {{method definition for 'meth' not found}}
|
||||
- (void) meth : (int) arg1; // expected-warning {{method definition for 'meth:' not found}}
|
||||
+ (void) cls_meth : (int) arg1; // expected-warning {{method definition for 'cls_meth:' not found}}
|
||||
- (void) meth;
|
||||
- (void) meth : (int) arg1;
|
||||
+ (void) cls_meth : (int) arg1;
|
||||
@end
|
||||
|
||||
@interface INTF <PROTO>
|
||||
@end
|
||||
|
||||
@implementation INTF // expected-warning {{incomplete implementation of class 'INTF'}}
|
||||
@implementation INTF // expected-warning {{incomplete implementation}} \
|
||||
expected-warning {{method definition for 'meth' not found}} \
|
||||
expected-warning {{method definition for 'meth:' not found}} \
|
||||
expected-warning {{method definition for 'cls_meth:' not found}} \
|
||||
expected-warning {{method definition for 'P3proto' not found}} \
|
||||
expected-warning {{method definition for 'ClsP3Proto' not found}} \
|
||||
expected-warning {{method definition for 'P2proto' not found}} \
|
||||
expected-warning {{method definition for 'ClsP2Proto' not found}} \
|
||||
expected-warning {{method definition for 'ClsP1Proto' not found}} \
|
||||
expected-warning {{method definition for 'P1proto' not found}}
|
||||
- (void) DefP1proto{}
|
||||
|
||||
+ (void) DefClsP3Proto{}
|
||||
|
Loading…
Reference in New Issue
Block a user