diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-11-18 00:28:11 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-11-18 00:28:11 +0000 |
commit | 321c22f1c4271c3d9a3d4d3fc18847f948ab595b (patch) | |
tree | 293c5da5b500bcf3bfcda607fdb3dcb36bc377f1 /lib | |
parent | f74a419b7219d050e1e40ff920d30832e903e5a8 (diff) |
Add SourceLocations to ObjCClassDecl for the class identifiers referenced by @class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89170 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 2 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 41 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 8 |
7 files changed, 43 insertions, 23 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index c3c506e5ba..abcffed405 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -678,7 +678,7 @@ void DeclContext::buildLookup(DeclContext *DCtx) { if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D)) for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); I != IEnd; ++I) - makeDeclVisibleInContextImpl(*I); + makeDeclVisibleInContextImpl(I->getInterface()); // If this declaration is itself a transparent declaration context, // add its members (recursively). diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 7b48b724c0..9d43c7cca0 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -571,31 +571,46 @@ ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, //===----------------------------------------------------------------------===// ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts, unsigned nElts, + ObjCInterfaceDecl *const *Elts, + const SourceLocation *Locs, + unsigned nElts, ASTContext &C) : Decl(ObjCClass, DC, L) { - ForwardDecls.set(Elts, nElts, C); + setClassList(C, Elts, Locs, nElts); } +void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, + const SourceLocation *Locs, unsigned Num) { + ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num, + llvm::alignof<ObjCClassRef>()); + for (unsigned i = 0; i < Num; ++i) + new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]); + + NumDecls = Num; +} ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ObjCInterfaceDecl *const *Elts, + const SourceLocation *Locs, unsigned nElts) { - return new (C) ObjCClassDecl(DC, L, Elts, nElts, C); + return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C); } void ObjCClassDecl::Destroy(ASTContext &C) { - - // FIXME: There is no clear ownership policy now for referenced - // ObjCInterfaceDecls. Some of them can be forward declarations that - // are never later defined (in which case the ObjCClassDecl owns them) - // or the ObjCInterfaceDecl later becomes a real definition later. Ideally - // we should have separate objects for forward declarations and definitions, - // obviating this problem. Because of this situation, referenced - // ObjCInterfaceDecls are destroyed in ~TranslationUnit. - - ForwardDecls.Destroy(C); + // ObjCInterfaceDecls registered with a DeclContext will get destroyed + // when the DeclContext is destroyed. For those created only by a forward + // declaration, the first @class that created the ObjCInterfaceDecl gets + // to destroy it. + // FIXME: Note that this ownership role is very brittle; a better + // polict is surely need in the future. + for (iterator I = begin(), E = end(); I !=E ; ++I) { + ObjCInterfaceDecl *ID = I->getInterface(); + if (ID->isForwardDecl() && ID->getLocStart() == getLocStart()) + ID->Destroy(C); + } + + C.Deallocate(ForwardDecls); Decl::Destroy(C); } diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 199ed356d6..645133b4da 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -624,7 +624,7 @@ void DeclPrinter::VisitObjCClassDecl(ObjCClassDecl *D) { for (ObjCClassDecl::iterator I = D->begin(), E = D->end(); I != E; ++I) { if (I != D->begin()) Out << ", "; - Out << (*I)->getNameAsString(); + Out << I->getInterface()->getNameAsString(); } } diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 775ce76c92..6a92a2db51 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -264,7 +264,12 @@ void PCHDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) { ClassRefs.reserve(NumClassRefs); for (unsigned I = 0; I != NumClassRefs; ++I) ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]))); - CD->setClassList(*Reader.getContext(), ClassRefs.data(), NumClassRefs); + llvm::SmallVector<SourceLocation, 16> SLocs; + SLocs.reserve(NumClassRefs); + for (unsigned I = 0; I != NumClassRefs; ++I) + SLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + CD->setClassList(*Reader.getContext(), ClassRefs.data(), SLocs.data(), + NumClassRefs); } void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) { diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 8997e661a5..c7bfee2c8b 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -260,7 +260,9 @@ void PCHDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) { VisitDecl(D); Record.push_back(D->size()); for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I) - Writer.AddDeclRef(*I, Record); + Writer.AddDeclRef(I->getInterface(), Record); + for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I) + Writer.AddSourceLocation(I->getLocation(), Record); Code = pch::DECL_OBJC_CLASS; } diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 24ad69e3e0..06955e5c30 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -744,7 +744,7 @@ void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) { typedefString += "\n"; for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end(); I != E; ++I) { - ObjCInterfaceDecl *ForwardDecl = *I; + ObjCInterfaceDecl *ForwardDecl = I->getInterface(); typedefString += "#ifndef _REWRITER_typedef_"; typedefString += ForwardDecl->getNameAsString(); typedefString += "\n"; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 8961cf165a..0c5569caff 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1197,10 +1197,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); if (!IDecl) { // Not already seen? Make a forward decl. IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc, - IdentList[i], - // FIXME: need to get the 'real' - // identifier loc from the parser. - AtClassLoc, true); + IdentList[i], IdentLocs[i], true); // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to // the current DeclContext. This prevents clients that walk DeclContext @@ -1214,8 +1211,9 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, Interfaces.push_back(IDecl); } + assert(Interfaces.size() == NumElts); ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc, - &Interfaces[0], + Interfaces.data(), IdentLocs, Interfaces.size()); CurContext->addDecl(CDecl); CheckObjCDeclScope(CDecl); |