[cfe-commits] r150310 - /cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
Fariborz Jahanian
fjahanian at apple.com
Sat Feb 11 12:10:52 PST 2012
Author: fjahanian
Date: Sat Feb 11 14:10:52 2012
New Revision: 150310
URL: http://llvm.org/viewvc/llvm-project?rev=150310&view=rev
Log:
objective-c translator. more modern abi stuff, focusing on ivar related
meta-data.
Modified:
cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=150310&r1=150309&r2=150310&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Sat Feb 11 14:10:52 2012
@@ -626,9 +626,6 @@
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::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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
if (CDecl->isImplicitInterfaceDecl())
assert(false &&
"Legacy implicit interface rewriting not supported in moder abi");
+
WriteModernMetadataDeclarations(Result);
SmallVector<ObjCIvarDecl *, 8> IVars;
@@ -5692,238 +5711,6 @@
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) {
More information about the cfe-commits
mailing list