aboutsummaryrefslogtreecommitdiff
path: root/Driver/RewriteTest.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2007-10-26 19:46:17 +0000
committerFariborz Jahanian <fjahanian@apple.com>2007-10-26 19:46:17 +0000
commit26e4cd331c389a9b7d51c91981a7a10c8a909bf4 (patch)
treeeb358241392ede1e55fb3f25ec08d0e6528f7286 /Driver/RewriteTest.cpp
parentabad06cfd01edbd6ffe80856304b5ad991b67d08 (diff)
Patch to synthesize computation of Ivar offset in rewritten c file.
Thanks to Steve N. to point out using of offsetof for this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43391 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/RewriteTest.cpp')
-rw-r--r--Driver/RewriteTest.cpp89
1 files changed, 83 insertions, 6 deletions
diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp
index 3e1c3d799b..95b05ba0f4 100644
--- a/Driver/RewriteTest.cpp
+++ b/Driver/RewriteTest.cpp
@@ -18,6 +18,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
using namespace clang;
using llvm::utostr;
@@ -30,6 +31,7 @@ namespace {
SourceLocation LastIncLoc;
llvm::SmallVector<ObjcImplementationDecl *, 8> ClassImplementation;
llvm::SmallVector<ObjcCategoryImplDecl *, 8> CategoryImplementation;
+ llvm::SmallPtrSet<ObjcInterfaceDecl*, 8> ObjcSynthesizedStructs;
FunctionDecl *MsgSendFunctionDecl;
FunctionDecl *GetClassFunctionDecl;
@@ -64,6 +66,7 @@ namespace {
CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
Expr **args, unsigned nargs);
// Metadata emission.
+ void HandleObjcMetaDataEmission();
void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
std::string &Result);
@@ -82,6 +85,13 @@ namespace {
const char *prefix,
const char *ClassName,
std::string &Result);
+ void SynthesizeObjcInternalStruct(ObjcInterfaceDecl *CDecl,
+ std::string &Result);
+ void RewriteObjcInternalStructs(ObjcImplementationDecl *IDecl,
+ std::string &Result);
+ void SynthesizeIvarOffsetComputation(ObjcImplementationDecl *IDecl,
+ ObjcIvarDecl *ivar,
+ std::string &Result);
void WriteObjcMetaData(std::string &Result);
};
}
@@ -151,7 +161,12 @@ RewriteTest::~RewriteTest() {
} else {
printf("No changes\n");
}
-
+
+}
+
+/// HandleObjcMetaDataEmission - main routine to generate objective-c's
+/// metadata.
+void RewriteTest::HandleObjcMetaDataEmission() {
// Rewrite Objective-c meta data*
std::string ResultStr;
WriteObjcMetaData(ResultStr);
@@ -363,6 +378,47 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
return MessExp;
}
+/// SynthesizeObjcInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteTest::SynthesizeObjcInternalStruct(ObjcInterfaceDecl *CDecl,
+ std::string &Result) {
+ assert(CDecl && "Class missing in SynthesizeObjcInternalStruct");
+ assert(CDecl->getName() && "Name missing in SynthesizeObjcInternalStruct");
+ ObjcInterfaceDecl *RCDecl = CDecl->getSuperClass();
+ if (RCDecl && !ObjcSynthesizedStructs.count(RCDecl)) {
+ // Do it for the root
+ SynthesizeObjcInternalStruct(RCDecl, Result);
+ }
+
+ int NumIvars = CDecl->getIntfDeclNumIvars();
+ if (NumIvars <= 0 && (!RCDecl || !ObjcSynthesizedStructs.count(RCDecl)))
+ return;
+
+ Result += "\nstruct _interface_";
+ Result += CDecl->getName();
+ Result += " {\n";
+ if (RCDecl && ObjcSynthesizedStructs.count(RCDecl)) {
+ Result += "\tstruct _interface_";
+ Result += RCDecl->getName();
+ Result += " _";
+ Result += RCDecl->getName();
+ Result += ";\n";
+ }
+
+ ObjcIvarDecl **Ivars = CDecl->getIntfDeclIvars();
+ for (int i = 0; i < NumIvars; i++) {
+ Result += "\t";
+ std::string Name = Ivars[i]->getName();
+ Ivars[i]->getType().getAsStringInternal(Name);
+ Result += Name;
+ Result += ";\n";
+ }
+ Result += "};\n";
+ // Mark this struct as having been generated.
+ if (!ObjcSynthesizedStructs.insert(CDecl))
+ assert(true && "struct already synthesize- SynthesizeObjcInternalStruct");
+}
+
// RewriteObjcMethodsMetaData - Rewrite methods metadata for instance or
/// class methods.
void RewriteTest::RewriteObjcMethodsMetaData(ObjcMethodDecl **Methods,
@@ -687,6 +743,18 @@ void RewriteTest::RewriteObjcCategoryImplDecl(ObjcCategoryImplDecl *IDecl,
Result += "\t, sizeof(struct _objc_category), 0\n};\n";
}
+/// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteTest::SynthesizeIvarOffsetComputation(ObjcImplementationDecl *IDecl,
+ ObjcIvarDecl *ivar,
+ std::string &Result) {
+ Result += "offsetof(struct _interface_";
+ Result += IDecl->getName();
+ Result += ", ";
+ Result += ivar->getName();
+ Result += ")";
+}
+
//===----------------------------------------------------------------------===//
// Meta Data Emission
//===----------------------------------------------------------------------===//
@@ -701,6 +769,8 @@ void RewriteTest::RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
: (CDecl ? CDecl->getIntfDeclNumIvars() : 0);
if (NumIvars > 0) {
+ SynthesizeObjcInternalStruct(CDecl, Result);
+
static bool objc_ivar = false;
if (!objc_ivar) {
/* struct _objc_ivar {
@@ -738,13 +808,17 @@ void RewriteTest::RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
: CDecl->getIntfDeclIvars();
Result += "\t,{{\"";
Result += Ivars[0]->getName();
- Result += "\", \"\", 0}\n";
+ Result += "\", \"\", ";
+ SynthesizeIvarOffsetComputation(IDecl, Ivars[0], Result);
+ Result += "}\n";
for (int i = 1; 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.
+ // ivar_type type of each ivar .
Result += "\t ,{\"";
Result += Ivars[i]->getName();
- Result += "\", \"\", 0}\n";
+ Result += "\", \"\", ";
+ SynthesizeIvarOffsetComputation(IDecl, Ivars[i], Result);
+ Result += "}\n";
}
Result += "\t }\n};\n";
@@ -904,7 +978,9 @@ void RewriteTest::WriteObjcMetaData(std::string &Result) {
// TODO: This is temporary until we decide how to access objc types in a
// c program
- Result += "\n#include <Objc/objc.h>\n";
+ Result += "#include <Objc/objc.h>\n";
+ // This is needed for use of offsetof
+ Result += "#include <stddef.h>\n";
// For each implemented class, write out all its meta data.
for (int i = 0; i < ClsDefCount; i++)
@@ -973,7 +1049,8 @@ void RewriteTest::WriteObjcMetaData(std::string &Result) {
Result += "};\n\n";
Result += "static struct _objc_module "
"_OBJC_MODULES __attribute__ ((section (\"__OBJC, __module_info\")))= {\n";
- Result += "\t" + utostr(OBJC_ABI_VERSION) + ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
+ Result += "\t" + utostr(OBJC_ABI_VERSION) +
+ ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
Result += "};\n\n";
}