[cfe-commits] r55302 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Sun Aug 24 23:02:07 PDT 2008
Author: ddunbar
Date: Mon Aug 25 01:02:07 2008
New Revision: 55302
URL: http://llvm.org/viewvc/llvm-project?rev=55302&view=rev
Log:
NeXT: Emit symbols used to manage linking of Obj-C classes.
- This ensures that references to undefined classes cause link
errors.
- NOTE: This relies on platform specific asm directives currently,
this should be factored out.
Also, don't emit a SYMBOLS metadata entry if there are no symbols.
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55302&r1=55301&r2=55302&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Mon Aug 25 01:02:07 2008
@@ -137,6 +137,16 @@
/// ObjCABI - FIXME: Not sure yet.
unsigned ObjCABI;
+ /// LazySymbols - Symbols to generate a lazy reference for. See
+ /// DefinedSymbols and FinishModule().
+ std::set<IdentifierInfo*> LazySymbols;
+
+ /// DefinedSymbols - External symbols which are defined by this
+ /// module. The symbols in this list and LazySymbols are used to add
+ /// special linker symbols which ensure that Objective-C modules are
+ /// linked properly.
+ std::set<IdentifierInfo*> DefinedSymbols;
+
/// ClassNames - uniqued class names.
llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
@@ -463,6 +473,11 @@
See EmitProtocolExtension().
*/
void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
+ // FIXME: I don't understand why gcc generates this, or where it is
+ // resolved. Investigate. Its also wasteful to look this up over and
+ // over.
+ LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
+
const char *ProtocolName = PD->getName();
std::vector<llvm::Constant*> Values(5);
@@ -844,6 +859,8 @@
See EmitClassExtension();
*/
void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
+ DefinedSymbols.insert(ID->getIdentifier());
+
const char *ClassName = ID->getName();
// FIXME: Gross
ObjCInterfaceDecl *Interface =
@@ -864,6 +881,9 @@
std::vector<llvm::Constant*> Values(12);
Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
+ // Record a reference to the super class.
+ LazySymbols.insert(Super->getIdentifier());
+
Values[ 1] =
llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
ObjCTypes.ClassPtrTy);
@@ -1293,10 +1313,14 @@
}
llvm::Constant *CGObjCMac::EmitModuleSymbols() {
- std::vector<llvm::Constant*> Values(5);
unsigned NumClasses = DefinedClasses.size();
unsigned NumCategories = DefinedCategories.size();
+ // Return null if no symbols were defined.
+ if (!NumClasses && !NumCategories)
+ return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
+
+ std::vector<llvm::Constant*> Values(5);
Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
@@ -1333,6 +1357,8 @@
llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
const ObjCInterfaceDecl *ID) {
+ LazySymbols.insert(ID->getIdentifier());
+
llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
if (!Entry) {
@@ -1495,6 +1521,23 @@
&CGM.getModule());
GV->setSection("llvm.metadata");
+
+ // Add assembler directives to add lazy undefined symbol references
+ // for classes which are referenced but not defined. This is
+ // important for correct linker interaction.
+
+ // FIXME: Uh, this isn't particularly portable.
+ std::stringstream s;
+ for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
+ e = LazySymbols.end(); i != e; ++i) {
+ s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
+ }
+ for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
+ e = DefinedSymbols.end(); i != e; ++i) {
+ s << "\t.objc_class_name_" << (*i)->getName() << " = 0\n"
+ << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
+ }
+ CGM.getModule().appendModuleInlineAsm(s.str());
}
/* *** */
More information about the cfe-commits
mailing list