diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/IdentifierResolver.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 109 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 8 |
9 files changed, 68 insertions, 72 deletions
diff --git a/clang/lib/Sema/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp index 08c9bdeb319..90906e72746 100644 --- a/clang/lib/Sema/IdentifierResolver.cpp +++ b/clang/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/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 29575838a90..41285c4e676 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index cdec1e6a29a..765dfe5420c 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index f023fbf2e2a..5fb2740fcf3 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 351694c74d1..6585733ab38 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c5e5aa2f3d2..edc3a28dcf5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 68e7744582c..69c45e9a647 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/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/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 3510b5d1289..111dca4ae02 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 704334d7897..26ef1bdaa35 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/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); |