[cfe-commits] r63126 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/CodeGen/CGObjCMac.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Jan 27 11:38:52 PST 2009
Author: fjahanian
Date: Tue Jan 27 13:38:51 2009
New Revision: 63126
URL: http://llvm.org/viewvc/llvm-project?rev=63126&view=rev
Log:
ivar meta-data generation for nonfragile-abi.
Still more work to do in this area.
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=63126&r1=63125&r2=63126&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Jan 27 13:38:51 2009
@@ -927,9 +927,11 @@
/// ObjCImplementationDecl - Represents a class definition - this is where
/// method definitions are specified. For example:
///
+/// @code
/// @implementation MyClass
/// - (void)myMethod { /* do something */ }
/// @end
+/// @endcode
///
/// Typically, instance variables are specified in the class interface,
/// *not* in the implementation. Nevertheless (for legacy reasons), we
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=63126&r1=63125&r2=63126&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Jan 27 13:38:51 2009
@@ -562,7 +562,13 @@
/// implementation. The return value has type MethodListnfABITy.
llvm::Constant *EmitMethodList(const std::string &Name,
const char *Section,
- const ConstantVector &Methods);
+ const ConstantVector &Methods);
+ /// EmitIvarList - Emit the ivar list for the given
+ /// implementation. If ForClass is true the list of class ivars
+ /// (i.e. metaclass ivars) is emitted, otherwise the list of
+ /// interface ivars will be emitted. The return value has type
+ /// IvarListnfABIPtrTy.
+ llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
public:
CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
@@ -3157,7 +3163,10 @@
Values[ 5] = EmitMethodList(MethodListName,
".section __DATA,__data,regular,no_dead_strip", Methods);
Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
- Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
+ if (flags & CLS_META)
+ Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
+ else
+ Values[ 7] = EmitIvarList(ID);
Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
@@ -3505,6 +3514,82 @@
return llvm::ConstantExpr::getBitCast(GV,
ObjCTypes.MethodListnfABIPtrTy);
}
+
+/// EmitIvarList - Emit the ivar list for the given
+/// implementation. If ForClass is true the list of class ivars
+/// (i.e. metaclass ivars) is emitted, otherwise the list of
+/// interface ivars will be emitted. The return value has type
+/// IvarListnfABIPtrTy.
+/// struct _ivar_t {
+/// unsigned long int *offset; // pointer to ivar offset location
+/// char *name;
+/// char *type;
+/// uint32_t alignment;
+/// uint32_t size;
+/// }
+/// struct _ivar_list_t {
+/// uint32 entsize; // sizeof(struct _ivar_t)
+/// uint32 count;
+/// struct _iver_t list[count];
+/// }
+///
+llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
+ const ObjCImplementationDecl *ID) {
+
+ std::vector<llvm::Constant*> Ivars, Ivar(5);
+
+ const ObjCInterfaceDecl *OID = ID->getClassInterface();
+ assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
+
+ for(ObjCInterfaceDecl::ivar_iterator i = OID->ivar_begin(),
+ e = OID->ivar_end(); i != e; ++i) {
+ FieldDecl *Field = *i;
+ // FIXME. Put the offset symbol address after code gen.
+ // for non-fragile ivar access is in.
+ Ivar[0] = llvm::Constant::getNullValue(
+ llvm::PointerType::getUnqual(ObjCTypes.LongTy));
+ if (Field->getIdentifier())
+ Ivar[1] = GetMethodVarName(Field->getIdentifier());
+ else
+ Ivar[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+ std::string TypeStr;
+ CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
+ Ivar[2] = GetMethodVarType(TypeStr);
+ const llvm::Type *FieldTy =
+ CGM.getTypes().ConvertTypeForMem(Field->getType());
+ unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy);
+ unsigned Align = CGM.getContext().getPreferredTypeAlign(
+ Field->getType().getTypePtr()) >> 3;
+ Align = llvm::Log2_32(Align);
+ Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
+ Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+ Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
+ }
+ // Return null for empty list.
+ if (Ivars.empty())
+ return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
+ std::vector<llvm::Constant*> Values(3);
+ unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.IvarnfABITy);
+ Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
+ Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
+ llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
+ Ivars.size());
+ Values[2] = llvm::ConstantArray::get(AT, Ivars);
+ llvm::Constant *Init = llvm::ConstantStruct::get(Values);
+ const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(Init->getType(), false,
+ llvm::GlobalValue::InternalLinkage,
+ Init,
+ Prefix + OID->getNameAsString(),
+ &CGM.getModule());
+
+ GV->setSection(".section __DATA,__data,regular,no_dead_strip");
+
+ UsedGlobals.push_back(GV);
+ return llvm::ConstantExpr::getBitCast(GV,
+ ObjCTypes.IvarListnfABIPtrTy);
+}
/* *** */
CodeGen::CGObjCRuntime *
More information about the cfe-commits
mailing list