From: Fariborz Jahanian Date: Sat, 29 Sep 2007 17:04:06 +0000 (+0000) Subject: Patch to remove use of has table for protocol name lookup. This patch mirrors my X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b6351f76e1e06893337441641c0e349939afb31;p=clang Patch to remove use of has table for protocol name lookup. This patch mirrors my previous patch to do the same for class name lookup using a hash table. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42471 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/Sema.h b/Sema/Sema.h index 2c753f3aa5..465e3fb73a 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -47,6 +47,7 @@ namespace clang { class OCUVectorType; class TypedefDecl; class ObjcInterfaceDecl; + class ObjcProtocolDecl; /// Sema - This implements semantic analysis and AST building for C. class Sema : public Action { @@ -185,6 +186,8 @@ private: SourceLocation IdLoc, Scope *S); ObjcInterfaceDecl *getObjCInterfaceDecl(Scope *S, IdentifierInfo *Id, SourceLocation IdLoc); + ObjcProtocolDecl *getObjCProtocolDecl(Scope *S, + IdentifierInfo *Id, SourceLocation IdLoc); ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S); ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, Scope *S); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 2b0e1452f6..5e66684cb4 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -78,7 +78,7 @@ void Sema::PopScope(SourceLocation Loc, Scope *S) { } } -/// ObjcInterfaceDecl - 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. ObjcInterfaceDecl *Sema::getObjCInterfaceDecl(Scope *S, IdentifierInfo *Id, @@ -90,6 +90,19 @@ ObjcInterfaceDecl *Sema::getObjCInterfaceDecl(Scope *S, return cast_or_null(static_cast(IdDecl)); } +/// getObjcProtocolDecl - Look up a for a protocol declaration in the scope. +/// return 0 if one not found. +ObjcProtocolDecl *Sema::getObjCProtocolDecl(Scope *S, + IdentifierInfo *Id, + SourceLocation IdLoc) { + // Note that Protocols have their own namespace. + ScopedDecl *PrDecl = LookupScopedDecl(Id, Decl::IDNS_Protocol, + IdLoc, S); + if (PrDecl && !isa(PrDecl)) + PrDecl = 0; + return cast_or_null(static_cast(PrDecl)); +} + /// LookupScopedDecl - Look up the inner-most declaration in the specified /// namespace. ScopedDecl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI, @@ -935,7 +948,8 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(Scope* S, /// Check then save referenced protocols for (unsigned int i = 0; i != NumProtocols; i++) { - ObjcProtocolDecl* RefPDecl = Context.getObjCProtocolDecl(ProtocolNames[i]); + ObjcProtocolDecl* RefPDecl = getObjCProtocolDecl(S, ProtocolNames[i], + ClassLoc); if (!RefPDecl || RefPDecl->getIsForwardProtoDecl()) Diag(ClassLoc, diag::err_undef_protocolref, ProtocolNames[i]->getName(), @@ -951,7 +965,7 @@ Sema::DeclTy *Sema::ObjcStartProtoInterface(Scope* S, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) { assert(ProtocolName && "Missing protocol identifier"); - ObjcProtocolDecl *PDecl = Context.getObjCProtocolDecl(ProtocolName); + ObjcProtocolDecl *PDecl = getObjCProtocolDecl(S, ProtocolName, ProtocolLoc); if (PDecl) { // Protocol already seen. Better be a forward protocol declaration if (!PDecl->getIsForwardProtoDecl()) @@ -969,12 +983,12 @@ Sema::DeclTy *Sema::ObjcStartProtoInterface(Scope* S, // Chain & install the protocol decl into the identifier. PDecl->setNext(ProtocolName->getFETokenInfo()); ProtocolName->setFETokenInfo(PDecl); - Context.setObjCProtocolDecl(ProtocolName, PDecl); } /// Check then save referenced protocols for (unsigned int i = 0; i != NumProtoRefs; i++) { - ObjcProtocolDecl* RefPDecl = Context.getObjCProtocolDecl(ProtoRefNames[i]); + ObjcProtocolDecl* RefPDecl = getObjCProtocolDecl(S, ProtoRefNames[i], + ProtocolLoc); if (!RefPDecl || RefPDecl->getIsForwardProtoDecl()) Diag(ProtocolLoc, diag::err_undef_protocolref, ProtoRefNames[i]->getName(), @@ -995,13 +1009,12 @@ Sema::ObjcForwardProtocolDeclaration(Scope *S, SourceLocation AtProtocolLoc, for (unsigned i = 0; i != NumElts; ++i) { ObjcProtocolDecl *PDecl; - PDecl = Context.getObjCProtocolDecl(IdentList[i]); + PDecl = getObjCProtocolDecl(S, IdentList[i], AtProtocolLoc); if (!PDecl) {// Already seen? PDecl = new ObjcProtocolDecl(SourceLocation(), 0, IdentList[i], true); // Chain & install the protocol decl into the identifier. PDecl->setNext(IdentList[i]->getFETokenInfo()); IdentList[i]->setFETokenInfo(PDecl); - Context.setObjCProtocolDecl(IdentList[i], PDecl); } // Remember that this needs to be removed when the scope is popped. S->AddDecl(IdentList[i]); @@ -1019,18 +1032,8 @@ Sema::DeclTy *Sema::ObjcStartCatInterface(Scope* S, ObjcCategoryDecl *CDecl; ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(S, ClassName, ClassLoc); CDecl = new ObjcCategoryDecl(AtInterfaceLoc, NumProtoRefs, ClassName); - if (IDecl) { - assert (ClassName->getFETokenInfo() && "Missing @interface decl"); - Decl *D = static_cast(ClassName->getFETokenInfo()); - assert(isa(D) && "Missing @interface decl"); - - // Chain & install the category decl into the identifier. - // Note that head of the chain is the @interface class type and follow up - // nodes in the chain are the protocol decl nodes. - cast(D)->setNext(CDecl); - } - CDecl->setClassInterface(IDecl); + /// Check that class of this category is already completely declared. if (!IDecl || IDecl->getIsForwardDecl()) Diag(ClassLoc, diag::err_undef_interface, ClassName->getName()); @@ -1053,7 +1056,8 @@ Sema::DeclTy *Sema::ObjcStartCatInterface(Scope* S, /// Check then save referenced protocols for (unsigned int i = 0; i != NumProtoRefs; i++) { - ObjcProtocolDecl* RefPDecl = Context.getObjCProtocolDecl(ProtoRefNames[i]); + ObjcProtocolDecl* RefPDecl = getObjCProtocolDecl(S, ProtoRefNames[i], + CategoryLoc); if (!RefPDecl || RefPDecl->getIsForwardProtoDecl()) Diag(CategoryLoc, diag::err_undef_protocolref, ProtoRefNames[i]->getName(), diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 59b1387eda..0258f98f43 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -39,7 +39,6 @@ class ASTContext { llvm::FoldingSet FunctionTypeNoProtos; llvm::FoldingSet FunctionTypeProtos; llvm::DenseMap RecordLayoutInfo; - llvm::DenseMap ProtocolNameInfo; llvm::SmallVector ImplementationClassInfo; RecordDecl *CFConstantStringTypeDecl; public: @@ -165,12 +164,6 @@ public: /// position information. const RecordLayout &getRecordLayout(const RecordDecl *D, SourceLocation L); - ObjcProtocolDecl* getObjCProtocolDecl(const IdentifierInfo* ProtocolName) - { return ProtocolNameInfo[ProtocolName]; } - void setObjCProtocolDecl(const IdentifierInfo* ProtocolName, - ObjcProtocolDecl* ProtocolDecl) - { ProtocolNameInfo[ProtocolName] = ProtocolDecl; } - ObjcImplementationDecl* getObjcImplementationClass(unsigned ix) { return ImplementationClassInfo[ix]; } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 2133d7a053..98a34406d3 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -47,10 +47,13 @@ public: /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, /// labels, tags, members and ordinary identifiers. + /// Objective-c protocols have their own namespace, so a protocol can have + /// the same name as category, class, struct, typedef, etc. enum IdentifierNamespace { IDNS_Label, IDNS_Tag, IDNS_Member, + IDNS_Protocol, IDNS_Ordinary }; private: @@ -86,13 +89,14 @@ public: case ParmVariable: case EnumConstant: case ObjcInterface: - case ObjcProtocol: return IDNS_Ordinary; case Struct: case Union: case Class: case Enum: return IDNS_Tag; + case ObjcProtocol: + return IDNS_Protocol; } } // global temp stats (until we have a per-module visitor)