]> granicus.if.org Git - clang/commitdiff
[AST/libclang] Fix the selector locations that are reported for a
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 16 Jun 2012 00:46:02 +0000 (00:46 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 16 Jun 2012 00:46:02 +0000 (00:46 +0000)
method definition that has its '{' attached to the method name without
a space.

With a method like:

-(id)meth{
.....
}

the logic in ObjCMethodDecl that determined the selector locations got
confused because it was initialized based on an end location for '{' but
that end location changed to '}' after the method was finished.

Fix this by having an immutable end location for the declarator and
for getLocEnd() get the end location from the body itself.

Fixes rdar://11659739.

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

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Sema/SemaDecl.cpp
lib/Serialization/ASTReaderDecl.cpp
test/Index/get-cursor.m
test/Index/overrides.m

index 5db0eca42adb267651f3f30dd75a2d5466adf162..1d82e1a1063bd3404d9fb5b738da1d94a777f317 100644 (file)
@@ -171,7 +171,7 @@ private:
   unsigned NumParams;
 
   /// List of attributes for this method declaration.
-  SourceLocation EndLoc; // the location of the ';' or '}'.
+  SourceLocation DeclEndLoc; // the location of the ';' or '{'.
 
   // The following are only used for method definitions, null otherwise.
   // FIXME: space savings opportunity, consider a sub-class.
@@ -242,7 +242,7 @@ private:
     SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0),
     MethodDeclType(T), ResultTInfo(ResultTInfo),
     ParamsAndSelLocs(0), NumParams(0),
-    EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {
+    DeclEndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {
     setImplicit(isImplicitlyDeclared);
   }
 
@@ -290,12 +290,16 @@ public:
   bool isRedeclaration() const { return IsRedeclaration; }
   void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
 
+  /// \brief Returns the location where the declarator ends. It will be
+  /// the location of ';' for a method declaration and the location of '{'
+  /// for a method definition.
+  SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
+
   // Location information, modeled after the Stmt API.
   SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
-  SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
-  void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY;
   virtual SourceRange getSourceRange() const LLVM_READONLY {
-    return SourceRange(getLocation(), EndLoc);
+    return SourceRange(getLocation(), getLocEnd());
   }
 
   SourceLocation getSelectorStartLoc() const {
@@ -310,7 +314,7 @@ public:
                                    getSelLocsKind() == SelLoc_StandardWithSpace,
                       llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
                                          NumParams),
-                                   EndLoc);
+                                   DeclEndLoc);
     return getStoredSelLocs()[Index];
   }
 
index b6b3f7d4c0af00a8ecea463cab841b2d4cf1c3df..37fb03914251de4c1864dde024417978f084544d 100644 (file)
@@ -451,7 +451,8 @@ void ObjCMethodDecl::setMethodParams(ASTContext &C,
   if (isImplicit())
     return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
 
-  SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params, EndLoc);
+  SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
+                                        DeclEndLoc);
   if (SelLocsKind != SelLoc_NonStandard)
     return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
 
@@ -523,6 +524,12 @@ ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
   return this;
 }
 
+SourceLocation ObjCMethodDecl::getLocEnd() const {
+  if (Stmt *Body = getBody())
+    return Body->getLocEnd();
+  return DeclEndLoc;
+}
+
 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
   ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
   if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
index 399f518fcc9ea0e26ea48c222195a48a7972d131..be62818c205f2ae4e462e070c0d59df843d7af48 100644 (file)
@@ -7634,8 +7634,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
   } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
     assert(MD == getCurMethodDecl() && "Method parsing confused");
     MD->setBody(Body);
-    if (Body)
-      MD->setEndLoc(Body->getLocEnd());
     if (!MD->isInvalidDecl()) {
       DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
       DiagnoseSizeOfParametersAndReturnValue(MD->param_begin(), MD->param_end(),
index d9e060c91df8d5679ee94f8ab4e2c148656bedc1..f5f9ba25988a719a85da8489f591aa160df645c5 100644 (file)
@@ -655,7 +655,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
   MD->SetRelatedResultType(Record[Idx++]);
   MD->setResultType(Reader.readType(F, Record, Idx));
   MD->setResultTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
-  MD->setEndLoc(ReadSourceLocation(Record, Idx));
+  MD->DeclEndLoc = ReadSourceLocation(Record, Idx);
   unsigned NumParams = Record[Idx++];
   SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
index 32ac53fe3bf99a1322b88c8b43fe51fb47e91ba0..d3da9ec197268cedcc01caf49af39fa78f3dc200 100644 (file)
@@ -82,6 +82,13 @@ void foo3(Test3 *test3) {
 @implementation Test5
 @synthesize prop1, prop2;
 @dynamic prop3, prop4;
+
+-(id)meth1 {
+  return 0;
+}
+-(id)meth2{
+  return 0;
+}
 @end
 
 // RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s
@@ -124,3 +131,7 @@ void foo3(Test3 *test3) {
 // CHECK-MULTISYNTH: 83:20 ObjCSynthesizeDecl=prop2:77:23 (Definition) Extent=[83:1 - 83:25] Spelling=prop2 ([83:20 - 83:25])
 // CHECK-MULTISYNTH: 84:10 ObjCDynamicDecl=prop3:78:23 (Definition) Extent=[84:1 - 84:15] Spelling=prop3 ([84:10 - 84:15])
 // CHECK-MULTISYNTH: 84:17 ObjCDynamicDecl=prop4:79:23 (Definition) Extent=[84:1 - 84:22] Spelling=prop4 ([84:17 - 84:22])
+
+// RUN: c-index-test -cursor-at=%s:86:7 -cursor-at=%s:89:7 %s | FileCheck -check-prefix=CHECK-SELECTORLOC %s
+// CHECK-SELECTORLOC: 86:6 ObjCInstanceMethodDecl=meth1:86:6 (Definition) Extent=[86:1 - 88:2] Spelling=meth1 ([86:6 - 86:11]) Selector index=0
+// CHECK-SELECTORLOC: 89:6 ObjCInstanceMethodDecl=meth2:89:6 (Definition) Extent=[89:1 - 91:2] Spelling=meth2 ([89:6 - 89:11]) Selector index=0
index f0f3e5fedbf61cce227175ddacd0a5b49ac37194..d0447b74739d8417464a55dcef7a24c5664e74e3 100644 (file)
 // CHECK: overrides.m:81:23: ObjCInstanceMethodDecl=setProp::81:23 [Overrides @77:8] Extent=[81:23 - 81:27]
 // CHECK: overrides.m:92:8: ObjCInstanceMethodDecl=meth:92:8 Extent=[92:1 - 92:13]
 // CHECK: overrides.m:95:17: ObjCImplementationDecl=I5:95:17 (Definition) Extent=[95:1 - 97:2]
-// CHECK: overrides.m:96:9: ObjCInstanceMethodDecl=meth:96:9 (Definition) [Overrides @92:8] Extent=[96:1 - 96:14]
+// CHECK: overrides.m:96:8: ObjCInstanceMethodDecl=meth:96:8 (Definition) [Overrides @92:8] Extent=[96:1 - 96:14]