Change ObjCInterfaceDecl to inherit from NamedDecl (not TypeDecl). While ObjCInterfaceDecl is arguably a TypeDecl, it isn't a ScopedDecl. Since TypeDecl's are scoped, it makes sense to simply treat them as NamedDecl's. I could have fiddled a bit more with the hierarchy (in terms of creating a non-scoped TypeDecl), however this probably isn't worth the effort.

I also finished unifying access to scope decl change by converting Sema::getObjCInterfaceDecl() to use Sema::LookupDecl(). This is much cleaner now:-)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49107 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steve Naroff 2008-04-02 18:30:49 +00:00
Родитель 5744dc294e
Коммит 3110251f13
7 изменённых файлов: 28 добавлений и 30 удалений

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

@ -52,7 +52,6 @@ public:
PropertyDecl, PropertyDecl,
// ScopedDecl // ScopedDecl
// TypeDecl // TypeDecl
ObjCInterface,
Typedef, Typedef,
// TagDecl // TagDecl
Enum, Enum,
@ -67,6 +66,7 @@ public:
BlockVar, BlockVar,
FileVar, FileVar,
ParmVar, ParmVar,
ObjCInterface,
ObjCCompatibleAlias, ObjCCompatibleAlias,
ObjCMethod, ObjCMethod,
ObjCClass, ObjCClass,
@ -78,8 +78,8 @@ public:
// of the class, to allow efficient classof. // of the class, to allow efficient classof.
NamedFirst = Field, NamedLast = ParmVar, NamedFirst = Field, NamedLast = ParmVar,
FieldFirst = Field, FieldLast = ObjCIvar, FieldFirst = Field, FieldLast = ObjCIvar,
ScopedFirst = ObjCInterface, ScopedLast = ParmVar, ScopedFirst = Typedef, ScopedLast = ParmVar,
TypeFirst = ObjCInterface, TypeLast = Class, TypeFirst = Typedef, TypeLast = Class,
TagFirst = Enum , TagLast = Class, TagFirst = Enum , TagLast = Class,
RecordFirst = Struct , RecordLast = Class, RecordFirst = Struct , RecordLast = Class,
ValueFirst = EnumConstant , ValueLast = ParmVar, ValueFirst = EnumConstant , ValueLast = ParmVar,

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

@ -191,7 +191,11 @@ public:
/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
/// typically inherit from NSObject (an exception is NSProxy). /// typically inherit from NSObject (an exception is NSProxy).
/// ///
class ObjCInterfaceDecl : public TypeDecl { class ObjCInterfaceDecl : public NamedDecl {
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
Type *TypeForDecl;
friend class ASTContext;
/// Class's super class. /// Class's super class.
ObjCInterfaceDecl *SuperClass; ObjCInterfaceDecl *SuperClass;
@ -227,7 +231,7 @@ class ObjCInterfaceDecl : public TypeDecl {
ObjCInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos, ObjCInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos,
IdentifierInfo *Id, bool FD, bool isInternal) IdentifierInfo *Id, bool FD, bool isInternal)
: TypeDecl(ObjCInterface, atLoc, Id, 0), SuperClass(0), : NamedDecl(ObjCInterface, atLoc, Id), TypeForDecl(0), SuperClass(0),
ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0), ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0),
NumIvars(0), NumIvars(0),
InstanceMethods(0), NumInstanceMethods(0), InstanceMethods(0), NumInstanceMethods(0),

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

@ -63,7 +63,6 @@ public:
DISPATCH_CASE(Union,RecordDecl) // FIXME: Refine. DISPATCH_CASE(Union,RecordDecl) // FIXME: Refine.
DISPATCH_CASE(Class,RecordDecl) // FIXME: Refine. DISPATCH_CASE(Class,RecordDecl) // FIXME: Refine.
DISPATCH_CASE(Enum,EnumDecl) DISPATCH_CASE(Enum,EnumDecl)
DISPATCH_CASE(ObjCInterface,ObjCInterfaceDecl)
default: default:
assert(false && "Subtype of ScopedDecl not handled."); assert(false && "Subtype of ScopedDecl not handled.");
} }

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

@ -94,7 +94,14 @@ class Sema : public Action {
/// with @protocol keyword, so that we can emit errors on duplicates and /// with @protocol keyword, so that we can emit errors on duplicates and
/// find the declarations when needed. /// find the declarations when needed.
llvm::DenseMap<IdentifierInfo*, ObjCProtocolDecl*> ObjCProtocols; llvm::DenseMap<IdentifierInfo*, ObjCProtocolDecl*> ObjCProtocols;
/// ObjCInterfaceDecls - Keep track of all class declarations declared
/// with @interface, so that we can emit errors on duplicates and
/// find the declarations when needed.
typedef llvm::DenseMap<const IdentifierInfo*,
ObjCInterfaceDecl*> ObjCInterfaceDeclsTy;
ObjCInterfaceDeclsTy ObjCInterfaceDecls;
/// ObjCAliasDecls - Keep track of all class declarations declared /// ObjCAliasDecls - Keep track of all class declarations declared
/// with @compatibility_alias, so that we can emit errors on duplicates and /// with @compatibility_alias, so that we can emit errors on duplicates and
/// find the declarations when needed. This construct is ancient and will /// find the declarations when needed. This construct is ancient and will
@ -102,7 +109,7 @@ class Sema : public Action {
typedef llvm::DenseMap<const IdentifierInfo*, typedef llvm::DenseMap<const IdentifierInfo*,
ObjCCompatibleAliasDecl*> ObjCAliasTy; ObjCCompatibleAliasDecl*> ObjCAliasTy;
ObjCAliasTy ObjCAliasDecls; ObjCAliasTy ObjCAliasDecls;
// Enum values used by KnownFunctionIDs (see below). // Enum values used by KnownFunctionIDs (see below).
enum { enum {
id_printf, id_printf,

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

@ -86,19 +86,11 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
/// getObjCInterfaceDecl - Look up a for a class declaration in the scope. /// getObjCInterfaceDecl - Look up a for a class declaration in the scope.
/// return 0 if one not found. /// return 0 if one not found.
/// FIXME: removed this when ObjCInterfaceDecl's aren't ScopedDecl's.
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) { ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
ScopedDecl *IDecl; // The third "scope" argument is 0 since we aren't enabling lazy built-in
// Scan up the scope chain looking for a decl that matches this identifier // creation from this context.
// that is in the appropriate namespace. Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0, false);
for (IDecl = Id->getFETokenInfo<ScopedDecl>(); IDecl;
IDecl = IDecl->getNext())
if (IDecl->getIdentifierNamespace() == Decl::IDNS_Ordinary)
break;
if (ObjCCompatibleAliasDecl *ADecl =
dyn_cast_or_null<ObjCCompatibleAliasDecl>(IDecl))
return ADecl->getClassInterface();
return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl); return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
} }
@ -130,6 +122,9 @@ Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI,
// Unlike typedef's, they can only be introduced at file-scope (and are // Unlike typedef's, they can only be introduced at file-scope (and are
// therefore not scoped decls). They can, however, be shadowed by // therefore not scoped decls). They can, however, be shadowed by
// other names in IDNS_Ordinary. // other names in IDNS_Ordinary.
ObjCInterfaceDeclsTy::iterator IDI = ObjCInterfaceDecls.find(II);
if (IDI != ObjCInterfaceDecls.end())
return IDI->second;
ObjCAliasTy::iterator I = ObjCAliasDecls.find(II); ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
if (I != ObjCAliasDecls.end()) if (I != ObjCAliasDecls.end())
return I->second->getClassInterface(); return I->second->getClassInterface();

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

@ -101,10 +101,7 @@ Sema::DeclTy *Sema::ActOnStartClassInterface(
IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc, NumProtocols, IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc, NumProtocols,
ClassName); ClassName);
// Chain & install the interface decl into the identifier. ObjCInterfaceDecls[ClassName] = IDecl;
IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
ClassName->setFETokenInfo(IDecl);
// Remember that this needs to be removed when the scope is popped. // Remember that this needs to be removed when the scope is popped.
TUScope->AddDecl(IDecl); TUScope->AddDecl(IDecl);
} }
@ -388,8 +385,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
// Build, chain & install the interface decl into the identifier. // Build, chain & install the interface decl into the identifier.
IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, 0, ClassName, IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, 0, ClassName,
false, true); false, true);
IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>()); ObjCInterfaceDecls[ClassName] = IDecl;
ClassName->setFETokenInfo(IDecl);
IDecl->setSuperClass(SDecl); IDecl->setSuperClass(SDecl);
IDecl->setLocEnd(ClassLoc); IDecl->setLocEnd(ClassLoc);
@ -597,9 +593,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
if (!IDecl) { // Not already seen? Make a forward decl. if (!IDecl) { // Not already seen? Make a forward decl.
IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, 0, IdentList[i], IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, 0, IdentList[i],
true); true);
// Chain & install the interface decl into the identifier. ObjCInterfaceDecls[IdentList[i]] = IDecl;
IDecl->setNext(IdentList[i]->getFETokenInfo<ScopedDecl>());
IdentList[i]->setFETokenInfo(IDecl);
// Remember that this needs to be removed when the scope is popped. // Remember that this needs to be removed when the scope is popped.
TUScope->AddDecl(IDecl); TUScope->AddDecl(IDecl);

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

@ -20,8 +20,7 @@ typedef int OBJECT; // expected-error {{previous definition is here}}
typedef int Gorf; // expected-error {{previous definition is here}} typedef int Gorf; // expected-error {{previous definition is here}}
@interface Gorf @end // expected-error {{redefinition of 'Gorf' as different kind of symbol}} \ @interface Gorf @end // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
// expected-error {{previous definition is here}}
void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symbol}} void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
{ {