]> granicus.if.org Git - clang/commitdiff
Allow getting all source locations of selector identifiers in a ObjCMethodDecl.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 3 Oct 2011 06:37:04 +0000 (06:37 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 3 Oct 2011 06:37:04 +0000 (06:37 +0000)
Instead of always storing all source locations for the selector identifiers
we check whether all the identifiers are in a "standard" position; "standard" position is

  -Immediately before the arguments: -(id)first:(int)x second:(int)y;
  -With a space between the arguments: -(id)first: (int)x second: (int)y;
  -For nullary selectors, immediately before ';': -(void)release;

In such cases we infer the locations instead of storing them.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140989 91177308-0d34-0410-b5e6-96231b3b80d8

19 files changed:
include/clang/AST/DeclObjC.h
include/clang/AST/ExprObjC.h
include/clang/AST/SelectorLocationsKind.h
lib/AST/ASTContext.cpp
lib/AST/ASTImporter.cpp
lib/AST/DeclObjC.cpp
lib/AST/SelectorLocationsKind.cpp
lib/CodeGen/CGCall.cpp
lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaObjCProperty.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp

index dc3d818d0029336bfaefcc11459a43a80f40e6f5..d54af89fc6773780b734d5472a38ae99bc1c1bea 100644 (file)
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_DECLOBJC_H
 
 #include "clang/AST/Decl.h"
+#include "clang/AST/SelectorLocationsKind.h"
 #include "llvm/ADT/STLExtras.h"
 
 namespace clang {
@@ -137,6 +138,10 @@ private:
 
   /// \brief Indicates whether this method has a related result type.
   unsigned RelatedResultType : 1;
+  
+  /// \brief Whether the locations of the selector identifiers are in a
+  /// "standard" position, a enum SelectorLocationsKind.
+  unsigned SelLocsKind : 2;
 
   // Result type of this method.
   QualType MethodDeclType;
@@ -144,9 +149,10 @@ private:
   // Type source information for the result type.
   TypeSourceInfo *ResultTInfo;
 
-  /// ParamInfo - List of pointers to VarDecls for the formal parameters of this
-  /// Method.
-  ObjCList<ParmVarDecl> ParamInfo;
+  /// \brief Array of ParmVarDecls for the formal parameters of this method
+  /// and optionally followed by selector locations.
+  void *ParamsAndSelLocs;
+  unsigned NumParams;
 
   /// List of attributes for this method declaration.
   SourceLocation EndLoc; // the location of the ';' or '}'.
@@ -162,6 +168,43 @@ private:
   /// constructed by createImplicitParams.
   ImplicitParamDecl *CmdDecl;
 
+  SelectorLocationsKind getSelLocsKind() const {
+    return (SelectorLocationsKind)SelLocsKind;
+  }
+  bool hasStandardSelLocs() const {
+    return getSelLocsKind() != SelLoc_NonStandard;
+  }
+
+  /// \brief Get a pointer to the stored selector identifiers locations array.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  SourceLocation *getStoredSelLocs() {
+    return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
+  }
+  const SourceLocation *getStoredSelLocs() const {
+    return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
+  }
+
+  /// \brief Get a pointer to the stored selector identifiers locations array.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  ParmVarDecl **getParams() {
+    return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
+  }
+  const ParmVarDecl *const *getParams() const {
+    return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
+  }
+
+  /// \brief Get the number of stored selector identifiers locations.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  unsigned getNumStoredSelLocs() const {
+    if (hasStandardSelLocs())
+      return 0;
+    return getNumSelectorLocs();
+  }
+
+  void setParamsAndSelLocs(ASTContext &C,
+                           ArrayRef<ParmVarDecl*> Params,
+                           ArrayRef<SourceLocation> SelLocs);
+
   ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
                  Selector SelInfo, QualType T,
                  TypeSourceInfo *ResultTInfo,
@@ -180,7 +223,9 @@ private:
     IsDefined(isDefined),
     DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
     RelatedResultType(HasRelatedResultType),
+    SelLocsKind(SelLoc_StandardNoSpace),
     MethodDeclType(T), ResultTInfo(ResultTInfo),
+    ParamsAndSelLocs(0), NumParams(0),
     EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {
     setImplicit(isImplicitlyDeclared);
   }
@@ -194,7 +239,6 @@ public:
   static ObjCMethodDecl *Create(ASTContext &C,
                                 SourceLocation beginLoc,
                                 SourceLocation endLoc,
-                                ArrayRef<SourceLocation> SelLocs,
                                 Selector SelInfo,
                                 QualType T, 
                                 TypeSourceInfo *ResultTInfo,
@@ -232,6 +276,29 @@ public:
     return SourceRange(getLocation(), EndLoc);
   }
 
+  SourceLocation getSelectorStartLoc() const { return getSelectorLoc(0); }
+  SourceLocation getSelectorLoc(unsigned Index) const {
+    assert(Index < getNumSelectorLocs() && "Index out of range!");
+    if (hasStandardSelLocs())
+      return getStandardSelectorLoc(Index, getSelector(),
+                                   getSelLocsKind() == SelLoc_StandardWithSpace,
+                      llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
+                                         NumParams),
+                                   EndLoc);
+    return getStoredSelLocs()[Index];
+  }
+
+  void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
+
+  unsigned getNumSelectorLocs() const {
+    if (isImplicit())
+      return 0;
+    Selector Sel = getSelector();
+    if (Sel.isUnarySelector())
+      return 1;
+    return Sel.getNumArgs();
+  }
+
   ObjCInterfaceDecl *getClassInterface();
   const ObjCInterfaceDecl *getClassInterface() const {
     return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
@@ -252,23 +319,27 @@ public:
   void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
 
   // Iterator access to formal parameters.
-  unsigned param_size() const { return ParamInfo.size(); }
-  typedef ObjCList<ParmVarDecl>::iterator param_iterator;
-  param_iterator param_begin() const { return ParamInfo.begin(); }
-  param_iterator param_end() const { return ParamInfo.end(); }
+  unsigned param_size() const { return NumParams; }
+  typedef const ParmVarDecl *const *param_const_iterator;
+  typedef ParmVarDecl *const *param_iterator;
+  param_const_iterator param_begin() const { return getParams(); }
+  param_const_iterator param_end() const { return getParams() + NumParams; }
+  param_iterator param_begin() { return getParams(); }
+  param_iterator param_end() { return getParams() + NumParams; }
   // This method returns and of the parameters which are part of the selector
   // name mangling requirements.
-  param_iterator sel_param_end() const { 
-    return ParamInfo.begin() + getSelector().getNumArgs(); 
+  param_const_iterator sel_param_end() const { 
+    return param_begin() + getSelector().getNumArgs(); 
   }
 
-  void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num) {
-    ParamInfo.set(List, Num, C);
-  }
+  void setMethodParams(ASTContext &C,
+                       ArrayRef<ParmVarDecl*> Params,
+                       ArrayRef<SourceLocation> SelLocs);
 
   // Iterator access to parameter types.
   typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
-  typedef llvm::mapped_iterator<param_iterator, deref_fun> arg_type_iterator;
+  typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
+      arg_type_iterator;
 
   arg_type_iterator arg_type_begin() const {
     return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
@@ -331,6 +402,9 @@ public:
   static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
     return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
   }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// ObjCContainerDecl - Represents a container for method declarations.
index 96185aa654e69de18cf4f38d1479f59722b0c6f3..55726eb4ae65abdf05f5b27d44e5a0018867765e 100644 (file)
@@ -360,12 +360,12 @@ public:
     QualType ArgType;
     if (isImplicitProperty()) {
       const ObjCMethodDecl *Setter = getImplicitPropertySetter();
-      ObjCMethodDecl::param_iterator P = Setter->param_begin(); 
+      ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 
       ArgType = (*P)->getType();
     } else {
       if (ObjCPropertyDecl *PDecl = getExplicitProperty())
         if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
-          ObjCMethodDecl::param_iterator P = Setter->param_begin(); 
+          ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 
           ArgType = (*P)->getType();
         }
       if (ArgType.isNull())
index b9b058d55b30730c423e6e43592c441223a2e2a5..cd43a5c49c55730d9f625decc4d6f5bf958ae77b 100644 (file)
@@ -21,6 +21,7 @@ namespace clang {
   class Selector;
   class SourceLocation;
   class Expr;
+  class ParmVarDecl;
 
 /// \brief Whether all locations of the selector identifiers are in a
 /// "standard" position.
@@ -59,6 +60,24 @@ SourceLocation getStandardSelectorLoc(unsigned Index,
                                       ArrayRef<Expr *> Args,
                                       SourceLocation EndLoc);
 
+/// \brief Returns true if all \arg SelLocs are in a "standard" location.
+SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
+                                              ArrayRef<SourceLocation> SelLocs,
+                                              ArrayRef<ParmVarDecl *> Args,
+                                              SourceLocation EndLoc);
+
+/// \brief Get the "standard" location of a selector identifier, e.g:
+/// For nullary selectors, immediately before ']': "[foo release]"
+///
+/// \param WithArgSpace if true the standard location is with a space apart
+/// before arguments: "-(id)first: (int)x second: (int)y;"
+/// If false: "-(id)first:(int)x second:(int)y;"
+SourceLocation getStandardSelectorLoc(unsigned Index,
+                                      Selector Sel,
+                                      bool WithArgSpace,
+                                      ArrayRef<ParmVarDecl *> Args,
+                                      SourceLocation EndLoc);
+
 } // end namespace clang
 
 #endif
index 0f6df3175518415944c551f8f61d36b0edade436..5e0c78409dae506f4b6a8fc53af6d94031fcbe3a 100644 (file)
@@ -3994,7 +3994,7 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
   // The first two arguments (self and _cmd) are pointers; account for
   // their size.
   CharUnits ParmOffset = 2 * PtrSize;
-  for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(),
+  for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(),
        E = Decl->sel_param_end(); PI != E; ++PI) {
     QualType PType = (*PI)->getType();
     CharUnits sz = getObjCEncodingTypeSize(PType);
@@ -4011,9 +4011,9 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
 
   // Argument types.
   ParmOffset = 2 * PtrSize;
-  for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(),
+  for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(),
        E = Decl->sel_param_end(); PI != E; ++PI) {
-    ParmVarDecl *PVDecl = *PI;
+    const ParmVarDecl *PVDecl = *PI;
     QualType PType = PVDecl->getOriginalType();
     if (const ArrayType *AT =
           dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
index 7c866cd88c997f9326619f018d9bcedd44c670fc..476e83aae69b22a25caa1c9ce2e75f45796496a0 100644 (file)
@@ -2923,7 +2923,6 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
     = ObjCMethodDecl::Create(Importer.getToContext(),
                              Loc,
                              Importer.Import(D->getLocEnd()),
-                             /*FIXME:*/ ArrayRef<SourceLocation>(),
                              Name.getObjCSelector(),
                              ResultTy, ResultTInfo, DC,
                              D->isInstanceMethod(),
@@ -2955,8 +2954,9 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
     ToParams[I]->setOwningFunction(ToMethod);
     ToMethod->addDecl(ToParams[I]);
   }
-  ToMethod->setMethodParams(Importer.getToContext(), 
-                            ToParams.data(), ToParams.size());
+  SmallVector<SourceLocation, 12> SelLocs;
+  D->getSelectorLocs(SelLocs);
+  ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs); 
 
   ToMethod->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, ToMethod);
index 0e1e833d2fd9ff61661cb4be2229335c08a97cb2..d7775d5aadea9f48c91597fcac65290eae4f3c15 100644 (file)
@@ -332,7 +332,6 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
                                        SourceLocation beginLoc,
                                        SourceLocation endLoc,
-                                       ArrayRef<SourceLocation> SelLocs,
                                        Selector SelInfo, QualType T,
                                        TypeSourceInfo *ResultTInfo,
                                        DeclContext *contextDecl,
@@ -352,6 +351,42 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
                                 HasRelatedResultType);
 }
 
+void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
+                                         ArrayRef<ParmVarDecl*> Params,
+                                         ArrayRef<SourceLocation> SelLocs) {
+  ParamsAndSelLocs = 0;
+  NumParams = Params.size();
+  if (Params.empty() && SelLocs.empty())
+    return;
+
+  unsigned Size = sizeof(ParmVarDecl *) * NumParams +
+                  sizeof(SourceLocation) * SelLocs.size();
+  ParamsAndSelLocs = C.Allocate(Size);
+  std::copy(Params.begin(), Params.end(), getParams());
+  std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
+}
+
+void ObjCMethodDecl::getSelectorLocs(
+                               SmallVectorImpl<SourceLocation> &SelLocs) const {
+  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
+    SelLocs.push_back(getSelectorLoc(i));
+}
+
+void ObjCMethodDecl::setMethodParams(ASTContext &C,
+                                     ArrayRef<ParmVarDecl*> Params,
+                                     ArrayRef<SourceLocation> SelLocs) {
+  assert((!SelLocs.empty() || isImplicit()) &&
+         "No selector locs for non-implicit method");
+  if (isImplicit())
+    return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
+
+  SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params, EndLoc);
+  if (SelLocsKind != SelLoc_NonStandard)
+    return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
+
+  setParamsAndSelLocs(C, Params, SelLocs);
+}
+
 /// \brief A definition will return its interface declaration.
 /// An interface declaration will return its definition.
 /// Otherwise it will return itself.
index cafb105e996ab3a5b5435257e7f2fc8a44e55cf2..9a44b387dd8112586bd12fa432bf3b78b8e9e808 100644 (file)
@@ -52,6 +52,12 @@ SourceLocation getArgLoc<Expr>(Expr *Arg) {
   return Arg->getLocStart();
 }
 
+template <>
+SourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) {
+  // -1 to point to left paren of the method parameter's type.
+  return Arg->getLocStart().getLocWithOffset(-1);
+}
+
 template <typename T>
 SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) {
   return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation();
@@ -100,3 +106,20 @@ SourceLocation clang::getStandardSelectorLoc(unsigned Index,
   return getStandardSelLoc(Index, Sel, WithArgSpace,
                            getArgLoc(Index, Args), EndLoc);
 }
+
+SelectorLocationsKind
+clang::hasStandardSelectorLocs(Selector Sel,
+                               ArrayRef<SourceLocation> SelLocs,
+                               ArrayRef<ParmVarDecl *> Args,
+                               SourceLocation EndLoc) {
+  return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
+}
+
+SourceLocation clang::getStandardSelectorLoc(unsigned Index,
+                                             Selector Sel,
+                                             bool WithArgSpace,
+                                             ArrayRef<ParmVarDecl *> Args,
+                                             SourceLocation EndLoc) {
+  return getStandardSelLoc(Index, Sel, WithArgSpace,
+                           getArgLoc(Index, Args), EndLoc);
+}
index 665263d55056bcf217bfa7c414e7f0bf0112783f..eb0dcf3bef98e03d96df82b253c03f9c5f79ef6b 100644 (file)
@@ -184,7 +184,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
   ArgTys.push_back(Context.getCanonicalParamType(MD->getSelfDecl()->getType()));
   ArgTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
   // FIXME: Kill copy?
-  for (ObjCMethodDecl::param_iterator i = MD->param_begin(),
+  for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
          e = MD->param_end(); i != e; ++i) {
     ArgTys.push_back(Context.getCanonicalParamType((*i)->getType()));
   }
index bb9cbd2602f257edd75c04fbd169ca8ab86a9ce6..6938a76a804a8046cdfe1d98339c98dec14ba020 100644 (file)
@@ -1660,7 +1660,7 @@ llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl * D, QualType FnTyp
     // "cmd" pointer is always second argument.
     Elts.push_back(getOrCreateType(OMethod->getCmdDecl()->getType(), F));
     // Get rest of the arguments.
-    for (ObjCMethodDecl::param_iterator PI = OMethod->param_begin(), 
+    for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(), 
            PE = OMethod->param_end(); PI != PE; ++PI)
       Elts.push_back(getOrCreateType((*PI)->getType(), F));
 
index 96ab3dcd68650e8f15e7923dee4f6b864cf8e67d..72e0c30524037af5394fd3abe122eb516eeed14e 100644 (file)
@@ -313,7 +313,7 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
   args.push_back(OMD->getSelfDecl());
   args.push_back(OMD->getCmdDecl());
 
-  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
+  for (ObjCMethodDecl::param_const_iterator PI = OMD->param_begin(),
        E = OMD->param_end(); PI != E; ++PI)
     args.push_back(*PI);
 
index 6e8e439107efa05a7af5ce0067ff528cd44f93ac..25e6bb3e239d365df4c5fea17916da1e4df31dfb 100644 (file)
@@ -2134,7 +2134,6 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
     Selector cxxSelector = getContext().Selectors.getSelector(0, &II);
     ObjCMethodDecl *DTORMethod =
       ObjCMethodDecl::Create(getContext(), D->getLocation(), D->getLocation(),
-                             ArrayRef<SourceLocation>(),
                              cxxSelector, getContext().VoidTy, 0, D,
                              /*isInstance=*/true, /*isVariadic=*/false,
                           /*isSynthesized=*/true, /*isImplicitlyDeclared=*/true,
@@ -2155,7 +2154,6 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
   ObjCMethodDecl *CTORMethod = ObjCMethodDecl::Create(getContext(), 
                                                 D->getLocation(),
                                                 D->getLocation(),
-                                                ArrayRef<SourceLocation>(),
                                                 cxxSelector,
                                                 getContext().getObjCIdType(), 0, 
                                                 D, /*isInstance=*/true,
index f4b6ce92e5d3d42105911e5d655790f0b31129d2..2988f118986d59725d38ae0d6eb8f77d9e9ae1ef 100644 (file)
@@ -2003,7 +2003,8 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
   mergeDeclAttributes(newMethod, oldMethod, Context, mergeDeprecation);
 
   // Merge attributes from the parameters.
-  for (ObjCMethodDecl::param_iterator oi = oldMethod->param_begin(),
+  ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin();
+  for (ObjCMethodDecl::param_iterator
          ni = newMethod->param_begin(), ne = newMethod->param_end();
        ni != ne; ++ni, ++oi)
     mergeParamDeclAttributes(*ni, *oi, Context);
index 3a34ffb5433e2d2342600529dc9ee817ef746077..b4def893af85592eb5b7d4162c585b1eb73f7291 100644 (file)
@@ -171,10 +171,11 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
         Diag(Overridden->getLocation(), diag::note_previous_decl) 
         << "method";
     }
-    for (ObjCMethodDecl::param_iterator oi = Overridden->param_begin(),
-         ni = NewMethod->param_begin(), ne = NewMethod->param_end();
+    ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin();
+    for (ObjCMethodDecl::param_iterator
+           ni = NewMethod->param_begin(), ne = NewMethod->param_end();
          ni != ne; ++ni, ++oi) {
-      ParmVarDecl *oldDecl = (*oi);
+      const ParmVarDecl *oldDecl = (*oi);
       ParmVarDecl *newDecl = (*ni);
       if (newDecl->hasAttr<NSConsumedAttr>() != 
           oldDecl->hasAttr<NSConsumedAttr>()) {
@@ -1860,12 +1861,12 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
          != right->hasAttr<NSConsumesSelfAttr>()))
     return false;
 
-  ObjCMethodDecl::param_iterator
+  ObjCMethodDecl::param_const_iterator
     li = left->param_begin(), le = left->param_end(), ri = right->param_begin();
 
   for (; li != le; ++li, ++ri) {
     assert(ri != right->param_end() && "Param mismatch");
-    ParmVarDecl *lparm = *li, *rparm = *ri;
+    const ParmVarDecl *lparm = *li, *rparm = *ri;
 
     if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType()))
       return false;
@@ -2527,7 +2528,7 @@ Decl *Sema::ActOnMethodDeclaration(
   }
 
   ObjCMethodDecl* ObjCMethod =
-    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, SelectorLocs, Sel,
+    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel,
                            resultDeclType,
                            ResultTInfo,
                            CurContext,
@@ -2610,7 +2611,7 @@ Decl *Sema::ActOnMethodDeclaration(
     Params.push_back(Param);
   }
   
-  ObjCMethod->setMethodParams(Context, Params.data(), Params.size());
+  ObjCMethod->setMethodParams(Context, Params, SelectorLocs);
   ObjCMethod->setObjCDeclQualifier(
     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
 
index d5d073fd6fa6af98379e03919a0588b6c14c31f9..1675568a56a3dcc00578964f996a7080467c4b5a 100644 (file)
@@ -7412,7 +7412,7 @@ void Sema::ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS,
     // setter, RHS expression is being passed to the setter argument. So,
     // type conversion (and comparison) is RHS to setter's argument type.
     if (const ObjCMethodDecl *SetterMD = PropRef->getImplicitPropertySetter()) {
-      ObjCMethodDecl::param_iterator P = SetterMD->param_begin();
+      ObjCMethodDecl::param_const_iterator P = SetterMD->param_begin();
       LHSTy = (*P)->getType();
       Consumed = (getLangOptions().ObjCAutoRefCount &&
                   (*P)->hasAttr<NSConsumedAttr>());
@@ -7431,7 +7431,7 @@ void Sema::ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS,
     const ObjCMethodDecl *setter
       = PropRef->getExplicitProperty()->getSetterMethodDecl();
     if (setter) {
-      ObjCMethodDecl::param_iterator P = setter->param_begin();
+      ObjCMethodDecl::param_const_iterator P = setter->param_begin();
       LHSTy = (*P)->getType();
       Consumed = (*P)->hasAttr<NSConsumedAttr>();
     }
index a6f21fbf96399641f7c8ce86039bab350f5d5075..80c440907489a79eba8ea23160c82b73966c5575 100644 (file)
@@ -1518,7 +1518,6 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
       property->getLocation();
 
     GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc,
-                             ArrayRef<SourceLocation>(),
                              property->getGetterName(),
                              property->getType(), 0, CD, /*isInstance=*/true,
                              /*isVariadic=*/false, /*isSynthesized=*/true,
@@ -1556,7 +1555,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
         property->getLocation();
 
       SetterMethod =
-        ObjCMethodDecl::Create(Context, Loc, Loc, ArrayRef<SourceLocation>(),
+        ObjCMethodDecl::Create(Context, Loc, Loc,
                                property->getSetterName(), Context.VoidTy, 0,
                                CD, /*isInstance=*/true, /*isVariadic=*/false,
                                /*isSynthesized=*/true,
@@ -1577,7 +1576,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
                                                   SC_None,
                                                   SC_None,
                                                   0);
-      SetterMethod->setMethodParams(Context, &Argument, 1);
+      SetterMethod->setMethodParams(Context, Argument,
+                                    ArrayRef<SourceLocation>());
 
       AddPropertyAttrs(*this, SetterMethod, property);
 
index f370f866867913bb83196621062d127526dd7120..360fcabf51ca7c8ea96847c79017328b3b6da8e3 100644 (file)
@@ -493,7 +493,15 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
     Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
-  MD->setMethodParams(Reader.getContext(), Params.data(), NumParams);
+
+  MD->SelLocsKind = Record[Idx++];
+  unsigned NumStoredSelLocs = Record[Idx++];
+  SmallVector<SourceLocation, 16> SelLocs;
+  SelLocs.reserve(NumStoredSelLocs);
+  for (unsigned i = 0; i != NumStoredSelLocs; ++i)
+    SelLocs.push_back(ReadSourceLocation(Record, Idx));
+
+  MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
 }
 
 void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
@@ -1614,7 +1622,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
 
   case DECL_OBJC_METHOD:
     D = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
-                               ArrayRef<SourceLocation>(),
                                Selector(), QualType(), 0, 0);
     break;
   case DECL_OBJC_INTERFACE:
index 77fc3f0988f716f4c0f4bef578b0045a91219732..62459f7d3c0743febb8074d40a02e6d4bed850e0 100644 (file)
@@ -414,6 +414,14 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
   for (ObjCMethodDecl::param_iterator P = D->param_begin(),
                                    PEnd = D->param_end(); P != PEnd; ++P)
     Writer.AddDeclRef(*P, Record);
+
+  Record.push_back(D->SelLocsKind);
+  unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
+  SourceLocation *SelLocs = D->getStoredSelLocs();
+  Record.push_back(NumStoredSelLocs);
+  for (unsigned i = 0; i != NumStoredSelLocs; ++i)
+    Writer.AddSourceLocation(SelLocs[i], Record);
+
   Code = serialization::DECL_OBJC_METHOD;
 }
 
index 6b2701145ca36c571925d9eb0e8b3469c7cc4e07..3e4a49415cebd656406d3e11ac804d3ef577078c 100644 (file)
@@ -60,7 +60,7 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D,
     II = &D->getASTContext().Idents.get("NSError"); 
 
   bool hasNSError = false;
-  for (ObjCMethodDecl::param_iterator
+  for (ObjCMethodDecl::param_const_iterator
          I = D->param_begin(), E = D->param_end(); I != E; ++I)  {
     if (IsNSError((*I)->getType(), II)) {
       hasNSError = true;
index 0a23d5b6bb81676ba852c67facffb18a72fa03fc..10a9c2f2094fe498a0c26be72e6993e747bfe785 100644 (file)
@@ -1198,7 +1198,8 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
   
   // Effects on the parameters.
   unsigned parm_idx = 0;
-  for (ObjCMethodDecl::param_iterator pi=MD->param_begin(), pe=MD->param_end();
+  for (ObjCMethodDecl::param_const_iterator
+         pi=MD->param_begin(), pe=MD->param_end();
        pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
     if (pd->getAttr<NSConsumedAttr>()) {
@@ -1244,9 +1245,9 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl *MD,
     // Delegates are a frequent form of false positives with the retain
     // count checker.
     unsigned i = 0;
-    for (ObjCMethodDecl::param_iterator I = MD->param_begin(),
+    for (ObjCMethodDecl::param_const_iterator I = MD->param_begin(),
          E = MD->param_end(); I != E; ++I, ++i)
-      if (ParmVarDecl *PD = *I) {
+      if (const ParmVarDecl *PD = *I) {
         QualType Ty = Ctx.getCanonicalType(PD->getType());
         if (Ty.getLocalUnqualifiedType() == Ctx.VoidPtrTy)
           ScratchArgs = AF.add(ScratchArgs, i, StopTracking);