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
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f14dc3c..4989014 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -419,7 +419,7 @@
return false;
}
-DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
+DeclContext *DeclContext::getPrimaryContext() {
switch (DeclKind) {
case Decl::TranslationUnit:
case Decl::LinkageSpec:
@@ -468,9 +468,15 @@
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 @@
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 @@
/// 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 @@
// 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_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 @@
}
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 7f787de..e3d7534 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -98,7 +98,7 @@
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 @@
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 2bfad5a..0b6eff1 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -24,7 +24,7 @@
SourceLocation beginLoc,
SourceLocation endLoc,
Selector SelInfo, QualType T,
- Decl *contextDecl,
+ DeclContext *contextDecl,
bool isInstance,
bool isVariadic,
bool isSynthesized,
@@ -61,8 +61,6 @@
}
ObjCContainerDecl::~ObjCContainerDecl() {
- delete [] InstanceMethods;
- delete [] ClassMethods;
}
ObjCInterfaceDecl::~ObjCInterfaceDecl() {
@@ -362,7 +360,7 @@
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 @@
}
}
-/// 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 @@
}
}
-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 @@
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 @@
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 @@
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 @@
}
}
-/// 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 @@
// 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 08c9b93..41acf5e 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -630,7 +630,7 @@
// 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 @@
// 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 08c9bde..90906e7 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -161,7 +161,7 @@
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 2957583..41285c4 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -223,7 +223,7 @@
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 cdec1e6..765dfe5 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -67,6 +67,7 @@
class ObjCIvarDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl;
+ class ObjCContainerDecl;
struct BlockSemaInfo;
class BasePaths;
@@ -1166,9 +1167,7 @@
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 f023fbf..5fb2740 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -26,7 +26,7 @@
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 351694c..6585733 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -287,7 +287,7 @@
// 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 @@
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 c5e5aa2..edc3a28 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -681,7 +681,7 @@
// 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 @@
= 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 68e7744..69c45e9 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1001,14 +1001,18 @@
}
}
-/// 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 @@
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 @@
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 @@
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 @@
<< 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 @@
<< 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 @@
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 @@
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 @@
}
}
}
- // 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 @@
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 3510b5d..111dca4 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -414,7 +414,7 @@
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 @@
// 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 704334d..26ef1bd 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1117,7 +1117,7 @@
= 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 @@
// 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 @@
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 @@
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);