diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/ParseAST.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 18 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 85 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 4 | 
5 files changed, 79 insertions, 35 deletions
| diff --git a/clang/lib/Sema/ParseAST.cpp b/clang/lib/Sema/ParseAST.cpp index bb0bd9e1cb5..73f1167d0e6 100644 --- a/clang/lib/Sema/ParseAST.cpp +++ b/clang/lib/Sema/ParseAST.cpp @@ -92,7 +92,7 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,        Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());    };    // Check for any pending objective-c implementation decl. -  while ((ADecl = P.RetrievePendingObjCImpDecl())) +  while ((ADecl = P.FinishPendingObjCActions()))      Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());    // Process any TopLevelDecls generated by #pragma weak. diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 490ff65cd9a..0540dd9e0c5 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -606,6 +606,11 @@ public:    MethodPool InstanceMethodPool;    MethodPool FactoryMethodPool; +  /// Method selectors used in a @selector expression. Used for implementation  +  /// of -Wselector. +  llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors; + +    MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance);    /// Private Helper predicate to check for 'self'. @@ -798,6 +803,8 @@ public:    DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr); +  void DiagnoseUseOfUnimplementedSelectors(); +    virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,                                Scope *S, CXXScopeSpec *SS,                                bool isClassName = false, @@ -1656,7 +1663,7 @@ public:    /// unit are added to a global pool. This allows us to efficiently associate    /// a selector with a method declaraation for purposes of typechecking    /// messages sent to "id" (where the class of the object is unknown). -  void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method); +  void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false);    /// LookupInstanceMethodInGlobalPool - Returns the method and warns if    /// there are multiple signatures. @@ -1665,10 +1672,15 @@ public:    /// LookupFactoryMethodInGlobalPool - Returns the method and warns if    /// there are multiple signatures. -  ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R); +  ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, +                                                  bool warn=true); + +  /// LookupImplementedMethodInGlobalPool - Returns the method which has an +  /// implementation. +  ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);    /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. -  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method); +  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false);    /// CollectIvarsToConstructOrDestruct - Collect those ivars which require    /// initialization. diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 21aeb59a088..5f2f37eb0b0 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -32,10 +32,10 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {    // Allow the rest of sema to find private method decl implementations.    if (MDecl->isInstanceMethod()) -    AddInstanceMethodToGlobalPool(MDecl); +    AddInstanceMethodToGlobalPool(MDecl, true);    else -    AddFactoryMethodToGlobalPool(MDecl); - +    AddFactoryMethodToGlobalPool(MDecl, true); +      // Allow all of Sema to see that we are entering a method definition.    PushDeclContext(FnBodyScope, MDecl);    PushFunctionScope(); @@ -1130,7 +1130,7 @@ Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,    return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;  } -void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) { +void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl) {    llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos      = InstanceMethodPool.find(Method->getSelector());    if (Pos == InstanceMethodPool.end()) { @@ -1140,7 +1140,7 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {        Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),                                                       ObjCMethodList())).first;    } - +  Method->setDefined(impl);    ObjCMethodList &Entry = Pos->second;    if (Entry.Method == 0) {      // Haven't seen a method with this selector name yet - add it. @@ -1152,8 +1152,10 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {    // We've seen a method with this name, see if we have already seen this type    // signature.    for (ObjCMethodList *List = &Entry; List; List = List->Next) -    if (MatchTwoMethodDeclarations(Method, List->Method)) +    if (MatchTwoMethodDeclarations(Method, List->Method)) { +      List->Method->setDefined(impl);        return; +    }    // We have a new signature for an existing method - add it.    // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". @@ -1194,7 +1196,7 @@ ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,    return MethList.Method;  } -void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) { +void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl) {    llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos      = FactoryMethodPool.find(Method->getSelector());    if (Pos == FactoryMethodPool.end()) { @@ -1204,32 +1206,31 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {        Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),                                                      ObjCMethodList())).first;    } - -  ObjCMethodList &FirstMethod = Pos->second; -  if (!FirstMethod.Method) { +  Method->setDefined(impl); +  ObjCMethodList &Entry = Pos->second; +  if (!Entry.Method) {      // Haven't seen a method with this selector name yet - add it. -    FirstMethod.Method = Method; -    FirstMethod.Next = 0; -  } else { -    // We've seen a method with this name, now check the type signature(s). -    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method); - -    for (ObjCMethodList *Next = FirstMethod.Next; !match && Next; -         Next = Next->Next) -      match = MatchTwoMethodDeclarations(Method, Next->Method); - -    if (!match) { -      // We have a new signature for an existing method - add it. -      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". -      ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); -      ObjCMethodList *OMI = new (Mem) ObjCMethodList(Method, FirstMethod.Next); -      FirstMethod.Next = OMI; +    Entry.Method = Method; +    Entry.Next = 0; +    return; +  }  +  // We've seen a method with this name, see if we have already seen this type +  // signature. +  for (ObjCMethodList *List = &Entry; List; List = List->Next) +    if (MatchTwoMethodDeclarations(Method, List->Method)) { +      List->Method->setDefined(impl); +      return;      } -  } +   +  // We have a new signature for an existing method - add it. +  // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". +  ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); +  Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);  }  ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel, -                                                      SourceRange R) { +                                                      SourceRange R, +                                                      bool warn) {    llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos      = FactoryMethodPool.find(Sel);    if (Pos == FactoryMethodPool.end()) { @@ -1246,7 +1247,7 @@ ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,      for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)        // This checks if the methods differ by size & alignment.        if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true)) -        issueWarning = true; +        issueWarning = warn;    }    if (issueWarning && (MethList.Method && MethList.Next)) {      Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R; @@ -1259,6 +1260,18 @@ ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,    return MethList.Method;  } +ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) { +  SourceRange SR; +  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel, +                                                            SR, false); +  if (Method && Method->isDefined()) +    return Method; +  Method = LookupFactoryMethodInGlobalPool(Sel, SR, false); +  if (Method && Method->isDefined()) +    return Method; +  return 0; +} +  /// CompareMethodParamsInBaseAndSuper - This routine compares methods with  /// identical selector names in current and its super classes and issues  /// a warning if any of their argument types are incompatible. @@ -1540,7 +1553,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(                             ResultTInfo,                             cast<DeclContext>(ClassDecl),                             MethodType == tok::minus, isVariadic, -                           false, +                           false, false,                             MethodDeclKind == tok::objc_optional ?                             ObjCMethodDecl::Optional :                             ObjCMethodDecl::Required); @@ -1849,3 +1862,15 @@ void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,    }  } +void Sema::DiagnoseUseOfUnimplementedSelectors() { +  if (ReferencedSelectors.empty()) +    return; +  for (llvm::DenseMap<Selector, SourceLocation>::iterator S =  +        ReferencedSelectors.begin(), +       E = ReferencedSelectors.end(); S != E; ++S) { +    Selector Sel = (*S).first; +    if (!LookupImplementedMethodInGlobalPool(Sel)) +      Diag((*S).second, diag::warn_unimplemented_selector) << Sel; +  } +  return; +} diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 9f43471e0ad..5132464d244 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -163,6 +163,11 @@ Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,    if (!Method)      Diag(SelLoc, diag::warn_undeclared_selector) << Sel; +  llvm::DenseMap<Selector, SourceLocation>::iterator Pos +    = ReferencedSelectors.find(Sel); +  if (Pos == ReferencedSelectors.end()) +    ReferencedSelectors.insert(std::make_pair(Sel, SelLoc)); +    QualType Ty = Context.getObjCSelType();    return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);  } diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index e7358edec3e..6a7d8dbee12 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -1084,7 +1084,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,      // for this class.      GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),                               property->getLocation(), property->getGetterName(), -                             property->getType(), 0, CD, true, false, true, +                             property->getType(), 0, CD, true, false, true,  +                             false,                               (property->getPropertyImplementation() ==                                ObjCPropertyDecl::Optional) ?                               ObjCMethodDecl::Optional : @@ -1112,6 +1113,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,                                 property->getLocation(),                                 property->getSetterName(),                                 Context.VoidTy, 0, CD, true, false, true, +                               false,                                 (property->getPropertyImplementation() ==                                  ObjCPropertyDecl::Optional) ?                                 ObjCMethodDecl::Optional : | 

