forked from OSchip/llvm-project
objective-c translator. more modern abi stuff, focusing on ivar related
meta-data. llvm-svn: 150310
This commit is contained in:
parent
b24f06780c
commit
088959a28b
|
@ -626,9 +626,6 @@ void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
|
|||
ConstantStringClassReference = FVD;
|
||||
return;
|
||||
}
|
||||
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
|
||||
if (ID->isThisDeclarationADefinition())
|
||||
RewriteInterfaceDecl(ID);
|
||||
} else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
|
||||
RewriteCategoryDecl(CD);
|
||||
} else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
|
||||
|
@ -1183,6 +1180,15 @@ void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) {
|
|||
}
|
||||
|
||||
void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
|
||||
// Do not synthesize more than once.
|
||||
if (ObjCSynthesizedStructs.count(ClassDecl))
|
||||
return;
|
||||
// Make sure super class's are written before current class is written.
|
||||
ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
|
||||
while (SuperClass) {
|
||||
RewriteInterfaceDecl(SuperClass);
|
||||
SuperClass = SuperClass->getSuperClass();
|
||||
}
|
||||
std::string ResultStr;
|
||||
if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
|
||||
// we haven't seen a forward decl - generate a typedef.
|
||||
|
@ -1215,6 +1221,9 @@ void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
|
|||
// Lastly, comment out the @end.
|
||||
ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"),
|
||||
"/* @end */");
|
||||
// Mark this struct as having been generated.
|
||||
if (!ObjCSynthesizedStructs.insert(ClassDecl))
|
||||
llvm_unreachable("struct already synthesize- RewriteInterfaceDecl");
|
||||
}
|
||||
|
||||
Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
|
||||
|
@ -3128,9 +3137,6 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
|
|||
assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
|
||||
assert(CDecl->getName() != "" &&
|
||||
"Name missing in SynthesizeObjCInternalStruct");
|
||||
// Do not synthesize more than once.
|
||||
if (ObjCSynthesizedStructs.count(CDecl))
|
||||
return;
|
||||
ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
|
||||
SmallVector<ObjCIvarDecl *, 8> IVars;
|
||||
for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
|
||||
|
@ -3171,15 +3177,14 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
|
|||
std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
|
||||
Result += "\t";
|
||||
Result += TypeString; Result += " "; Result += IvarDecl->getNameAsString();
|
||||
if (IvarDecl->isBitField()) {
|
||||
Result += " : "; Result += utostr(IvarDecl->getBitWidthValue(*Context));
|
||||
}
|
||||
Result += ";\n";
|
||||
}
|
||||
Result += "};\n";
|
||||
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
|
||||
ReplaceText(LocStart, endBuf-startBuf, Result);
|
||||
|
||||
// Mark this struct as having been generated.
|
||||
if (!ObjCSynthesizedStructs.insert(CDecl))
|
||||
llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct");
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -3195,8 +3200,19 @@ void RewriteModernObjC::RewriteImplementations() {
|
|||
int CatDefCount = CategoryImplementation.size();
|
||||
|
||||
// Rewrite implemented methods
|
||||
for (int i = 0; i < ClsDefCount; i++)
|
||||
RewriteImplementationDecl(ClassImplementation[i]);
|
||||
for (int i = 0; i < ClsDefCount; i++) {
|
||||
ObjCImplementationDecl *OIMP = ClassImplementation[i];
|
||||
ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
|
||||
if (CDecl->isImplicitInterfaceDecl())
|
||||
assert(false &&
|
||||
"Legacy implicit interface rewriting not supported in moder abi");
|
||||
// Write struct declaration for the class matching its ivar declarations.
|
||||
// Note that for modern abi, this is postponed until implementation decl.
|
||||
// because class extensions and the implementation might declare their own
|
||||
// private ivars.
|
||||
RewriteInterfaceDecl(CDecl);
|
||||
RewriteImplementationDecl(OIMP);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CatDefCount; i++)
|
||||
RewriteImplementationDecl(CategoryImplementation[i]);
|
||||
|
@ -5458,8 +5474,10 @@ static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
|
|||
RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
|
||||
Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
|
||||
|
||||
// FIXME: what should the alignment be?
|
||||
unsigned Align = 0;
|
||||
// FIXME. this alignment represents the host alignment and need be changed to
|
||||
// represent the target alignment.
|
||||
unsigned Align = Context->getTypeAlign(IvarDecl->getType())/8;
|
||||
Align = llvm::Log2_32(Align);
|
||||
Result += llvm::utostr(Align); Result += ", ";
|
||||
CharUnits Size = Context->getTypeSizeInChars(IvarDecl->getType());
|
||||
Result += llvm::utostr(Size.getQuantity());
|
||||
|
@ -5678,6 +5696,7 @@ void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
|
|||
if (CDecl->isImplicitInterfaceDecl())
|
||||
assert(false &&
|
||||
"Legacy implicit interface rewriting not supported in moder abi");
|
||||
|
||||
WriteModernMetadataDeclarations(Result);
|
||||
SmallVector<ObjCIvarDecl *, 8> IVars;
|
||||
|
||||
|
@ -5692,238 +5711,6 @@ void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
|
|||
Write__ivar_list_t_initializer(*this, Context, Result, IVars,
|
||||
"_OBJC_INSTANCE_VARIABLES_",
|
||||
CDecl->getNameAsString());
|
||||
|
||||
// FIXME. Handle modern abi's private ivars declared in @implementation.
|
||||
// Build _objc_ivar_list metadata for classes ivars if needed
|
||||
unsigned NumIvars = CDecl->ivar_size();
|
||||
|
||||
if (NumIvars > 0) {
|
||||
|
||||
/* struct {
|
||||
int ivar_count;
|
||||
struct _objc_ivar ivar_list[nIvars];
|
||||
};
|
||||
*/
|
||||
Result += "\nstatic struct {\n";
|
||||
Result += "\tint ivar_count;\n";
|
||||
Result += "\tstruct _objc_ivar ivar_list[";
|
||||
Result += utostr(NumIvars);
|
||||
Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
|
||||
Result += IDecl->getNameAsString();
|
||||
Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
|
||||
"{\n\t";
|
||||
Result += utostr(NumIvars);
|
||||
Result += "\n";
|
||||
|
||||
ObjCInterfaceDecl::ivar_iterator IVI, IVE;
|
||||
SmallVector<ObjCIvarDecl *, 8> IVars;
|
||||
if (!IDecl->ivar_empty()) {
|
||||
for (ObjCInterfaceDecl::ivar_iterator
|
||||
IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
|
||||
IV != IVEnd; ++IV)
|
||||
IVars.push_back(*IV);
|
||||
IVI = IDecl->ivar_begin();
|
||||
IVE = IDecl->ivar_end();
|
||||
} else {
|
||||
IVI = CDecl->ivar_begin();
|
||||
IVE = CDecl->ivar_end();
|
||||
}
|
||||
Result += "\t,{{\"";
|
||||
Result += (*IVI)->getNameAsString();
|
||||
Result += "\", \"";
|
||||
std::string TmpString, StrEncoding;
|
||||
Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
|
||||
QuoteDoublequotes(TmpString, StrEncoding);
|
||||
Result += StrEncoding;
|
||||
Result += "\", ";
|
||||
RewriteIvarOffsetComputation(*IVI, Result);
|
||||
Result += "}\n";
|
||||
for (++IVI; IVI != IVE; ++IVI) {
|
||||
Result += "\t ,{\"";
|
||||
Result += (*IVI)->getNameAsString();
|
||||
Result += "\", \"";
|
||||
std::string TmpString, StrEncoding;
|
||||
Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
|
||||
QuoteDoublequotes(TmpString, StrEncoding);
|
||||
Result += StrEncoding;
|
||||
Result += "\", ";
|
||||
RewriteIvarOffsetComputation((*IVI), Result);
|
||||
Result += "}\n";
|
||||
}
|
||||
|
||||
Result += "\t }\n};\n";
|
||||
}
|
||||
|
||||
// Build _objc_method_list for class's instance methods if needed
|
||||
SmallVector<ObjCMethodDecl *, 32>
|
||||
InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
|
||||
|
||||
// If any of our property implementations have associated getters or
|
||||
// setters, produce metadata for them as well.
|
||||
for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
|
||||
PropEnd = IDecl->propimpl_end();
|
||||
Prop != PropEnd; ++Prop) {
|
||||
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
|
||||
continue;
|
||||
if (!(*Prop)->getPropertyIvarDecl())
|
||||
continue;
|
||||
ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
|
||||
if (!PD)
|
||||
continue;
|
||||
if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
|
||||
if (!Getter->isDefined())
|
||||
InstanceMethods.push_back(Getter);
|
||||
if (PD->isReadOnly())
|
||||
continue;
|
||||
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
|
||||
if (!Setter->isDefined())
|
||||
InstanceMethods.push_back(Setter);
|
||||
}
|
||||
RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
|
||||
true, "", IDecl->getName(), Result);
|
||||
|
||||
// Build _objc_method_list for class's class methods if needed
|
||||
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
|
||||
false, "", IDecl->getName(), Result);
|
||||
|
||||
// Protocols referenced in class declaration?
|
||||
RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
|
||||
"CLASS", CDecl->getName(), Result);
|
||||
|
||||
// Declaration of class/meta-class metadata
|
||||
/* struct _objc_class {
|
||||
struct _objc_class *isa; // or const char *root_class_name when metadata
|
||||
const char *super_class_name;
|
||||
char *name;
|
||||
long version;
|
||||
long info;
|
||||
long instance_size;
|
||||
struct _objc_ivar_list *ivars;
|
||||
struct _objc_method_list *methods;
|
||||
struct objc_cache *cache;
|
||||
struct objc_protocol_list *protocols;
|
||||
const char *ivar_layout;
|
||||
struct _objc_class_ext *ext;
|
||||
};
|
||||
*/
|
||||
static bool objc_class = false;
|
||||
if (!objc_class) {
|
||||
Result += "\nstruct _objc_class {\n";
|
||||
Result += "\tstruct _objc_class *isa;\n";
|
||||
Result += "\tconst char *super_class_name;\n";
|
||||
Result += "\tchar *name;\n";
|
||||
Result += "\tlong version;\n";
|
||||
Result += "\tlong info;\n";
|
||||
Result += "\tlong instance_size;\n";
|
||||
Result += "\tstruct _objc_ivar_list *ivars;\n";
|
||||
Result += "\tstruct _objc_method_list *methods;\n";
|
||||
Result += "\tstruct objc_cache *cache;\n";
|
||||
Result += "\tstruct _objc_protocol_list *protocols;\n";
|
||||
Result += "\tconst char *ivar_layout;\n";
|
||||
Result += "\tstruct _objc_class_ext *ext;\n";
|
||||
Result += "};\n";
|
||||
objc_class = true;
|
||||
}
|
||||
|
||||
// Meta-class metadata generation.
|
||||
ObjCInterfaceDecl *RootClass = 0;
|
||||
ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
|
||||
while (SuperClass) {
|
||||
RootClass = SuperClass;
|
||||
SuperClass = SuperClass->getSuperClass();
|
||||
}
|
||||
SuperClass = CDecl->getSuperClass();
|
||||
|
||||
Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
|
||||
"{\n\t(struct _objc_class *)\"";
|
||||
Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
|
||||
Result += "\"";
|
||||
|
||||
if (SuperClass) {
|
||||
Result += ", \"";
|
||||
Result += SuperClass->getNameAsString();
|
||||
Result += "\", \"";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += "\"";
|
||||
}
|
||||
else {
|
||||
Result += ", 0, \"";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += "\"";
|
||||
}
|
||||
// Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
|
||||
// 'info' field is initialized to CLS_META(2) for metaclass
|
||||
Result += ", 0,2, sizeof(struct _objc_class), 0";
|
||||
if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
|
||||
Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
|
||||
Result += IDecl->getNameAsString();
|
||||
Result += "\n";
|
||||
}
|
||||
else
|
||||
Result += ", 0\n";
|
||||
if (CDecl->protocol_begin() != CDecl->protocol_end()) {
|
||||
Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += ",0,0\n";
|
||||
}
|
||||
else
|
||||
Result += "\t,0,0,0,0\n";
|
||||
Result += "};\n";
|
||||
|
||||
// class metadata generation.
|
||||
Result += "\nstatic struct _objc_class _OBJC_CLASS_";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
|
||||
"{\n\t&_OBJC_METACLASS_";
|
||||
Result += CDecl->getNameAsString();
|
||||
if (SuperClass) {
|
||||
Result += ", \"";
|
||||
Result += SuperClass->getNameAsString();
|
||||
Result += "\", \"";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += "\"";
|
||||
}
|
||||
else {
|
||||
Result += ", 0, \"";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += "\"";
|
||||
}
|
||||
// 'info' field is initialized to CLS_CLASS(1) for class
|
||||
Result += ", 0,1";
|
||||
if (!ObjCSynthesizedStructs.count(CDecl))
|
||||
Result += ",0";
|
||||
else {
|
||||
// class has size. Must synthesize its size.
|
||||
Result += ",sizeof(struct ";
|
||||
Result += CDecl->getNameAsString();
|
||||
if (LangOpts.MicrosoftExt)
|
||||
Result += "_IMPL";
|
||||
Result += ")";
|
||||
}
|
||||
if (NumIvars > 0) {
|
||||
Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += "\n\t";
|
||||
}
|
||||
else
|
||||
Result += ",0";
|
||||
if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
|
||||
Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += ", 0\n\t";
|
||||
}
|
||||
else
|
||||
Result += ",0,0";
|
||||
if (CDecl->protocol_begin() != CDecl->protocol_end()) {
|
||||
Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
|
||||
Result += CDecl->getNameAsString();
|
||||
Result += ", 0,0\n";
|
||||
}
|
||||
else
|
||||
Result += ",0,0,0\n";
|
||||
Result += "};\n";
|
||||
}
|
||||
|
||||
void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
|
||||
|
|
Loading…
Reference in New Issue