From f4d331dd922f92478ebf30e808c0ca97ce49418b Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 18 Oct 2007 22:09:03 +0000 Subject: [PATCH] Patch to rewrite ivar tables metadata for classes defined. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43151 91177308-0d34-0410-b5e6-96231b3b80d8 --- Driver/RewriteTest.cpp | 58 +++++++++++++++++++++++++++++++++++- Sema/SemaDecl.cpp | 5 ++-- include/clang/AST/DeclObjC.h | 12 ++++++-- 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 8954a19819..883482c67e 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -45,6 +45,7 @@ namespace { void RewriteFunctionBody(Stmt *S); void RewriteAtEncode(ObjCEncodeExpr *Exp); + void WriteObjcClassMetaData(ObjcImplementationDecl *IDecl); void WriteObjcMetaData(); ~RewriteTest(); @@ -119,7 +120,7 @@ void RewriteTest::RewriteFunctionBody(Stmt *S) { if (*CI) RewriteFunctionBody(*CI); } - + void RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) { // Create a new string expression. QualType StrType = Context->getPointerType(Context->CharTy); @@ -129,11 +130,66 @@ void RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) { delete Replacement; } +void RewriteTest::WriteObjcClassMetaData(ObjcImplementationDecl *IDecl) { + ObjcInterfaceDecl *CDecl = IDecl->getClassInterface(); + + if (IDecl->getImplDeclNumIvars() > 0 || + CDecl&& CDecl->getIntfDeclNumIvars() > 0) { + static bool objc_ivar = false; + + int NumIvars = IDecl->getImplDeclNumIvars() > 0 + ? IDecl->getImplDeclNumIvars() + : CDecl->getIntfDeclNumIvars(); + + if (!objc_ivar) { + /* struct _objc_ivar { + char *ivar_name; + char *ivar_type; + int ivar_offset; + }; + */ + printf("\nstruct _objc_ivar {\n"); + printf("\tchar *ivar_name;\n"); + printf("\tchar *ivar_type;\n"); + printf("\tint ivar_offset;\n"); + printf("};\n"); + objc_ivar = true; + } + + /* struct _objc_ivar_list { + int ivar_count; + struct _objc_ivar ivar_list[ivar_count]; + }; + */ + printf("\nstatic struct {\n"); + printf("\tint ivar_count;\n"); + printf("\tstruct _objc_ivar ivar_list[%d];\n", NumIvars); + printf("} _OBJC_INSTANCE_VARIABLES_%s " + "__attribute__ ((section (\"__OBJC, __instance_vars\")))= " + "{\n\t%d\n",IDecl->getName(), + NumIvars); + ObjcIvarDecl **Ivars = IDecl->getImplDeclIVars() + ? IDecl->getImplDeclIVars() + : CDecl->getIntfDeclIvars(); + for (int i = 0; i < NumIvars; i++) + // TODO: 1) ivar names may have to go to another section. 2) encode + // ivar_type type of each ivar . 3) compute and add ivar offset. + printf("\t,\"%s\", \"\", 0\n", Ivars[i]->getName()); + printf("};\n"); + } + +} + void RewriteTest::WriteObjcMetaData() { int ClsDefCount = ClassImplementation.size(); int CatDefCount = CategoryImplementation.size(); if (ClsDefCount == 0 && CatDefCount == 0) return; + + // For each defined class, write out all its meta data. + for (int i = 0; i < ClsDefCount; i++) + WriteObjcClassMetaData(ClassImplementation[i]); + // Write objc_symtab metadata /* struct _objc_symtab diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 5b54d8be7d..9c8ec7f3fa 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1225,8 +1225,6 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation( } } - ObjcImplementationDecl* IMPDecl = - new ObjcImplementationDecl(AtClassImplLoc, ClassName, SDecl); if (!IDecl) { // Legacy case of @implementation with no corresponding @interface. // Build, chain & install the interface decl into the identifier. @@ -1238,6 +1236,9 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation( TUScope->AddDecl(IDecl); } + ObjcImplementationDecl* IMPDecl = + new ObjcImplementationDecl(AtClassImplLoc, ClassName, IDecl, SDecl); + // Check that there is no duplicate implementation of this class. if (!ObjcImplementations.insert(ClassName)) Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName()); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index bbab58a324..b5d211f308 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -540,7 +540,9 @@ class ObjcCategoryImplDecl : public NamedDecl { /// from the class interface to the class implementation (but I digress:-) /// class ObjcImplementationDecl : public NamedDecl { - + /// Class interface for this category implementation + ObjcInterfaceDecl *ClassInterface; + /// Implementation Class's super class. ObjcInterfaceDecl *SuperClass; @@ -558,8 +560,10 @@ class ObjcImplementationDecl : public NamedDecl { public: ObjcImplementationDecl(SourceLocation L, IdentifierInfo *Id, - ObjcInterfaceDecl* superDecl) + ObjcInterfaceDecl *classInterface, + ObjcInterfaceDecl *superDecl) : NamedDecl(ObjcImplementation, L, Id), + ClassInterface(classInterface), SuperClass(superDecl), Ivars(0), NumIvars(-1), InstanceMethods(0), NumInstanceMethods(-1), @@ -571,6 +575,7 @@ public: void ObjcAddImplMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, ObjcMethodDecl **clsMethods, unsigned numClsMembers); + ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; } ObjcInterfaceDecl *getSuperClass() const { return SuperClass; } void setSuperClass(ObjcInterfaceDecl * superCls) @@ -581,6 +586,9 @@ public: ObjcMethodDecl **getClassMethods() const { return ClassMethods; } int getNumClassMethods() const { return NumClassMethods; } + + ObjcIvarDecl **getImplDeclIVars() const { return Ivars; } + int getImplDeclNumIvars() const { return NumIvars; } static bool classof(const Decl *D) { return D->getKind() == ObjcImplementation; -- 2.50.1