[cfe-commits] r146722 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/DeclObjC.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/DeclObjC.cpp lib/Sema/Sema.cpp lib/Sema/SemaDeclObjC.cpp lib/Serialization/ASTReaderDecl.cpp test/Modules/Inputs/decl2.h test/Modules/Inputs/module.map test/SemaObjC/forward-class-1.m
Douglas Gregor
dgregor at apple.com
Thu Dec 15 19:12:42 PST 2011
Author: dgregor
Date: Thu Dec 15 21:12:41 2011
New Revision: 146722
URL: http://llvm.org/viewvc/llvm-project?rev=146722&view=rev
Log:
Fix chaining of ObjCInterfaceDecl redeclarations
Added:
cfe/trunk/test/Modules/Inputs/decl2.h
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/test/Modules/Inputs/module.map
cfe/trunk/test/SemaObjC/forward-class-1.m
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Dec 15 21:12:41 2011
@@ -853,7 +853,8 @@
QualType getPackExpansionType(QualType Pattern,
llvm::Optional<unsigned> NumExpansions);
- QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const;
+ QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+ ObjCInterfaceDecl *PrevDecl = 0) const;
QualType getObjCObjectType(QualType Base,
ObjCProtocolDecl * const *Protocols,
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Dec 15 21:12:41 2011
@@ -614,9 +614,12 @@
static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation atLoc,
IdentifierInfo *Id,
+ ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc = SourceLocation(),
bool isInternal = false);
+ static ObjCInterfaceDecl *CreateEmpty(ASTContext &C);
+
virtual SourceRange getSourceRange() const {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -916,8 +919,6 @@
return getFirstDeclaration();
}
- void setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl);
-
// Low-level accessor
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Dec 15 21:12:41 2011
@@ -2808,11 +2808,17 @@
/// getObjCInterfaceType - Return the unique reference to the type for the
/// specified ObjC interface decl. The list of protocols is optional.
-QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const {
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+ ObjCInterfaceDecl *PrevDecl) const {
if (Decl->TypeForDecl)
return QualType(Decl->TypeForDecl, 0);
- // FIXME: redeclarations?
+ if (PrevDecl) {
+ assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+ Decl->TypeForDecl = PrevDecl->TypeForDecl;
+ return QualType(PrevDecl->TypeForDecl, 0);
+ }
+
void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
Decl->TypeForDecl = T;
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Dec 15 21:12:41 2011
@@ -3182,7 +3182,8 @@
if (!ToIface) {
ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getAtStartLoc()),
- Name.getAsIdentifierInfo(), Loc,
+ Name.getAsIdentifierInfo(),
+ /*PrevDecl=*/0,Loc,
D->isImplicitInterfaceDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIface);
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Dec 15 21:12:41 2011
@@ -225,18 +225,19 @@
void ObjCInterfaceDecl::allocateDefinitionData() {
assert(!hasDefinition() && "ObjC class already has a definition");
Data = new (getASTContext()) DefinitionData();
- Data->Definition = this;
-
+ Data->Definition = this;
+}
+
+void ObjCInterfaceDecl::startDefinition() {
+ allocateDefinitionData();
+
// Update all of the declarations with a pointer to the definition.
for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
RD != RDEnd; ++RD) {
if (*RD != this)
RD->Data = Data;
}
-}
-void ObjCInterfaceDecl::startDefinition() {
- allocateDefinitionData();
if (ASTMutationListener *L = getASTContext().getASTMutationListener())
L->CompletedObjCForwardRef(this);
}
@@ -674,9 +675,24 @@
DeclContext *DC,
SourceLocation atLoc,
IdentifierInfo *Id,
+ ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc,
bool isInternal){
- return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, isInternal);
+ ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
+ isInternal);
+ C.getObjCInterfaceType(Result, PrevDecl);
+
+ if (PrevDecl) {
+ Result->Data = PrevDecl->Data;
+ Result->setPreviousDeclaration(PrevDecl);
+ }
+
+ return Result;
+}
+
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateEmpty(ASTContext &C) {
+ return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
+ false);
}
ObjCInterfaceDecl::
@@ -851,14 +867,6 @@
return false;
}
-void ObjCInterfaceDecl::setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl) {
- redeclarable_base::setPreviousDeclaration(PrevDecl);
-
- // Inherit the 'Data' pointer from the previous declaration.
- if (PrevDecl)
- Data = PrevDecl->Data;
-}
-
//===----------------------------------------------------------------------===//
// ObjCIvarDecl
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Dec 15 21:12:41 2011
@@ -82,6 +82,7 @@
ObjCInterfaceDecl *ProtocolDecl =
ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
&Context.Idents.get("Protocol"),
+ /*PrevDecl=*/0,
SourceLocation(), true);
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
PushOnScopeChains(ProtocolDecl, TUScope, false);
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Dec 15 21:12:41 2011
@@ -366,11 +366,11 @@
}
// Create a declaration to describe this @interface.
+ ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
ObjCInterfaceDecl *IDecl
= ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
- ClassLoc);
+ PrevIDecl, ClassLoc);
- ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (PrevIDecl) {
// Class already seen. Was it a definition?
if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -379,9 +379,6 @@
Diag(Def->getLocation(), diag::note_previous_definition);
IDecl->setInvalidDecl();
}
-
- // Link to the previous declaration.
- IDecl->setPreviousDeclaration(PrevIDecl);
}
if (AttrList)
@@ -870,9 +867,8 @@
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
} else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
- if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
- diag::warn_undef_interface))
- IDecl = 0;
+ RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
+ diag::warn_undef_interface);
} else {
// We did not find anything with the name ClassName; try to correct for
// typos in the class name.
@@ -928,7 +924,8 @@
// FIXME: Do we support attributes on the @implementation? If so we should
// copy them over.
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
- ClassName, ClassLoc, true);
+ ClassName, /*PrevDecl=*/0, ClassLoc,
+ true);
IDecl->startDefinition();
if (SDecl) {
IDecl->setSuperClass(SDecl);
@@ -1774,16 +1771,13 @@
}
// Create a declaration to describe this forward declaration.
+ ObjCInterfaceDecl *PrevIDecl
+ = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
ObjCInterfaceDecl *IDecl
= ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
- IdentList[i], IdentLocs[i], true);
+ IdentList[i], PrevIDecl, IdentLocs[i], true);
IDecl->setAtEndRange(IdentLocs[i]);
- // If there was a previous declaration, link to it.
- if (ObjCInterfaceDecl *PrevIDecl
- = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))
- IDecl->setPreviousDeclaration(PrevIDecl);
-
// Create the forward declaration. Note that we intentionally do this
// before we add the ObjCInterfaceDecl we just created, so that the
// rewriter sees the ObjCClassDecl first.
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Dec 15 21:12:41 2011
@@ -223,6 +223,9 @@
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
// if we have a fully initialized TypeDecl, we can safely read its type now.
TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
+ } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+ // if we have a fully initialized TypeDecl, we can safely read its type now.
+ ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// FunctionDecl's body was written last after all other Stmts/Exprs.
if (Record[Idx++])
@@ -556,7 +559,7 @@
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
VisitRedeclarable(ID);
VisitObjCContainerDecl(ID);
- ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
+ TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
if (ID == Def) {
@@ -621,13 +624,13 @@
// pending references were linked.
Reader.PendingForwardRefs.erase(ID);
#endif
- } else if (Def) {
- if (Def->Data) {
- ID->Data = Def->Data;
- } else {
- // The definition is still initializing.
- Reader.PendingForwardRefs[Def].push_back(ID);
- }
+ }
+ } else if (Def) {
+ if (Def->Data) {
+ ID->Data = Def->Data;
+ } else {
+ // The definition is still initializing.
+ Reader.PendingForwardRefs[Def].push_back(ID);
}
}
}
@@ -1561,6 +1564,8 @@
FD->RedeclLink.setPointer(cast<FunctionDecl>(previous));
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
VD->RedeclLink.setPointer(cast<VarDecl>(previous));
+ } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(previous)) {
+ ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1736,7 +1741,7 @@
Selector(), QualType(), 0, 0);
break;
case DECL_OBJC_INTERFACE:
- D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
+ D = ObjCInterfaceDecl::CreateEmpty(Context);
break;
case DECL_OBJC_IVAR:
D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
Added: cfe/trunk/test/Modules/Inputs/decl2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/decl2.h?rev=146722&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/decl2.h (added)
+++ cfe/trunk/test/Modules/Inputs/decl2.h Thu Dec 15 21:12:41 2011
@@ -0,0 +1 @@
+ at class A;
Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Thu Dec 15 21:12:41 2011
@@ -39,5 +39,6 @@
module decldef {
explicit module Decl { header "decl.h" }
+ explicit module Decl2 { header "decl2.h" }
explicit module Def { header "def.h" }
}
\ No newline at end of file
Modified: cfe/trunk/test/SemaObjC/forward-class-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/forward-class-1.m?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/forward-class-1.m (original)
+++ cfe/trunk/test/SemaObjC/forward-class-1.m Thu Dec 15 21:12:41 2011
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
- at class FOO, BAR;
@class FOO, BAR; // expected-note {{forward declaration of class here}}
+ at class FOO, BAR;
@interface INTF : FOO // expected-error {{attempting to use the forward class 'FOO' as superclass of 'INTF'}}
@end
More information about the cfe-commits
mailing list