/// \brief The location of the category name in this declaration.
SourceLocation CategoryNameLoc;
+ /// class extension may have private ivars.
+ SourceLocation IvarLBraceLoc;
+ SourceLocation IvarRBraceLoc;
+
ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
- IdentifierInfo *Id, ObjCInterfaceDecl *IDecl)
+ IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
+ SourceLocation IvarLBraceLoc=SourceLocation(),
+ SourceLocation IvarRBraceLoc=SourceLocation())
: ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
ClassInterface(IDecl), NextClassCategory(0), HasSynthBitfield(false),
- CategoryNameLoc(CategoryNameLoc) {
+ CategoryNameLoc(CategoryNameLoc),
+ IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
}
public:
SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc,
IdentifierInfo *Id,
- ObjCInterfaceDecl *IDecl);
+ ObjCInterfaceDecl *IDecl,
+ SourceLocation IvarLBraceLoc=SourceLocation(),
+ SourceLocation IvarRBraceLoc=SourceLocation());
static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
+
+ void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
+ SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
+ void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
+ SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryDecl *D) { return true; }
virtual void anchor();
/// Implementation Class's super class.
ObjCInterfaceDecl *SuperClass;
+ /// @implementation may have private ivars.
+ SourceLocation IvarLBraceLoc;
+ SourceLocation IvarRBraceLoc;
+
/// Support for ivar initialization.
/// IvarInitializers - The arguments used to initialize the ivars
CXXCtorInitializer **IvarInitializers;
ObjCImplementationDecl(DeclContext *DC,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc, SourceLocation atStartLoc)
+ SourceLocation nameLoc, SourceLocation atStartLoc,
+ SourceLocation IvarLBraceLoc=SourceLocation(),
+ SourceLocation IvarRBraceLoc=SourceLocation())
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
- SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
- HasCXXStructors(false), HasSynthBitfield(false) {}
+ SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc),
+ IvarRBraceLoc(IvarRBraceLoc),
+ IvarInitializers(0), NumIvarInitializers(0),
+ HasCXXStructors(false), HasSynthBitfield(false){}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl,
SourceLocation nameLoc,
- SourceLocation atStartLoc);
+ SourceLocation atStartLoc,
+ SourceLocation IvarLBraceLoc=SourceLocation(),
+ SourceLocation IvarRBraceLoc=SourceLocation());
static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+ void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
+ SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
+ void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
+ SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
+
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
Loc,
Importer.Import(D->getCategoryNameLoc()),
Name.getAsIdentifierInfo(),
- ToInterface);
+ ToInterface,
+ Importer.Import(D->getIvarLBraceLoc()),
+ Importer.Import(D->getIvarRBraceLoc()));
ToCategory->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToCategory);
Importer.Imported(D, ToCategory);
Importer.ImportContext(D->getDeclContext()),
Iface, Super,
Importer.Import(D->getLocation()),
- Importer.Import(D->getAtStartLoc()));
+ Importer.Import(D->getAtStartLoc()),
+ Importer.Import(D->getIvarLBraceLoc()),
+ Importer.Import(D->getIvarRBraceLoc()));
if (D->getDeclContext() != D->getLexicalDeclContext()) {
DeclContext *LexicalDC
SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc,
IdentifierInfo *Id,
- ObjCInterfaceDecl *IDecl) {
+ ObjCInterfaceDecl *IDecl,
+ SourceLocation IvarLBraceLoc,
+ SourceLocation IvarRBraceLoc) {
ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
CategoryNameLoc, Id,
- IDecl);
+ IDecl,
+ IvarLBraceLoc, IvarRBraceLoc);
if (IDecl) {
// Link this category into its class's category list.
CatDecl->NextClassCategory = IDecl->getCategoryList();
ObjCInterfaceDecl *ClassInterface,
ObjCInterfaceDecl *SuperDecl,
SourceLocation nameLoc,
- SourceLocation atStartLoc) {
+ SourceLocation atStartLoc,
+ SourceLocation IvarLBraceLoc,
+ SourceLocation IvarRBraceLoc) {
if (ClassInterface && ClassInterface->hasDefinition())
ClassInterface = ClassInterface->getDefinition();
return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
- nameLoc, atStartLoc);
+ nameLoc, atStartLoc,
+ IvarLBraceLoc, IvarRBraceLoc);
}
ObjCImplementationDecl *
// FIXME: handle category headers that are declared across multiple lines.
ReplaceText(LocStart, 0, "// ");
-
+ if (CatDecl->getIvarLBraceLoc().isValid())
+ InsertText(CatDecl->getIvarLBraceLoc(), "// ");
for (ObjCCategoryDecl::ivar_iterator
I = CatDecl->ivar_begin(), E = CatDecl->ivar_end(); I != E; ++I) {
ObjCIvarDecl *Ivar = (*I);
SourceLocation LocStart = Ivar->getLocStart();
ReplaceText(LocStart, 0, "// ");
}
-
+ if (CatDecl->getIvarRBraceLoc().isValid())
+ InsertText(CatDecl->getIvarRBraceLoc(), "// ");
+
for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
E = CatDecl->prop_end(); I != E; ++I)
RewriteProperty(*I);
if (IMD) {
InsertText(IMD->getLocStart(), "// ");
- for (ObjCImplementationDecl::ivar_iterator
- I = IMD->ivar_begin(), E = IMD->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Ivar = (*I);
- SourceLocation LocStart = Ivar->getLocStart();
- ReplaceText(LocStart, 0, "// ");
+ if (IMD->getIvarLBraceLoc().isValid())
+ InsertText(IMD->getIvarLBraceLoc(), "// ");
+ for (ObjCImplementationDecl::ivar_iterator
+ I = IMD->ivar_begin(), E = IMD->ivar_end(); I != E; ++I) {
+ ObjCIvarDecl *Ivar = (*I);
+ SourceLocation LocStart = Ivar->getLocStart();
+ ReplaceText(LocStart, 0, "// ");
}
+ if (IMD->getIvarRBraceLoc().isValid())
+ InsertText(IMD->getIvarRBraceLoc(), "// ");
}
else
InsertText(CID->getLocStart(), "// ");
// Only it is in implementation's lexical context.
ClsFields[I]->setLexicalDeclContext(IMPDecl);
CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac);
+ IMPDecl->setIvarLBraceLoc(LBrac);
+ IMPDecl->setIvarRBraceLoc(RBrac);
} else if (ObjCCategoryDecl *CDecl =
dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
// case of ivars in class extension; all other cases have been
ClsFields[i]->setLexicalDeclContext(CDecl);
CDecl->addDecl(ClsFields[i]);
}
+ CDecl->setIvarLBraceLoc(LBrac);
+ CDecl->setIvarRBraceLoc(RBrac);
}
}
void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
VisitObjCContainerDecl(CD);
CD->setCategoryNameLoc(ReadSourceLocation(Record, Idx));
+ CD->setIvarLBraceLoc(ReadSourceLocation(Record, Idx));
+ CD->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
// Note that this category has been deserialized. We do this before
// deserializing the interface declaration, so that it will consider this
void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
VisitObjCImplDecl(D);
D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
+ D->setIvarLBraceLoc(ReadSourceLocation(Record, Idx));
+ D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
= Reader.ReadCXXCtorInitializers(F, Record, Idx);
D->setHasSynthBitfield(Record[Idx++]);
void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
VisitObjCContainerDecl(D);
Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
+ Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record);
+ Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
Writer.AddDeclRef(D->getClassInterface(), Record);
Record.push_back(D->protocol_size());
for (ObjCCategoryDecl::protocol_iterator
void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
VisitObjCImplDecl(D);
Writer.AddDeclRef(D->getSuperClass(), Record);
+ Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record);
+ Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
Writer.AddCXXCtorInitializers(D->IvarInitializers, D->NumIvarInitializers,
Record);
Record.push_back(D->hasSynthBitfield());
--- /dev/null
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+
+@protocol PROTO @end
+
+@interface empty_root @end
+
+@interface root_with_ivars
+{
+ id ROOT_IVAR;
+ id ROOT1_IVAR;
+}
+@end
+
+@interface MAXIMAL : root_with_ivars<PROTO>
+{
+ double D_IVAR;
+ double D_PROPERTY;
+}
+- (void) V_METH;
+@end
+
+@implementation MAXIMAL
+- (void) V_METH {}
+@end
+//=========================================
+@interface empty_class @end
+
+@implementation empty_class @end
+//=========================================
+@interface class_empty_root : empty_root @end
+
+@implementation class_empty_root @end
+//=========================================
+@interface class_with_ivars : empty_root
+{
+ int class_with_ivars_IVAR;
+}
+@end
+
+@implementation class_with_ivars @end
+//=========================================
+@interface class_has_no_ivar : root_with_ivars @end
+
+@implementation class_has_no_ivar @end
+
+//============================class needs to be synthesized here=====================
+@interface SUPER {
+@public
+ double divar;
+ SUPER *p_super;
+}
+@end
+
+@interface INTF @end
+
+@implementation INTF
+- (SUPER *) Meth : (SUPER *)arg {
+ return arg->p_super;
+}
+@end
--- /dev/null
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+
+@protocol P @end
+@protocol P1 @end
+@interface INTF
+{
+ id CLASS_IVAR;
+ id<P, P1> Q_IVAR;
+
+ void (^_block)(id<P>);
+ void (*_fptr)(void (^_block)(id<P>));
+ char CLASS_EXT_IVAR;
+ id<P, P1> (^ext_block)(id<P>, INTF<P,P1>*, INTF*);
+ id IMPL_IVAR;
+ double D_IMPL_IVAR;
+ INTF<P> *(*imp_fptr)(void (^_block)(id<P>, INTF<P,P1>*));
+ id arr[100];
+}
+@end
+
+@implementation INTF @end
+
+@interface MISC_INTF
+{
+ id CLASS_IVAR;
+ id<P, P1> Q_IVAR;
+
+ void (^_block)(id<P>);
+ void (*_fptr)(void (^_block)(id<P>));
+ unsigned int BF : 8;
+}
+@end
+
+@interface MISC_INTF()
+{
+ char CLASS_EXT_IVAR;
+ id<P, P1> (^ext_block)(id<P>, MISC_INTF<P,P1>*, MISC_INTF*);
+}
+@end
+
+@interface MISC_INTF() {
+ int II1;
+ double DD1; }
+@end
+
+@interface MISC_INTF() { int II2; double DD2; }
+@end
+
+@interface MISC_INTF() { int II3;
+ double DD3; }
+@end
+
+@interface MISC_INTF() { int II4; double DD4;
+}
+@end
+
+@implementation MISC_INTF
+{
+ id IMPL_IVAR;
+ double D_IMPL_IVAR;
+ MISC_INTF<P> *(*imp_fptr)(void (^_block)(id<P>, MISC_INTF<P,P1>*));
+}
+@end
--- /dev/null
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+
+@protocol ROOT @end
+
+@protocol P1 @end
+
+@protocol P2<ROOT> @end
+
+@class NSObject;
+
+@protocol PROTO <P1, P2>
+- (id) INST_METHOD;
++ (id) CLASS_METHOD : (id)ARG;
+@property id Prop_in_PROTO;
+@optional
+- (id) opt_instance_method;
++ (id) opt_class_method;
+@property (readonly, retain) NSObject *AnotherProperty;
+@required
+- (id) req;
+@optional
+- (id) X_opt_instance_method;
++ (id) X_opt_class_method;
+@end
+
+@interface INTF <PROTO, ROOT>
+@end
+
+@implementation INTF
+@end