[cfe-commits] r147412 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Sema/Sema.h lib/AST/ASTImporter.cpp lib/AST/DeclObjC.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaLookup.cpp lib/Serialization/ASTReaderDecl.cpp test/Modules/Inputs/redecl-merge-bottom.h test/Modules/Inputs/redecl-merge-left.h test/Modules/Inputs/redecl-merge-right.h test/Modules/Inputs/redecl-merge-top.h test/Modules/redecl-merge.m
Douglas Gregor
dgregor at apple.com
Sun Jan 1 12:30:41 PST 2012
Author: dgregor
Date: Sun Jan 1 14:30:41 2012
New Revision: 147412
URL: http://llvm.org/viewvc/llvm-project?rev=147412&view=rev
Log:
Wire up redeclaration chains for Objective-C protocols, so that both
forward declarations and definitions of an Objective-C protocol are
represented within a single chain of ObjCProtocolDecls.
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/test/Modules/Inputs/redecl-merge-bottom.h
cfe/trunk/test/Modules/Inputs/redecl-merge-left.h
cfe/trunk/test/Modules/Inputs/redecl-merge-right.h
cfe/trunk/test/Modules/Inputs/redecl-merge-top.h
cfe/trunk/test/Modules/redecl-merge.m
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sun Jan 1 14:30:41 2012
@@ -1089,12 +1089,8 @@
ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc,
- bool isForwardDecl)
- : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
- Data(0),
- InitiallyForwardDecl(isForwardDecl),
- isForwardProtoDecl(isForwardDecl) {
- }
+ ObjCProtocolDecl *PrevDecl,
+ bool isForwardDecl);
void allocateDefinitionData();
@@ -1108,6 +1104,7 @@
IdentifierInfo *Id,
SourceLocation nameLoc,
SourceLocation atStartLoc,
+ ObjCProtocolDecl *PrevDecl,
bool isForwardDecl);
const ObjCProtocolList &getReferencedProtocols() const {
@@ -1194,8 +1191,6 @@
/// false when we see the definition, but this will remain true.
bool isInitiallyForwardDecl() const { return InitiallyForwardDecl; }
- void completedForwardDecl();
-
// Location information, modeled after the Stmt API.
SourceLocation getLocStart() const { return getAtStartLoc(); } // '@'protocol
SourceLocation getLocEnd() const { return EndLoc; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Jan 1 14:30:41 2012
@@ -1327,10 +1327,11 @@
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
TypeSourceInfo *TInfo);
bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
+ void mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation = true);
void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
- void mergeObjCMethodDecls(ObjCMethodDecl *New, const ObjCMethodDecl *Old);
+ void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
@@ -1755,7 +1756,9 @@
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
bool AllowBuiltinCreation = false,
bool EnteringContext = false);
- ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc);
+ ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc,
+ RedeclarationKind Redecl
+ = NotForRedeclaration);
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Jan 1 14:30:41 2012
@@ -3124,11 +3124,10 @@
ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
Name.getAsIdentifierInfo(), Loc,
Importer.Import(D->getAtStartLoc()),
+ /*PrevDecl=*/0,
D->isInitiallyForwardDecl());
ToProto->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToProto);
- if (D->isInitiallyForwardDecl() && D->hasDefinition())
- ToProto->completedForwardDecl();
}
if (!ToProto->hasDefinition())
ToProto->startDefinition();
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Sun Jan 1 14:30:41 2012
@@ -967,12 +967,32 @@
void ObjCProtocolDecl::anchor() { }
+ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
+ SourceLocation nameLoc,
+ SourceLocation atStartLoc,
+ ObjCProtocolDecl *PrevDecl,
+ bool isForwardDecl)
+ : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
+ Data(0),
+ InitiallyForwardDecl(isForwardDecl),
+ isForwardProtoDecl(isForwardDecl)
+{
+ setPreviousDeclaration(PrevDecl);
+ if (PrevDecl)
+ Data = PrevDecl->Data;
+}
+
ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
SourceLocation nameLoc,
SourceLocation atStartLoc,
+ ObjCProtocolDecl *PrevDecl,
bool isForwardDecl) {
- return new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, isForwardDecl);
+ ObjCProtocolDecl *Result
+ = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl,
+ isForwardDecl);
+
+ return Result;
}
ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
@@ -1016,12 +1036,7 @@
for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
RD != RDEnd; ++RD)
RD->Data = this->Data;
-}
-
-void ObjCProtocolDecl::completedForwardDecl() {
- assert(!hasDefinition() && "Only valid to call for forward refs");
- isForwardProtoDecl = false;
- startDefinition();
+
if (ASTMutationListener *L = getASTContext().getASTMutationListener())
L->CompletedObjCForwardRef(this);
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Jan 1 14:30:41 2012
@@ -1540,36 +1540,37 @@
}
/// mergeDeclAttributes - Copy attributes from the Old decl to the New one.
-static void mergeDeclAttributes(Decl *newDecl, const Decl *oldDecl,
- ASTContext &C, bool mergeDeprecation = true) {
- if (!oldDecl->hasAttrs())
+void Sema::mergeDeclAttributes(Decl *New, Decl *Old,
+ bool MergeDeprecation) {
+ if (!Old->hasAttrs())
return;
- bool foundAny = newDecl->hasAttrs();
+ bool foundAny = New->hasAttrs();
// Ensure that any moving of objects within the allocated map is done before
// we process them.
- if (!foundAny) newDecl->setAttrs(AttrVec());
+ if (!foundAny) New->setAttrs(AttrVec());
for (specific_attr_iterator<InheritableAttr>
- i = oldDecl->specific_attr_begin<InheritableAttr>(),
- e = oldDecl->specific_attr_end<InheritableAttr>(); i != e; ++i) {
+ i = Old->specific_attr_begin<InheritableAttr>(),
+ e = Old->specific_attr_end<InheritableAttr>();
+ i != e; ++i) {
// Ignore deprecated/unavailable/availability attributes if requested.
- if (!mergeDeprecation &&
+ if (!MergeDeprecation &&
(isa<DeprecatedAttr>(*i) ||
isa<UnavailableAttr>(*i) ||
isa<AvailabilityAttr>(*i)))
continue;
- if (!DeclHasAttr(newDecl, *i)) {
- InheritableAttr *newAttr = cast<InheritableAttr>((*i)->clone(C));
+ if (!DeclHasAttr(New, *i)) {
+ InheritableAttr *newAttr = cast<InheritableAttr>((*i)->clone(Context));
newAttr->setInherited(true);
- newDecl->addAttr(newAttr);
+ New->addAttr(newAttr);
foundAny = true;
}
}
- if (!foundAny) newDecl->dropAttrs();
+ if (!foundAny) New->dropAttrs();
}
/// mergeParamDeclAttributes - Copy attributes from the old parameter
@@ -2035,7 +2036,7 @@
/// \returns false
bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
// Merge the attributes
- mergeDeclAttributes(New, Old, Context);
+ mergeDeclAttributes(New, Old);
// Merge the storage class.
if (Old->getStorageClass() != SC_Extern &&
@@ -2061,13 +2062,13 @@
void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
- const ObjCMethodDecl *oldMethod) {
+ ObjCMethodDecl *oldMethod) {
// We don't want to merge unavailable and deprecated attributes
// except from interface to implementation.
bool mergeDeprecation = isa<ObjCImplDecl>(newMethod->getDeclContext());
// Merge the attributes.
- mergeDeclAttributes(newMethod, oldMethod, Context, mergeDeprecation);
+ mergeDeclAttributes(newMethod, oldMethod, mergeDeprecation);
// Merge attributes from the parameters.
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin();
@@ -2174,7 +2175,7 @@
New->setInvalidDecl();
}
- mergeDeclAttributes(New, Old, Context);
+ mergeDeclAttributes(New, Old);
// Warn if an already-declared variable is made a weak_import in a subsequent
// declaration
if (New->getAttr<WeakImportAttr>() &&
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Sun Jan 1 14:30:41 2012
@@ -569,46 +569,50 @@
bool err = false;
// FIXME: Deal with AttrList.
assert(ProtocolName && "Missing protocol identifier");
- ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolName, ProtocolLoc);
- if (PDecl) {
- // Protocol already seen. Better be a forward protocol declaration
- if (ObjCProtocolDecl *Def = PDecl->getDefinition()) {
- Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
- Diag(Def->getLocation(), diag::note_previous_definition);
-
- // 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 {
+ ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
+ ForRedeclaration);
+ ObjCProtocolDecl *PDecl = 0;
+ if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : 0) {
+ // If we already have a definition, complain.
+ Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
+ Diag(Def->getLocation(), diag::note_previous_definition);
+
+ // 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,
+ /*PrevDecl=*/0,
+ /*isForwardDecl=*/false);
+ PDecl->startDefinition();
+ } else {
+ if (PrevDecl) {
+ // Check for circular dependencies among protocol declarations. This can
+ // only happen if this protocol was forward-declared.
ObjCList<ObjCProtocolDecl> PList;
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
err = CheckForwardProtocolDeclarationForCircularDependency(
- ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
-
- // Make sure the cached decl gets a valid start location.
- PDecl->setAtStartLoc(AtProtoInterfaceLoc);
- PDecl->setLocation(ProtocolLoc);
- // Since this ObjCProtocolDecl was created by a forward declaration,
- // we now add it to the DeclContext since it wasn't added before
- PDecl->setLexicalDeclContext(CurContext);
- CurContext->addDecl(PDecl);
- PDecl->completedForwardDecl();
+ ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
}
- } else {
+
+ // Create the new declaration.
PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
ProtocolLoc, AtProtoInterfaceLoc,
+ /*PrevDecl=*/PrevDecl,
/*isForwardDecl=*/false);
+
PushOnScopeChains(PDecl, TUScope);
PDecl->startDefinition();
}
if (AttrList)
ProcessDeclAttributeList(TUScope, PDecl, AttrList);
+
+ // Merge attributes from previous declarations.
+ if (PrevDecl)
+ mergeDeclAttributes(PDecl, PrevDecl);
+
if (!err && NumProtoRefs ) {
/// Check then save referenced protocols.
PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
@@ -700,22 +704,26 @@
for (unsigned i = 0; i != NumElts; ++i) {
IdentifierInfo *Ident = IdentList[i].first;
- ObjCProtocolDecl *PDecl = LookupProtocol(Ident, IdentList[i].second);
- bool isNew = false;
- if (PDecl == 0) { // Not already seen?
- PDecl = ObjCProtocolDecl::Create(Context, CurContext, Ident,
- IdentList[i].second, AtProtocolLoc,
- /*isForwardDecl=*/true);
- PushOnScopeChains(PDecl, TUScope, false);
- isNew = true;
- }
+ ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentList[i].second,
+ ForRedeclaration);
+ ObjCProtocolDecl *PDecl
+ = ObjCProtocolDecl::Create(Context, CurContext, Ident,
+ IdentList[i].second, AtProtocolLoc,
+ PrevDecl, /*isForwardDecl=*/true);
+
+ PushOnScopeChains(PDecl, TUScope);
+
if (attrList) {
ProcessDeclAttributeList(TUScope, PDecl, attrList);
- if (!isNew) {
+ if (PrevDecl) {
if (ASTMutationListener *L = Context.getASTMutationListener())
L->UpdatedAttributeList(PDecl);
}
}
+
+ if (PrevDecl)
+ mergeDeclAttributes(PDecl, PrevDecl);
+
Protocols.push_back(PDecl);
ProtoLocs.push_back(IdentList[i].second);
}
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sun Jan 1 14:30:41 2012
@@ -2180,9 +2180,10 @@
/// \brief Find the protocol with the given name, if any.
ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II,
- SourceLocation IdLoc) {
+ SourceLocation IdLoc,
+ RedeclarationKind Redecl) {
Decl *D = LookupSingleName(TUScope, II, IdLoc,
- LookupObjCProtocolName);
+ LookupObjCProtocolName, Redecl);
return cast_or_null<ObjCProtocolDecl>(D);
}
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Jan 1 14:30:41 2012
@@ -1950,7 +1950,7 @@
break;
case DECL_OBJC_PROTOCOL:
D = ObjCProtocolDecl::Create(Context, 0, 0, SourceLocation(),
- SourceLocation(), 0);
+ SourceLocation(), 0, false);
break;
case DECL_OBJC_AT_DEFS_FIELD:
D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(),
Modified: cfe/trunk/test/Modules/Inputs/redecl-merge-bottom.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-merge-bottom.h?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-merge-bottom.h (original)
+++ cfe/trunk/test/Modules/Inputs/redecl-merge-bottom.h Sun Jan 1 14:30:41 2012
@@ -8,6 +8,8 @@
@class A;
+ at protocol P1;
+
void refers_to_C4(C4*);
#ifdef __cplusplus
Modified: cfe/trunk/test/Modules/Inputs/redecl-merge-left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-merge-left.h?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-merge-left.h (original)
+++ cfe/trunk/test/Modules/Inputs/redecl-merge-left.h Sun Jan 1 14:30:41 2012
@@ -10,6 +10,11 @@
@class A;
+ at protocol P1;
+ at protocol P2
+- (void)protoMethod2;
+ at end
+
// Test declarations in different modules with no common initial
// declaration.
@class C;
Modified: cfe/trunk/test/Modules/Inputs/redecl-merge-right.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-merge-right.h?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-merge-right.h (original)
+++ cfe/trunk/test/Modules/Inputs/redecl-merge-right.h Sun Jan 1 14:30:41 2012
@@ -9,6 +9,18 @@
@class B;
+ at protocol P1
+- (void)protoMethod1;
+ at end
+
+ at protocol P1;
+
+ at protocol P2;
+
+ at protocol P2;
+
+ at protocol P2;
+
// Test declarations in different modules with no common initial
// declaration.
@class C;
Modified: cfe/trunk/test/Modules/Inputs/redecl-merge-top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-merge-top.h?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-merge-top.h (original)
+++ cfe/trunk/test/Modules/Inputs/redecl-merge-top.h Sun Jan 1 14:30:41 2012
@@ -6,6 +6,11 @@
@class B;
+ at protocol P1;
+
+ at protocol P2;
+ at protocol P2;
+
#ifdef __cplusplus
template<typename T> class Vector;
#endif
Modified: cfe/trunk/test/Modules/redecl-merge.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecl-merge.m?rev=147412&r1=147411&r2=147412&view=diff
==============================================================================
--- cfe/trunk/test/Modules/redecl-merge.m (original)
+++ cfe/trunk/test/Modules/redecl-merge.m Sun Jan 1 14:30:41 2012
@@ -26,6 +26,11 @@
@class B;
+void testProtoMerge(id<P1> p1, id<P2> p2) {
+ [p1 protoMethod1];
+ [p2 protoMethod2];
+}
+
// Test redeclarations of entities in explicit submodules, to make
// sure we're maintaining the declaration chains even when normal name
// lookup can't see what we're looking for.
More information about the cfe-commits
mailing list