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
/// 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; }
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; }
//===----------------------------------------------------------------------===//
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 {
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) {
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);
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;
}
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);
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,
// Category @implementation with no corresponding @interface.
// Create and install one.
CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, SourceLocation(),
+ SourceLocation(), SourceLocation(),
CatName);
CatIDecl->setClassInterface(IDecl);
CatIDecl->insertNextClassCategory();
// 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
{
}