diff options
author | Steve Naroff <snaroff@apple.com> | 2009-01-08 17:28:14 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-01-08 17:28:14 +0000 |
commit | 0701bbb228dfd87e1fe82a0a4b7b9facfecb43da (patch) | |
tree | 0e6483e9a1755c00b458662c0cd52c26d132b70e /lib | |
parent | 7e5d6ed47dcedce35043de59ee00464b681bc786 (diff) |
This is a large/messy diff that unifies the ObjC AST's with DeclContext.
- ObjCContainerDecl's (ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl), ObjCCategoryImpl, & ObjCImplementation are all DeclContexts.
- ObjCMethodDecl is now a ScopedDecl (so it can play nicely with DeclContext).
- ObjCContainerDecl now does iteration/lookup using DeclContext infrastructure (no more linear search:-)
- Removed ASTContext argument to DeclContext::lookup(). It wasn't being used and complicated it's use from an ObjC AST perspective.
- Added Sema::ProcessPropertyDecl() and removed Sema::diagnosePropertySetterGetterMismatch().
- Simplified Sema::ActOnAtEnd() considerably. Still more work to do.
- Fixed an incorrect casting assumption in Sema::getCurFunctionOrMethodDecl(), now that ObjCMethodDecl is a ScopedDecl.
- Removed addPropertyMethods from ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl.
This passes all the tests on my machine. Since many of the changes are central to the way ObjC finds it's methods, I expect some fallout (and there are still a handful of FIXME's). Nevertheless, this should be a step in the right direction.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61929 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 30 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 127 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/IdentifierResolver.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 109 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 8 |
13 files changed, 136 insertions, 169 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index f14dc3c717..49890144a9 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -419,7 +419,7 @@ bool DeclContext::isTransparentContext() const { return false; } -DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) { +DeclContext *DeclContext::getPrimaryContext() { switch (DeclKind) { case Decl::TranslationUnit: case Decl::LinkageSpec: @@ -468,9 +468,15 @@ DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) { return this; case Decl::ObjCInterface: + case Decl::ObjCProtocol: + case Decl::ObjCCategory: // FIXME: Can Objective-C interfaces be forward-declared? return this; + case Decl::ObjCImplementation: + case Decl::ObjCCategoryImpl: + return this; + default: assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast && "Unknown DeclContext kind"); @@ -486,6 +492,10 @@ DeclContext *DeclContext::getNextContext() { case Decl::CXXRecord: case Decl::ObjCMethod: case Decl::ObjCInterface: + case Decl::ObjCCategory: + case Decl::ObjCProtocol: + case Decl::ObjCImplementation: + case Decl::ObjCCategoryImpl: case Decl::LinkageSpec: case Decl::Block: // There is only one DeclContext for these entities. @@ -511,7 +521,7 @@ void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup) /// buildLookup - Build the lookup data structure with all of the /// declarations in DCtx (and any other contexts linked to it or /// transparent contexts nested within it). -void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) { +void DeclContext::buildLookup(DeclContext *DCtx) { for (; DCtx; DCtx = DCtx->getNextContext()) { for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end(); D != DEnd; ++D) { @@ -522,22 +532,22 @@ void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) { // add its members (recursively). if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) if (InnerCtx->isTransparentContext()) - buildLookup(Context, InnerCtx->getPrimaryContext(Context)); + buildLookup(InnerCtx->getPrimaryContext()); } } } DeclContext::lookup_result -DeclContext::lookup(ASTContext &Context, DeclarationName Name) { - DeclContext *PrimaryContext = getPrimaryContext(Context); +DeclContext::lookup(DeclarationName Name) { + DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) - return PrimaryContext->lookup(Context, Name); + return PrimaryContext->lookup(Name); /// If there is no lookup data structure, build one now by walking /// all of the linked DeclContexts (in declaration order!) and /// inserting their values. if (LookupPtr.getPointer() == 0) - buildLookup(Context, this); + buildLookup(this); if (isLookupMap()) { StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer()); @@ -563,8 +573,8 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) { } DeclContext::lookup_const_result -DeclContext::lookup(ASTContext &Context, DeclarationName Name) const { - return const_cast<DeclContext*>(this)->lookup(Context, Name); +DeclContext::lookup(DeclarationName Name) const { + return const_cast<DeclContext*>(this)->lookup(Name); } const DeclContext *DeclContext::getLookupContext() const { @@ -575,7 +585,7 @@ const DeclContext *DeclContext::getLookupContext() const { } void DeclContext::insert(ASTContext &Context, ScopedDecl *D) { - DeclContext *PrimaryContext = getPrimaryContext(Context); + DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) { PrimaryContext->insert(Context, D); return; diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 7f787de75f..e3d753490a 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -98,7 +98,7 @@ bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const { Context.getCanonicalType(ClassType)); unsigned TypeQuals; DeclContext::lookup_const_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName); + for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName); Con != ConEnd; ++Con) { if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) && (TypeQuals & QualType::Const) != 0) @@ -114,7 +114,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const { DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal); DeclContext::lookup_const_iterator Op, OpEnd; - for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName); + for (llvm::tie(Op, OpEnd) = this->lookup(OpName); Op != OpEnd; ++Op) { // C++ [class.copy]p9: // A user-declared copy assignment operator is a non-static non-template diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 2bfad5a7be..0b6eff1af5 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -24,7 +24,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, - Decl *contextDecl, + DeclContext *contextDecl, bool isInstance, bool isVariadic, bool isSynthesized, @@ -61,8 +61,6 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, } ObjCContainerDecl::~ObjCContainerDecl() { - delete [] InstanceMethods; - delete [] ClassMethods; } ObjCInterfaceDecl::~ObjCInterfaceDecl() { @@ -362,7 +360,7 @@ FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class"); DeclarationName Member = ivar->getDeclName(); DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl)) - ->lookup(Context, Member); + ->lookup(Member); assert((Lookup.first != Lookup.second) && "field decl not found"); FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first); assert(MemberDecl && "field decl not found"); @@ -382,27 +380,6 @@ void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl( } } -/// addMethods - Insert instance and methods declarations into -/// ObjCInterfaceDecl's InsMethods and ClsMethods fields. -/// -void ObjCContainerDecl::addMethods(ObjCMethodDecl **insMethods, - unsigned numInsMembers, - ObjCMethodDecl **clsMethods, - unsigned numClsMembers, - SourceLocation endLoc) { - NumInstanceMethods = numInsMembers; - if (numInsMembers) { - InstanceMethods = new ObjCMethodDecl*[numInsMembers]; - memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); - } - NumClassMethods = numClsMembers; - if (numClsMembers) { - ClassMethods = new ObjCMethodDecl*[numClsMembers]; - memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); - } - AtEndLoc = endLoc; -} - /// addProperties - Insert property declaration AST nodes into /// ObjCInterfaceDecl's PropertyDecl field. /// @@ -440,18 +417,45 @@ void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties, } } -static void -addPropertyMethods(Decl *D, - ASTContext &Context, - ObjCPropertyDecl *property, - llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, - llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) { - ObjCMethodDecl *GetterDecl, *SetterDecl = 0; - - GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]); - if (!property->isReadOnly()) - SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]); - +// Get the local instance method declared in this interface. +// FIXME: handle overloading, instance & class methods can have the same name. +ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const { + lookup_const_result MethodResult = lookup(Sel); + if (MethodResult.first) + return const_cast<ObjCMethodDecl*>( + dyn_cast<ObjCMethodDecl>(*MethodResult.first)); + return 0; +} + +// Get the local class method declared in this interface. +ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const { + lookup_const_result MethodResult = lookup(Sel); + if (MethodResult.first) + return const_cast<ObjCMethodDecl*>( + dyn_cast<ObjCMethodDecl>(*MethodResult.first)); + return 0; +} + +unsigned ObjCContainerDecl::getNumInstanceMethods() const { + unsigned sum = 0; + for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I) + sum++; + return sum; +} +unsigned ObjCContainerDecl::getNumClassMethods() const { + unsigned sum = 0; + for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I) + sum++; + return sum; +} + +/// addPropertyMethods - Goes through list of properties declared in this class +/// and builds setter/getter method declartions depending on the setter/getter +/// attributes of the property. +/// +void ObjCContainerDecl::getPropertyMethods( + ASTContext &Context, ObjCPropertyDecl *property, + ObjCMethodDecl *& GetterDecl, ObjCMethodDecl *&SetterDecl) { // FIXME: The synthesized property we set here is misleading. We // almost always synthesize these methods unless the user explicitly // provided prototypes (which is odd, but allowed). Sema should be @@ -467,15 +471,12 @@ addPropertyMethods(Decl *D, ObjCMethodDecl::Create(Context, property->getLocation(), property->getLocation(), property->getGetterName(), - property->getType(), - D, + property->getType(), this, true, false, true, (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) ? ObjCMethodDecl::Optional : ObjCMethodDecl::Required); - insMethods.push_back(GetterDecl); - InsMap[property->getGetterName()] = GetterDecl; } else // A user declared getter will be synthesize when @synthesize of @@ -496,15 +497,12 @@ addPropertyMethods(Decl *D, ObjCMethodDecl::Create(Context, property->getLocation(), property->getLocation(), property->getSetterName(), - Context.VoidTy, - D, + Context.VoidTy, this, true, false, true, (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) ? ObjCMethodDecl::Optional : ObjCMethodDecl::Required); - insMethods.push_back(SetterDecl); - InsMap[property->getSetterName()] = SetterDecl; // Invent the arguments for the setter. We don't bother making a // nice name for the argument. ParmVarDecl *Argument = ParmVarDecl::Create(Context, @@ -523,30 +521,6 @@ addPropertyMethods(Decl *D, property->setSetterMethodDecl(SetterDecl); } -/// addPropertyMethods - Goes through list of properties declared in this class -/// and builds setter/getter method declartions depending on the setter/getter -/// attributes of the property. -/// -void ObjCInterfaceDecl::addPropertyMethods( - ASTContext &Context, - ObjCPropertyDecl *property, - llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, - llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) { - ::addPropertyMethods(this, Context, property, insMethods, InsMap); -} - -/// addPropertyMethods - Goes through list of properties declared in this class -/// and builds setter/getter method declartions depending on the setter/getter -/// attributes of the property. -/// -void ObjCCategoryDecl::addPropertyMethods( - ASTContext &Context, - ObjCPropertyDecl *property, - llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, - llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) { - ::addPropertyMethods(this, Context, property, insMethods, InsMap); -} - /// mergeProperties - Adds properties to the end of list of current properties /// for this category. @@ -572,18 +546,6 @@ void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties, } } -/// addPropertyMethods - Goes through list of properties declared in this class -/// and builds setter/getter method declartions depending on the setter/getter -/// attributes of the property. -/// -void ObjCProtocolDecl::addPropertyMethods( - ASTContext &Context, - ObjCPropertyDecl *property, - llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, - llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) { - ::addPropertyMethods(this, Context, property, insMethods, InsMap); -} - /// addProperties - Insert property declaration AST nodes into /// ObjCProtocolDecl's PropertyDecl field. /// @@ -850,9 +812,8 @@ unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { // Get length of this name. unsigned length = 3; // _I_ or _C_ length += getClassInterface()->getNameAsString().size()+1; // extra for _ - NamedDecl *MethodContext = getMethodContext(); if (ObjCCategoryImplDecl *CID = - dyn_cast<ObjCCategoryImplDecl>(MethodContext)) + dyn_cast<ObjCCategoryImplDecl>(getMethodContext())) length += CID->getNameAsString().size()+1; length += getSelector().getAsString().size(); // selector name return length; diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 08c9b938f1..41acf5ed50 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -630,7 +630,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { // Collect information about instance methods llvm::SmallVector<Selector, 16> InstanceMethodSels; llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes; - for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(), + for (ObjCCategoryImplDecl::instmeth_iterator iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end() ; iter != endIter ; iter++) { InstanceMethodSels.push_back((*iter)->getSelector()); std::string TypeStr; @@ -641,7 +641,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) { // Collect information about class methods llvm::SmallVector<Selector, 16> ClassMethodSels; llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes; - for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(), + for (ObjCCategoryImplDecl::classmeth_iterator iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end() ; iter != endIter ; iter++) { ClassMethodSels.push_back((*iter)->getSelector()); std::string TypeStr; diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp index 08c9bdeb31..90906e7274 100644 --- a/lib/Sema/IdentifierResolver.cpp +++ b/lib/Sema/IdentifierResolver.cpp @@ -161,7 +161,7 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, return false; } - return LookupContext(D) == LookupContext(Ctx->getPrimaryContext(Context)); + return LookupContext(D) == LookupContext(Ctx->getPrimaryContext()); } /// AddDecl - Link the decl to its shadowed decl chain. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 29575838a9..41285c4e67 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -223,7 +223,7 @@ NamedDecl *Sema::getCurFunctionOrMethodDecl() { while (isa<BlockDecl>(DC)) DC = DC->getParent(); if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC)) - return cast<NamedDecl>(DC); + return cast<ScopedDecl>(DC); return 0; } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index cdec1e6a29..765dfe5420 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -67,6 +67,7 @@ namespace clang { class ObjCIvarDecl; class ObjCMethodDecl; class ObjCPropertyDecl; + class ObjCContainerDecl; struct BlockSemaInfo; class BasePaths; @@ -1166,9 +1167,7 @@ public: void CheckObjCPropertyAttributes(QualType PropertyTy, SourceLocation Loc, unsigned &Attributes); - void diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property, - const ObjCMethodDecl *GetterMethod, - const ObjCMethodDecl *SetterMethod); + void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC); void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name); diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index f023fbf2e2..5fb2740fcf 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -26,7 +26,7 @@ namespace { if (LookupCtx && !LookInParentCtx) {
IdIsUndeclared = true;
DeclContext::lookup_const_iterator I, E;
- for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) {
+ for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) {
IdIsUndeclared = false;
if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag) ||
isa<TypedefDecl>(*I))
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 351694c74d..6585733ab3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -287,7 +287,7 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, // Perform qualified name lookup into the LookupCtx. // FIXME: Will need to look into base classes and such. DeclContext::lookup_const_iterator I, E; - for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) + for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) if ((*I)->isInIdentifierNamespace(NS)) { // Ignore non-namespace names if we're only looking for namespaces. if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) continue; @@ -334,7 +334,7 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, while (Ctx && (Ctx->isNamespace() || Ctx->isRecord())) { // Look for declarations of this name in this scope. DeclContext::lookup_const_iterator I, E; - for (llvm::tie(I, E) = Ctx->lookup(Context, Name); I != E; ++I) { + for (llvm::tie(I, E) = Ctx->lookup(Name); I != E; ++I) { // FIXME: Cache this result in the IdResolver if ((*I)->isInIdentifierNamespace(NS)) { if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c5e5aa2f3d..edc3a28dcf 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -681,7 +681,7 @@ Sema::ActOnMemInitializer(DeclTy *ConstructorD, // using a qualified name. ] // Look for a member, first. FieldDecl *Member = 0; - DeclContext::lookup_result Result = ClassDecl->lookup(Context, MemberOrBase); + DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase); if (Result.first != Result.second) Member = dyn_cast<FieldDecl>(*Result.first); @@ -1590,7 +1590,7 @@ Sema::PerformInitializationByConstructor(QualType ClassType, = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(ClassType.getUnqualifiedType())); DeclContext::lookup_const_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName); + for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName); Con != ConEnd; ++Con) { CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); if ((Kind == IK_Direct) || diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 68e7744582..69c45e9a64 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1001,14 +1001,18 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) { } } -/// diagnosePropertySetterGetterMismatch - Make sure that use-defined -/// setter/getter methods have the property type and issue diagnostics -/// if they don't. -/// -void -Sema::diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property, - const ObjCMethodDecl *GetterMethod, - const ObjCMethodDecl *SetterMethod) { +/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods +/// have the property type and issue diagnostics if they don't. +/// Also synthesize a getter/setter method if none exist (and update the +/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized +/// methods is the "right" thing to do. +void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, + ObjCContainerDecl *CD) { + ObjCMethodDecl *GetterMethod, *SetterMethod; + + GetterMethod = CD->getInstanceMethod(property->getGetterName()); + SetterMethod = CD->getInstanceMethod(property->getSetterName()); + if (GetterMethod && GetterMethod->getResultType() != property->getType()) { Diag(property->getLocation(), @@ -1031,6 +1035,29 @@ Sema::diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property, Diag(SetterMethod->getLocation(), diag::note_declared_at); } } + + // Synthesize getter/setter methods if none exist. + // Add any synthesized methods to the global pool. This allows us to + // handle the following, which is supported by GCC (and part of the design). + // + // @interface Foo + // @property double bar; + // @end + // + // void thisIsUnfortunate() { + // id foo; + // double bar = [foo bar]; + // } + // + CD->getPropertyMethods(Context, property, GetterMethod, SetterMethod); + if (GetterMethod) { + CD->addDecl(Context, GetterMethod); + AddInstanceMethodToGlobalPool(GetterMethod); + } + if (SetterMethod) { + CD->addDecl(Context, SetterMethod); + AddInstanceMethodToGlobalPool(SetterMethod); + } } // Note: For class/category implemenations, allMethods/allProperties is @@ -1046,17 +1073,12 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, if (!ClassDecl) return; - llvm::SmallVector<ObjCMethodDecl*, 32> insMethods; - llvm::SmallVector<ObjCMethodDecl*, 16> clsMethods; - - llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap; - llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap; - bool isInterfaceDeclKind = isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl) || isa<ObjCProtocolDecl>(ClassDecl); bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl); + if (pNum != 0) { if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum); @@ -1067,7 +1089,14 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, else assert(false && "ActOnAtEnd - property declaration misplaced"); } - + + DeclContext *DC = dyn_cast<DeclContext>(ClassDecl); + assert(DC && "Missing DeclContext"); + + // FIXME: Remove these and use the ObjCContainerDecl/DeclContext. + llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap; + llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap; + for (unsigned i = 0; i < allNum; i++ ) { ObjCMethodDecl *Method = cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i])); @@ -1084,7 +1113,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, << Method->getDeclName(); Diag(PrevMethod->getLocation(), diag::note_previous_declaration); } else { - insMethods.push_back(Method); + DC->addDecl(Context, Method); InsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "id". AddInstanceMethodToGlobalPool(Method); @@ -1101,17 +1130,13 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, << Method->getDeclName(); Diag(PrevMethod->getLocation(), diag::note_previous_declaration); } else { - clsMethods.push_back(Method); + DC->addDecl(Context, Method); ClsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "Class". AddFactoryMethodToGlobalPool(Method); } } } - // Save the size so we can detect if we've added any property methods. - unsigned int insMethodsSizePriorToPropAdds = insMethods.size(); - unsigned int clsMethodsSizePriorToPropAdds = clsMethods.size(); - if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { // Compares properties declared in this class to those of its // super class. @@ -1119,22 +1144,15 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, MergeProtocolPropertiesIntoClass(I, I); for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(), e = I->classprop_end(); i != e; ++i) { - diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()], - InsMap[(*i)->getSetterName()]); - I->addPropertyMethods(Context, *i, insMethods, InsMap); + ProcessPropertyDecl((*i), I); } - I->addMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size(), AtEndLoc); - + I->setAtEndLoc(AtEndLoc); } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) { for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(), e = P->classprop_end(); i != e; ++i) { - diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()], - InsMap[(*i)->getSetterName()]); - P->addPropertyMethods(Context, *i, insMethods, InsMap); + ProcessPropertyDecl((*i), P); } - P->addMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size(), AtEndLoc); + P->setAtEndLoc(AtEndLoc); } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { // Categories are used to extend the class by declaring new methods. @@ -1145,12 +1163,9 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, MergeProtocolPropertiesIntoClass(C, C); for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(), e = C->classprop_end(); i != e; ++i) { - diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()], - InsMap[(*i)->getSetterName()]); - C->addPropertyMethods(Context, *i, insMethods, InsMap); + ProcessPropertyDecl((*i), C); } - C->addMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size(), AtEndLoc); + C->setAtEndLoc(AtEndLoc); } else if (ObjCImplementationDecl *IC = dyn_cast<ObjCImplementationDecl>(ClassDecl)) { @@ -1173,24 +1188,6 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, } } } - // Add any synthesized methods to the global pool. This allows us to - // handle the following, which is supported by GCC (and part of the design). - // - // @interface Foo - // @property double bar; - // @end - // - // void thisIsUnfortunate() { - // id foo; - // double bar = [foo bar]; - // } - // - if (insMethodsSizePriorToPropAdds < insMethods.size()) - for (unsigned i = insMethodsSizePriorToPropAdds; i < insMethods.size(); i++) - AddInstanceMethodToGlobalPool(insMethods[i]); - if (clsMethodsSizePriorToPropAdds < clsMethods.size()) - for (unsigned i = clsMethodsSizePriorToPropAdds; i < clsMethods.size(); i++) - AddFactoryMethodToGlobalPool(clsMethods[i]); } @@ -1241,7 +1238,7 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( ObjCMethodDecl* ObjCMethod = ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType, - ClassDecl, + dyn_cast<DeclContext>(ClassDecl), MethodType == tok::minus, isVariadic, false, MethodDeclKind == tok::objc_optional ? diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 3510b5d128..111dca4ae0 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -414,7 +414,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name, FunctionDecl *&Operator) { DeclContext::lookup_iterator Alloc, AllocEnd; - llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name); + llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name); if (Alloc == AllocEnd) { if (AllowMissing) return false; @@ -517,7 +517,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, // Check if this function is already declared. { DeclContext::lookup_iterator Alloc, AllocEnd; - for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Context, Name); + for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name); Alloc != AllocEnd; ++Alloc) { // FIXME: Do we need to check for default arguments here? FunctionDecl *Func = cast<FunctionDecl>(*Alloc); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 704334d789..26ef1bdaa3 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1117,7 +1117,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(ToType)); DeclContext::lookup_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(Context, ConstructorName); + for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(ConstructorName); Con != ConEnd; ++Con) { CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); if (Constructor->isConvertingConstructor()) @@ -2141,7 +2141,7 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S, // empty. if (const RecordType *T1Rec = T1->getAsRecordType()) { DeclContext::lookup_const_iterator Oper, OperEnd; - for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName); + for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper) AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0], Args+1, NumArgs - 1, CandidateSet, @@ -3392,7 +3392,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, OverloadCandidateSet CandidateSet; DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); DeclContext::lookup_const_iterator Oper, OperEnd; - for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName); + for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper) AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs, CandidateSet, /*SuppressUserConversions=*/false); @@ -3577,7 +3577,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, const RecordType *BaseRecord = Base->getType()->getAsRecordType(); DeclContext::lookup_const_iterator Oper, OperEnd; - for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(Context, OpName); + for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper) AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet, /*SuppressUserConversions=*/false); |