#include "clang/AST/DeclNodes.def"
};
- /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
- /// labels, tags, members and ordinary identifiers. These are meant
- /// as bitmasks, so that searches in C++ can look into the "tag" namespace
- /// during ordinary lookup.
+ /// IdentifierNamespace - According to C99 6.2.3, there are four
+ /// namespaces, labels, tags, members and ordinary
+ /// identifiers. These are meant as bitmasks, so that searches in
+ /// C++ can look into the "tag" namespace during ordinary lookup. We
+ /// use additional namespaces for Objective-C entities.
enum IdentifierNamespace {
IDNS_Label = 0x1,
IDNS_Tag = 0x2,
IDNS_Member = 0x4,
IDNS_Ordinary = 0x8,
- IDNS_Protocol = 0x10
+ IDNS_ObjCProtocol = 0x10,
+ IDNS_ObjCImplementation = 0x20,
+ IDNS_ObjCCategoryImpl = 0x40
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
bool Implicit : 1;
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
- unsigned IdentifierNamespace : 5;
+ unsigned IdentifierNamespace : 8;
#ifndef NDEBUG
void CheckAccessDeclContext() const;
static bool classof(const ObjCCategoryDecl *D) { return true; }
};
-class ObjCImplDecl : public Decl, public DeclContext {
+class ObjCImplDecl : public NamedDecl, public DeclContext {
/// Class interface for this category implementation
ObjCInterfaceDecl *ClassInterface;
protected:
ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *classInterface)
- : Decl(DK, DC, L), DeclContext(DK),
- ClassInterface(classInterface) {}
+ : NamedDecl(DK, DC, L,
+ classInterface? classInterface->getDeclName()
+ : DeclarationName()),
+ DeclContext(DK), ClassInterface(classInterface) {}
public:
virtual ~ObjCImplDecl() {}
case ObjCContainer:
case ObjCCategory:
case ObjCInterface:
- case ObjCCategoryImpl:
case ObjCProperty:
case ObjCCompatibleAlias:
return IDNS_Ordinary;
case ObjCProtocol:
- return IDNS_Protocol;
+ return IDNS_ObjCProtocol;
+ case ObjCImplementation:
+ return IDNS_ObjCImplementation;
+
+ case ObjCCategoryImpl:
+ return IDNS_ObjCCategoryImpl;
+
case Field:
case ObjCAtDefsField:
case ObjCIvar:
case FileScopeAsm:
case StaticAssert:
case ObjCClass:
- case ObjCImplementation:
case ObjCPropertyImpl:
case ObjCForwardProtocol:
case Block:
}
void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
- VisitDecl(D);
+ VisitNamedDecl(D);
D->setClassInterface(
cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
D->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
- VisitDecl(D);
+ VisitNamedDecl(D);
Writer.AddDeclRef(D->getClassInterface(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
// Abstract class (no need to define a stable pch::DECL code).
/// This is only necessary for issuing pretty diagnostics.
llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
- /// ObjCImplementations - Keep track of all class @implementations
- /// so we can emit errors on duplicates.
- llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
-
/// ObjCCategoryImpls - Maintain a list of category implementations so
/// we can check for duplicates and find local method declarations.
llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
/// C99 6.2.2p4-5 and C++ [basic.link]p6.
LookupRedeclarationWithLinkage,
/// Look up the name of an Objective-C protocol.
- LookupProtocolName
+ LookupObjCProtocolName,
+ /// Look up the name of an Objective-C implementation
+ LookupObjCImplementationName,
+ /// Look up the name of an Objective-C category implementation
+ LookupObjCCategoryImplName
};
/// @brief Represents the results of name lookup.
case Sema::LookupTagName:
case Sema::LookupMemberName:
case Sema::LookupRedeclarationWithLinkage: // FIXME: check linkage, scoping
- case Sema::LookupProtocolName:
+ case Sema::LookupObjCProtocolName:
+ case Sema::LookupObjCImplementationName:
+ case Sema::LookupObjCCategoryImplName:
return D->isInIdentifierNamespace(IDNS);
case Sema::LookupOperatorName:
SourceLocation Loc = SourceLocation());
ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II);
+ ObjCImplementationDecl *LookupObjCImplementation(IdentifierInfo *II);
+ ObjCCategoryImplDecl *LookupObjCCategoryImpl(IdentifierInfo *II);
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
ObjCImplementationDecl::Create(Context, CurContext, AtClassImplLoc,
IDecl, SDecl);
- // FIXME: PushOnScopeChains?
- CurContext->addDecl(Context, IMPDecl);
-
if (CheckObjCDeclScope(IMPDecl))
return DeclPtrTy::make(IMPDecl);
// Check that there is no duplicate implementation of this class.
- if (ObjCImplementations[ClassName])
+ if (LookupObjCImplementation(ClassName))
// FIXME: Don't leak everything!
Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
else // add it to the list.
- ObjCImplementations[ClassName] = IMPDecl;
+ PushOnScopeChains(IMPDecl, TUScope);
return DeclPtrTy::make(IMPDecl);
}
}
}
// Lastly, look through the implementation (if one is in scope).
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[IDecl->getIdentifier()])
+ if (ObjCImplementationDecl *ImpDecl
+ = LookupObjCImplementation(IDecl->getIdentifier()))
if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
// If all fails, look at the super class.
const ObjCInterfaceDecl *IFace,
const Selector &Sel) {
ObjCMethodDecl *Method = 0;
- if (ObjCImplementationDecl *ImpDecl =
- Sema::ObjCImplementations[IFace->getIdentifier()])
+ if (ObjCImplementationDecl *ImpDecl
+ = LookupObjCImplementation(IFace->getIdentifier()))
Method = ImpDecl->getInstanceMethod(Context, Sel);
if (!Method && IFace->getSuperClass())
ObjCMethodDecl *Method = 0;
// lookup in class and all superclasses
while (ClassDecl && !Method) {
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
+ if (ObjCImplementationDecl *ImpDecl
+ = LookupObjCImplementation(ClassDecl->getIdentifier()))
Method = ImpDecl->getClassMethod(Context, Sel);
// Look through local category implementations associated with the class.
ObjCMethodDecl *Method = 0;
while (ClassDecl && !Method) {
// If we have implementations in scope, check "private" methods.
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
+ if (ObjCImplementationDecl *ImpDecl
+ = LookupObjCImplementation(ClassDecl->getIdentifier()))
Method = ImpDecl->getInstanceMethod(Context, Sel);
// Look through local category implementations associated with the class.
if (!Getter)
if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
+ if (ObjCImplementationDecl *ImpDecl
+ = LookupObjCImplementation(ClassDecl->getIdentifier()))
Getter = ImpDecl->getClassMethod(Context, Sel);
if (Getter) {
// methods.
if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
+ if (ObjCImplementationDecl *ImpDecl
+ = LookupObjCImplementation(ClassDecl->getIdentifier()))
Setter = ImpDecl->getClassMethod(Context, SetterSel);
}
// Look through local category implementations associated with the class.
IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member;
break;
- case Sema::LookupProtocolName:
- IDNS = Decl::IDNS_Protocol;
+ case Sema::LookupObjCProtocolName:
+ IDNS = Decl::IDNS_ObjCProtocol;
+ break;
+
+ case Sema::LookupObjCImplementationName:
+ IDNS = Decl::IDNS_ObjCImplementation;
+ break;
+
+ case Sema::LookupObjCCategoryImplName:
+ IDNS = Decl::IDNS_ObjCCategoryImpl;
break;
}
return IDNS;
IDNS = Decl::IDNS_Ordinary;
break;
- case Sema::LookupProtocolName:
- IDNS = Decl::IDNS_Protocol;
+ case Sema::LookupObjCProtocolName:
+ IDNS = Decl::IDNS_ObjCProtocol;
+ break;
+
+ case Sema::LookupObjCImplementationName:
+ IDNS = Decl::IDNS_ObjCImplementation;
+ break;
+
+ case Sema::LookupObjCCategoryImplName:
+ IDNS = Decl::IDNS_ObjCCategoryImpl;
break;
}
/// \brief Find the protocol with the given name, if any.
ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II) {
- Decl *D = LookupName(TUScope, II, LookupProtocolName).getAsDecl();
+ Decl *D = LookupName(TUScope, II, LookupObjCProtocolName).getAsDecl();
return cast_or_null<ObjCProtocolDecl>(D);
}
+/// \brief Find the Objective-C implementation with the given name, if
+/// any.
+ObjCImplementationDecl *Sema::LookupObjCImplementation(IdentifierInfo *II) {
+ Decl *D = LookupName(TUScope, II, LookupObjCImplementationName).getAsDecl();
+ return cast_or_null<ObjCImplementationDecl>(D);
+}
+
+/// \brief Find the Objective-C category implementation with the given
+/// name, if any.
+ObjCCategoryImplDecl *Sema::LookupObjCCategoryImpl(IdentifierInfo *II) {
+ Decl *D = LookupName(TUScope, II, LookupObjCCategoryImplName).getAsDecl();
+ return cast_or_null<ObjCCategoryImplDecl>(D);
+}
+
void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
FunctionSet &Functions) {