aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-01 19:29:29 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-01 19:29:29 +0000
commit5e2a1ff9f28d2eab256d2553e76a9c9d54693875 (patch)
tree9b6a413be6f25d57bd1e0737cb63227d337493e5 /lib/Sema
parent27b7ce6199bfd008ba8d10c8bd91d926e2274df3 (diff)
Move the data that corresponds to the definition of a protocol into a
separately-allocated DefinitionData structure. Introduce various functions that will help with the separation of declarations from definitions (isThisDeclarationADefinition(), hasDefinition(), getDefinition()). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaCodeComplete.cpp39
-rw-r--r--lib/Sema/SemaDeclObjC.cpp25
2 files changed, 39 insertions, 25 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 72cc37ccdd..6843ca7e6c 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -4554,13 +4554,16 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
// Visit the protocols of protocols.
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
- const ObjCList<ObjCProtocolDecl> &Protocols
- = Protocol->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end();
- I != E; ++I)
- AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
- CurContext, Selectors, AllowSameLength, Results, false);
+ if (Protocol->hasDefinition()) {
+ const ObjCList<ObjCProtocolDecl> &Protocols
+ = Protocol->getReferencedProtocols();
+ for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+ E = Protocols.end();
+ I != E; ++I)
+ AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
+ NumSelIdents, CurContext, Selectors, AllowSameLength,
+ Results, false);
+ }
}
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
@@ -5417,7 +5420,7 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
D != DEnd; ++D) {
// Record any protocols we find.
if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
- if (!OnlyForwardDeclarations || Proto->isForwardDecl())
+ if (!OnlyForwardDeclarations || !Proto->hasDefinition())
Results.AddResult(Result(Proto, 0), CurContext, 0, false);
// Record any forward-declared protocols we find.
@@ -5427,7 +5430,7 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
P = Forward->protocol_begin(),
PEnd = Forward->protocol_end();
P != PEnd; ++P)
- if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
+ if (!OnlyForwardDeclarations || !(*P)->hasDefinition())
Results.AddResult(Result(*P, 0), CurContext, 0, false);
}
}
@@ -5823,14 +5826,16 @@ static void FindImplementableMethods(ASTContext &Context,
}
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
- // Recurse into protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols
- = Protocol->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end();
- I != E; ++I)
- FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- KnownMethods, false);
+ if (Protocol->hasDefinition()) {
+ // Recurse into protocols.
+ const ObjCList<ObjCProtocolDecl> &Protocols
+ = Protocol->getReferencedProtocols();
+ for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+ E = Protocols.end();
+ I != E; ++I)
+ FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
+ KnownMethods, false);
+ }
}
// Add methods in this container. This operation occurs last because
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 168ccfc3f5..eb178612c8 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -545,6 +545,10 @@ bool Sema::CheckForwardProtocolDeclarationForCircularDependency(
Diag(PrevLoc, diag::note_previous_definition);
res = true;
}
+
+ if (!PDecl->hasDefinition())
+ continue;
+
if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
PDecl->getLocation(), PDecl->getReferencedProtocols()))
res = true;
@@ -568,18 +572,18 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolName, ProtocolLoc);
if (PDecl) {
// Protocol already seen. Better be a forward protocol declaration
- if (!PDecl->isForwardDecl()) {
+ if (ObjCProtocolDecl *Def = PDecl->getDefinition()) {
Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
- Diag(PDecl->getLocation(), diag::note_previous_definition);
+ Diag(Def->getLocation(), diag::note_previous_definition);
- // Create a new one; the other may be in a different DeclContex, (e.g.
- // this one may be in a LinkageSpecDecl while the other is not) which
- // will break invariants.
- // We will not add it to scope chains to ignore it as the warning says.
+ // Create a new protocol that is completely distinct from previous
+ // declarations, and do not make this protocol available for name lookup.
+ // That way, we'll end up completely ignoring the duplicate.
+ // FIXME: Can we turn this into an error?
PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
ProtocolLoc, AtProtoInterfaceLoc,
/*isForwardDecl=*/false);
-
+ PDecl->startDefinition();
} else {
ObjCList<ObjCProtocolDecl> PList;
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
@@ -600,7 +604,9 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
ProtocolLoc, AtProtoInterfaceLoc,
/*isForwardDecl=*/false);
PushOnScopeChains(PDecl, TUScope);
+ PDecl->startDefinition();
}
+
if (AttrList)
ProcessDeclAttributeList(TUScope, PDecl, AttrList);
if (!err && NumProtoRefs ) {
@@ -647,7 +653,7 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
// If this is a forward declaration and we are supposed to warn in this
// case, do it.
- if (WarnOnDeclarations && PDecl->isForwardDecl())
+ if (WarnOnDeclarations && !PDecl->hasDefinition())
Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
<< ProtocolId[i].first;
Protocols.push_back(PDecl);
@@ -2497,6 +2503,9 @@ private:
}
void searchFrom(ObjCProtocolDecl *protocol) {
+ if (!protocol->hasDefinition())
+ return;
+
// A method in a protocol declaration overrides declarations from
// referenced ("parent") protocols.
search(protocol->getReferencedProtocols());