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
This commit is contained in:
Ted Kremenek 2009-11-18 00:28:11 +00:00
Родитель f74a419b72
Коммит 321c22f1c4
8 изменённых файлов: 64 добавлений и 32 удалений

Просмотреть файл

@ -718,10 +718,22 @@ public:
/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
///
class ObjCClassDecl : public Decl {
ObjCList<ObjCInterfaceDecl> ForwardDecls;
public:
class ObjCClassRef {
ObjCInterfaceDecl *ID;
SourceLocation L;
public:
ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
SourceLocation getLocation() const { return L; }
ObjCInterfaceDecl *getInterface() const { return ID; }
};
private:
ObjCClassRef *ForwardDecls;
unsigned NumDecls;
ObjCClassDecl(DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C);
ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,
unsigned nElts, ASTContext &C);
virtual ~ObjCClassDecl() {}
public:
@ -730,17 +742,17 @@ public:
static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts = 0,
const SourceLocation *Locs = 0,
unsigned nElts = 0);
typedef ObjCList<ObjCInterfaceDecl>::iterator iterator;
iterator begin() const { return ForwardDecls.begin(); }
iterator end() const { return ForwardDecls.end(); }
unsigned size() const { return ForwardDecls.size(); }
typedef const ObjCClassRef* iterator;
iterator begin() const { return ForwardDecls; }
iterator end() const { return ForwardDecls + NumDecls; }
unsigned size() const { return NumDecls; }
/// setClassList - Set the list of forward classes.
void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) {
ForwardDecls.set(List, Num, C);
}
void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
const SourceLocation *Locs, unsigned Num);
static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
static bool classof(const ObjCClassDecl *D) { return true; }

Просмотреть файл

@ -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).

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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();
}
}

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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";

Просмотреть файл

@ -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);