summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-03-05 15:22:01 +0000
committerSteve Naroff <snaroff@apple.com>2009-03-05 15:22:01 +0000
commit41d09add4fd46ef680ca81c489bbd374620f82f2 (patch)
tree1c2e3d8213de001483a9ea0e19520cb6ecdebeba /clang/lib/Sema
parent96f52eb13fcab129e8d6daecfba295c2e55ccbb8 (diff)
downloadbcm5719-llvm-41d09add4fd46ef680ca81c489bbd374620f82f2.tar.gz
bcm5719-llvm-41d09add4fd46ef680ca81c489bbd374620f82f2.zip
Fix <rdar://problem/6144382> [sema] gcc inconsistency w.r.t. forward protocol declarations.
llvm-svn: 66161
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h6
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp25
2 files changed, 31 insertions, 0 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index de9b4cd013a..d7d80638d19 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/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/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 55b0d16e8c4..d90f2adc77a 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/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);
OpenPOWER on IntegriCloud