diff options
author | Steve Naroff <snaroff@apple.com> | 2009-03-05 15:22:01 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-03-05 15:22:01 +0000 |
commit | 61d6852f67b4416bb96f1613c1aa589c8cbc17db (patch) | |
tree | 4bb51da35af40125e88087176d7f93ef77648803 | |
parent | 00470a1c4c44c5ed26bad9a38b4d3904b02d7a28 (diff) |
Fix <rdar://problem/6144382> [sema] gcc inconsistency w.r.t. forward protocol declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66161 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.def | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 25 | ||||
-rw-r--r-- | test/SemaObjC/protocol-forward-circular.m | 10 |
4 files changed, 43 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index 6f94d8e2ec..2d751ad8af 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -135,6 +135,8 @@ DIAG(warn_undef_interface, WARNING, "cannot find interface declaration for %0") DIAG(err_duplicate_protocol_def, ERROR, "duplicate protocol definition of %0") +DIAG(err_protocol_has_circular_dependency, ERROR, + "protocol has circular dependency") DIAG(err_undeclared_protocol, ERROR, "cannot find protocol declaration for %0") DIAG(warn_undef_protocolref, WARNING, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index de9b4cd013..d7d80638d1 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -25,6 +25,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" +#include "clang/AST/DeclObjC.h" #include <string> #include <vector> @@ -1678,6 +1679,11 @@ public: SourceLocation AtCompatibilityAliasLoc, IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation); + + void CheckForwardProtocolDeclarationForCircularDependency( + IdentifierInfo *PName, + SourceLocation &PLoc, SourceLocation PrevLoc, + const ObjCList<ObjCProtocolDecl> &PList); virtual DeclTy *ActOnStartProtocolInterface( SourceLocation AtProtoInterfaceLoc, diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 55b0d16e8c..d90f2adc77 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -215,6 +215,25 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc, return AliasDecl; } +void Sema::CheckForwardProtocolDeclarationForCircularDependency( + IdentifierInfo *PName, + SourceLocation &Ploc, SourceLocation PrevLoc, + const ObjCList<ObjCProtocolDecl> &PList) +{ + for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(), + E = PList.end(); I != E; ++I) { + + if (ObjCProtocolDecl *PDecl = ObjCProtocols[(*I)->getIdentifier()]) { + if (PDecl->getIdentifier() == PName) { + Diag(Ploc, diag::err_protocol_has_circular_dependency); + Diag(PrevLoc, diag::note_previous_definition); + } + CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc, + PDecl->getLocation(), PDecl->getReferencedProtocols()); + } + } +} + Sema::DeclTy * Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, @@ -236,6 +255,12 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, // FIXME: don't leak the objects passed in! return PDecl; } + ObjCList<ObjCProtocolDecl> PList; + PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); + CheckForwardProtocolDeclarationForCircularDependency( + ProtocolName, ProtocolLoc, PDecl->getLocation(), PList); + PList.Destroy(Context); + // Make sure the cached decl gets a valid start location. PDecl->setLocation(AtProtoInterfaceLoc); PDecl->setForwardDecl(false); diff --git a/test/SemaObjC/protocol-forward-circular.m b/test/SemaObjC/protocol-forward-circular.m new file mode 100644 index 0000000000..836d5b2350 --- /dev/null +++ b/test/SemaObjC/protocol-forward-circular.m @@ -0,0 +1,10 @@ +// RUN: clang -fsyntax-only -verify %s + +@protocol B; +@protocol C < B > // expected-warning{{cannot find protocol definition for 'B'}} // expected-note{{previous definition is here}} +@end +@protocol A < C > +@end +@protocol B < A > // expected-error{{protocol has circular dependency}} +@end + |