]> granicus.if.org Git - clang/commitdiff
Improve location information for Objective-C category declarations. We
authorDouglas Gregor <dgregor@apple.com>
Sat, 16 Jan 2010 16:38:58 +0000 (16:38 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 16 Jan 2010 16:38:58 +0000 (16:38 +0000)
previously only had a single location (the @ in @interface); now we
know where the @ is (for the start of the declaration), where the
class name is (that's the normal "location" now for diagnostics), and
where the category name is. Also, eliminated the redundant "end"
location, since ObjCContainerDecl already has better @end information.

The only XFAIL'd test is temporary; will un-XFAIL-it once I've taught
CIndex how to use the new locations.

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

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Frontend/PCHReaderDecl.cpp
lib/Frontend/PCHWriterDecl.cpp
lib/Sema/SemaDeclObjC.cpp
test/Index/c-index-api-loadTU-test.m

index 9dc5abb3ad6efa24cac20640ab4fbdcde818c7f5..1b25b40ff23662c7de49cf540d579ba994b2964a 100644 (file)
@@ -880,16 +880,26 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
   /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
   ObjCCategoryDecl *NextClassCategory;
 
-  SourceLocation EndLoc; // marks the '>' or identifier.
+  /// \brief The location of the '@' in '@interface'
+  SourceLocation AtLoc;
+
+  /// \brief The location of the category name in this declaration.
+  SourceLocation CategoryNameLoc;
 
-  ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
-    : ObjCContainerDecl(ObjCCategory, DC, L, Id),
-      ClassInterface(0), NextClassCategory(0){
+  ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, 
+                   SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
+                   IdentifierInfo *Id)
+    : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id),
+      ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc), 
+      CategoryNameLoc(CategoryNameLoc) {
   }
 public:
 
   static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
-                                  SourceLocation L, IdentifierInfo *Id);
+                                  SourceLocation AtLoc, 
+                                  SourceLocation ClassNameLoc,
+                                  SourceLocation CategoryNameLoc,
+                                  IdentifierInfo *Id);
 
   ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
   const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
@@ -929,10 +939,16 @@ public:
     NextClassCategory = ClassInterface->getCategoryList();
     ClassInterface->setCategoryList(this);
   }
-  // Location information, modeled after the Stmt API.
-  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
-  SourceLocation getLocEnd() const { return EndLoc; }
-  void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation At) { AtLoc = At; }
+
+  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
+  void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(AtLoc, getAtEndRange().getEnd());
+  }
 
   static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
   static bool classof(const ObjCCategoryDecl *D) { return true; }
index 047c3492177daf0d21f613cdcd2324d8e0655001..40cbfd2d006a00f42626b2207df0fea1baf80318 100644 (file)
@@ -674,9 +674,11 @@ void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
 //===----------------------------------------------------------------------===//
 
 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
-                                           SourceLocation L,
+                                           SourceLocation AtLoc, 
+                                           SourceLocation ClassNameLoc,
+                                           SourceLocation CategoryNameLoc,
                                            IdentifierInfo *Id) {
-  return new (C) ObjCCategoryDecl(DC, L, Id);
+  return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
 }
 
 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
index 138ad8226f12e26887932d85705e7cdc97d7aa4a..8268bb2b511bb699a126a52c00c57cf892171025 100644 (file)
@@ -315,7 +315,8 @@ void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
   CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
                       *Reader.getContext());
   CD->setNextClassCategory(cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
-  CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setCategoryNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
 
 void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
@@ -691,7 +692,8 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
     D = ObjCForwardProtocolDecl::Create(*Context, 0, SourceLocation());
     break;
   case pch::DECL_OBJC_CATEGORY:
-    D = ObjCCategoryDecl::Create(*Context, 0, SourceLocation(), 0);
+    D = ObjCCategoryDecl::Create(*Context, 0, SourceLocation(), 
+                                 SourceLocation(), SourceLocation(), 0);
     break;
   case pch::DECL_OBJC_CATEGORY_IMPL:
     D = ObjCCategoryImplDecl::Create(*Context, 0, SourceLocation(), 0, 0);
index 6f4cd8f36177940a7108f0141b969dbc3cb1abd6..068fd41a826057ab357b1c38a6f8e2f6c512d5f7 100644 (file)
@@ -302,7 +302,8 @@ void PCHDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
        PL != PLEnd; ++PL)
     Writer.AddSourceLocation(*PL, Record);
   Writer.AddDeclRef(D->getNextClassCategory(), Record);
-  Writer.AddSourceLocation(D->getLocEnd(), Record);
+  Writer.AddSourceLocation(D->getAtLoc(), Record);
+  Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
   Code = pch::DECL_OBJC_CATEGORY;
 }
 
index cfea87504d45d562d59ac953dfbb80bd4608eb7d..ba21df776e175b53dc73e24219f88aaedfc8e14a 100644 (file)
@@ -597,7 +597,8 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
                             const SourceLocation *ProtoLocs,
                             SourceLocation EndProtoLoc) {
   ObjCCategoryDecl *CDecl =
-    ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName);
+    ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, ClassLoc,
+                             CategoryLoc, CategoryName);
   // FIXME: PushOnScopeChains?
   CurContext->addDecl(CDecl);
 
@@ -631,7 +632,6 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
   if (NumProtoRefs) {
     CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs, 
                            ProtoLocs, Context);
-    CDecl->setLocEnd(EndProtoLoc);
     // Protocols in the class extension belong to the class.
     if (!CDecl->getIdentifier())
      IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs, 
@@ -658,6 +658,7 @@ Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
       // Category @implementation with no corresponding @interface.
       // Create and install one.
       CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
                                           CatName);
       CatIDecl->setClassInterface(IDecl);
       CatIDecl->insertNextClassCategory();
index 1b2dcf4e33d1eb8315cb9289d7606b56a090739a..7ab435fa8591026206d3cad76d947bed052efec7 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
 // RUN: c-index-test -test-load-tu %t.ast all | FileCheck %s
-
+// XFAIL: *
 @interface Foo 
 {
 }