Skip to content

Commit 2c919e1

Browse files
authored
[ObjC][Gen] Emit ObjC strings to respective sections (#84300)
Clang emits ObjC strings into special sections https://github.com/llvm/llvm-project/blob/d5e7c27d53887e6ae490d8e26193a54987728458/clang/lib/CodeGen/CGObjCMac.cpp#L4056-L4072 As far as I can tell from `CGObjCMac.cpp`: * types go into `__objc_methtype` * class, category, and protocol names go into `__objc_classname` * method names, property names, and property types go into `__objc_methname` See also #84236.
1 parent 48fdd99 commit 2c919e1

File tree

10 files changed

+134
-76
lines changed

10 files changed

+134
-76
lines changed

lib/IRGen/GenBuiltin.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,8 +1401,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
14011401
auto clangTy = IGF.IGM.getClangType(valueTy->getCanonicalType());
14021402
std::string encoding;
14031403
IGF.IGM.getClangASTContext().getObjCEncodingForType(clangTy, encoding);
1404-
1405-
auto globalString = IGF.IGM.getAddrOfGlobalString(encoding);
1404+
1405+
auto globalString = IGF.IGM.getAddrOfGlobalString(
1406+
encoding, CStringSectionType::ObjCMethodType);
14061407
out.add(globalString);
14071408
return;
14081409
}

lib/IRGen/GenClass.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,8 @@ namespace {
14641464

14651465
// struct category_t {
14661466
// char const *name;
1467-
fields.add(IGM.getAddrOfGlobalString(CategoryName));
1467+
fields.add(IGM.getAddrOfGlobalString(CategoryName,
1468+
CStringSectionType::ObjCClassName));
14681469
// const class_t *theClass;
14691470
fields.add(getClassMetadataRef());
14701471
// const method_list_t *instanceMethods;
@@ -1503,7 +1504,8 @@ namespace {
15031504
// Class super;
15041505
fields.addNullPointer(IGM.Int8PtrTy);
15051506
// char const *name;
1506-
fields.add(IGM.getAddrOfGlobalString(getEntityName(nameBuffer)));
1507+
fields.add(IGM.getAddrOfGlobalString(getEntityName(nameBuffer),
1508+
CStringSectionType::ObjCClassName));
15071509
// const protocol_list_t *baseProtocols;
15081510
fields.add(buildProtocolList(weakLinkage));
15091511
// const method_list_t *requiredInstanceMethods;
@@ -1724,7 +1726,8 @@ namespace {
17241726
}
17251727

17261728
llvm::SmallString<64> buffer;
1727-
Name = IGM.getAddrOfGlobalString(getClass()->getObjCRuntimeName(buffer));
1729+
Name = IGM.getAddrOfGlobalString(getClass()->getObjCRuntimeName(buffer),
1730+
CStringSectionType::ObjCClassName);
17281731
return Name;
17291732
}
17301733

@@ -2088,11 +2091,10 @@ namespace {
20882091
else
20892092
fields.addNullPointer(IGM.PtrTy);
20902093

2091-
// TODO: clang puts this in __TEXT,__objc_methname,cstring_literals
2092-
fields.add(IGM.getAddrOfGlobalString(name));
2093-
2094-
// TODO: clang puts this in __TEXT,__objc_methtype,cstring_literals
2095-
fields.add(IGM.getAddrOfGlobalString(typeEnc));
2094+
fields.add(
2095+
IGM.getAddrOfGlobalString(name, CStringSectionType::ObjCMethodName));
2096+
fields.add(IGM.getAddrOfGlobalString(typeEnc,
2097+
CStringSectionType::ObjCMethodType));
20962098

20972099
Size size;
20982100
Alignment alignment;
@@ -2228,8 +2230,11 @@ namespace {
22282230
buildPropertyAttributes(prop, propertyAttributes);
22292231

22302232
auto fields = properties.beginStruct();
2231-
fields.add(IGM.getAddrOfGlobalString(prop->getObjCPropertyName().str()));
2232-
fields.add(IGM.getAddrOfGlobalString(propertyAttributes));
2233+
fields.add(
2234+
IGM.getAddrOfGlobalString(prop->getObjCPropertyName().str(),
2235+
CStringSectionType::ObjCPropertyName));
2236+
fields.add(IGM.getAddrOfGlobalString(
2237+
propertyAttributes, CStringSectionType::ObjCPropertyName));
22332238
fields.finishAndAddTo(properties);
22342239
}
22352240

lib/IRGen/GenConstant.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ llvm::Constant *irgen::emitAddrOfConstantString(IRGenModule &IGM,
7979
case StringLiteralInst::Encoding::Bytes:
8080
case StringLiteralInst::Encoding::UTF8:
8181
case StringLiteralInst::Encoding::UTF8_OSLOG:
82-
return IGM.getAddrOfGlobalString(SLI->getValue(), false, useOSLogEncoding);
82+
return IGM.getAddrOfGlobalString(
83+
SLI->getValue(), useOSLogEncoding ? CStringSectionType::OSLogString
84+
: CStringSectionType::Default);
8385

8486
case StringLiteralInst::Encoding::ObjCSelector:
8587
llvm_unreachable("cannot get the address of an Objective-C selector");

lib/IRGen/GenDecl.cpp

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,9 @@ class ObjCProtocolInitializerVisitor
296296
// Check if the ObjC runtime already has a descriptor for this
297297
// protocol. If so, use it.
298298
SmallString<32> buf;
299-
auto protocolName
300-
= IGM.getAddrOfGlobalString(proto->getObjCRuntimeName(buf));
301-
299+
auto protocolName = IGM.getAddrOfGlobalString(
300+
proto->getObjCRuntimeName(buf), CStringSectionType::ObjCClassName);
301+
302302
auto existing = Builder.CreateCall(objc_getProtocol, protocolName);
303303
auto isNull = Builder.CreateICmpEQ(existing,
304304
llvm::ConstantPointerNull::get(IGM.ProtocolDescriptorPtrTy));
@@ -1056,16 +1056,14 @@ void IRGenModule::SetCStringLiteralSection(llvm::GlobalVariable *GV,
10561056
case llvm::Triple::MachO:
10571057
switch (Type) {
10581058
case ObjCLabelType::ClassName:
1059-
GV->setSection("__TEXT,__objc_classname,cstring_literals");
1059+
GV->setSection(IRGenModule::ObjCClassNameSectionName);
10601060
return;
10611061
case ObjCLabelType::MethodVarName:
1062-
GV->setSection("__TEXT,__objc_methname,cstring_literals");
1062+
case ObjCLabelType::PropertyName:
1063+
GV->setSection(IRGenModule::ObjCMethodNameSectionName);
10631064
return;
10641065
case ObjCLabelType::MethodVarType:
1065-
GV->setSection("__TEXT,__objc_methtype,cstring_literals");
1066-
return;
1067-
case ObjCLabelType::PropertyName:
1068-
GV->setSection("__TEXT,__objc_methname,cstring_literals");
1066+
GV->setSection(IRGenModule::ObjCMethodTypeSectionName);
10691067
return;
10701068
}
10711069
case llvm::Triple::ELF:
@@ -4240,9 +4238,10 @@ static TypeEntityReference
42404238
getObjCClassByNameReference(IRGenModule &IGM, ClassDecl *cls) {
42414239
auto kind = TypeReferenceKind::DirectObjCClassName;
42424240
SmallString<64> objcRuntimeNameBuffer;
4243-
auto ref = IGM.getAddrOfGlobalString(
4244-
cls->getObjCRuntimeName(objcRuntimeNameBuffer),
4245-
/*willBeRelativelyAddressed=*/true);
4241+
auto ref =
4242+
IGM.getAddrOfGlobalString(cls->getObjCRuntimeName(objcRuntimeNameBuffer),
4243+
CStringSectionType::ObjCClassName,
4244+
/*willBeRelativelyAddressed=*/true);
42464245

42474246
return TypeEntityReference(kind, ref);
42484247
}
@@ -4799,9 +4798,9 @@ void IRGenModule::emitAccessibleFunction(StringRef sectionName,
47994798

48004799
// -- Field: Name (record name)
48014800
{
4802-
llvm::Constant *name =
4803-
getAddrOfGlobalString(func.getFunctionName(),
4804-
/*willBeRelativelyAddressed=*/true);
4801+
llvm::Constant *name = getAddrOfGlobalString(
4802+
func.getFunctionName(), CStringSectionType::Default,
4803+
/*willBeRelativelyAddressed=*/true);
48054804
fields.addRelativeAddress(name);
48064805
}
48074806

@@ -6023,15 +6022,34 @@ Address IRGenFunction::createAlloca(llvm::Type *type,
60236022
/// FIXME: willBeRelativelyAddressed is only needed to work around an ld64 bug
60246023
/// resolving relative references to coalesceable symbols.
60256024
/// It should be removed when fixed. rdar://problem/22674524
6026-
llvm::Constant *IRGenModule::getAddrOfGlobalString(StringRef data,
6027-
bool willBeRelativelyAddressed,
6028-
bool useOSLogSection) {
6029-
useOSLogSection = useOSLogSection &&
6030-
TargetInfo.OutputObjectFormat == llvm::Triple::MachO;
6025+
llvm::Constant *
6026+
IRGenModule::getAddrOfGlobalString(StringRef data, CStringSectionType type,
6027+
bool willBeRelativelyAddressed) {
6028+
if (TargetInfo.OutputObjectFormat != llvm::Triple::MachO)
6029+
type = CStringSectionType::Default;
6030+
StringRef sectionName;
6031+
switch (type) {
6032+
case CStringSectionType::Default:
6033+
sectionName = "";
6034+
break;
6035+
case CStringSectionType::ObjCClassName:
6036+
sectionName = ObjCClassNameSectionName;
6037+
break;
6038+
case CStringSectionType::ObjCMethodName:
6039+
sectionName = ObjCMethodNameSectionName;
6040+
break;
6041+
case CStringSectionType::ObjCMethodType:
6042+
sectionName = ObjCMethodTypeSectionName;
6043+
break;
6044+
case CStringSectionType::OSLogString:
6045+
sectionName = OSLogStringSectionName;
6046+
break;
6047+
case CStringSectionType::NumTypes:
6048+
llvm_unreachable("invalid type");
6049+
}
60316050

60326051
// Check whether this string already exists.
6033-
auto &entry = useOSLogSection ? GlobalOSLogStrings[data] :
6034-
GlobalStrings[data];
6052+
auto &entry = GlobalStrings[static_cast<size_t>(type)][data];
60356053

60366054
if (entry.second) {
60376055
// FIXME: Clear unnamed_addr if the global will be relative referenced
@@ -6053,9 +6071,6 @@ llvm::Constant *IRGenModule::getAddrOfGlobalString(StringRef data,
60536071
(llvm::Twine(".nul") + llvm::Twine(i)).toVector(name);
60546072
}
60556073

6056-
auto sectionName =
6057-
useOSLogSection ? "__TEXT,__oslogstring,cstring_literals" : "";
6058-
60596074
entry = createStringConstant(data, willBeRelativelyAddressed,
60606075
sectionName, name);
60616076
return entry.second;
@@ -6067,9 +6082,11 @@ IRGenModule::getAddrOfGlobalIdentifierString(StringRef data,
60676082
if (Lexer::identifierMustAlwaysBeEscaped(data)) {
60686083
llvm::SmallString<256> name;
60696084
Mangle::Mangler::appendRawIdentifierForRuntime(data, name);
6070-
return getAddrOfGlobalString(name, willBeRelativelyAddressed);
6085+
return getAddrOfGlobalString(name, CStringSectionType::Default,
6086+
willBeRelativelyAddressed);
60716087
}
6072-
return getAddrOfGlobalString(data, willBeRelativelyAddressed);
6088+
return getAddrOfGlobalString(data, CStringSectionType::Default,
6089+
willBeRelativelyAddressed);
60736090
}
60746091

60756092
/// Get or create a global UTF-16 string constant.

lib/IRGen/GenKeyPath.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,7 @@ IRGenModule::getAddrOfKeyPathPattern(KeyPathPattern *pattern,
11431143
// null otherwise.
11441144
if (!pattern->getObjCString().empty()) {
11451145
auto objcString = getAddrOfGlobalString(pattern->getObjCString(),
1146+
CStringSectionType::Default,
11461147
/*relatively addressed*/ true);
11471148
fields.addRelativeAddress(objcString);
11481149
} else {

lib/IRGen/GenMeta.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,8 @@ namespace {
845845
IRGenMangler mangler(IGM.Context);
846846
auto mangledName = mangler.mangleAnonymousDescriptorName(Name);
847847
auto mangledNameConstant =
848-
IGM.getAddrOfGlobalString(mangledName,
849-
/*willBeRelativelyAddressed*/ true);
848+
IGM.getAddrOfGlobalString(mangledName, CStringSectionType::Default,
849+
/*willBeRelativelyAddressed*/ true);
850850
B.addRelativeAddress(mangledNameConstant);
851851
}
852852

@@ -1277,6 +1277,7 @@ namespace {
12771277
llvm::Constant *global = nullptr;
12781278
if (!AssociatedTypeNames.empty()) {
12791279
global = IGM.getAddrOfGlobalString(AssociatedTypeNames,
1280+
CStringSectionType::Default,
12801281
/*willBeRelativelyAddressed=*/true);
12811282
}
12821283
B.addRelativeAddressOrNull(global);
@@ -1515,9 +1516,10 @@ namespace {
15151516
name.pop_back();
15161517
assert(name.back() == '\0');
15171518
}
1518-
1519-
auto nameStr = IGM.getAddrOfGlobalString(name,
1520-
/*willBeRelativelyAddressed*/ true);
1519+
1520+
auto nameStr =
1521+
IGM.getAddrOfGlobalString(name, CStringSectionType::Default,
1522+
/*willBeRelativelyAddressed*/ true);
15211523
B.addRelativeAddress(nameStr);
15221524
}
15231525

lib/IRGen/GenObjC.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,8 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM,
13181318
encodingString += llvm::itostr(parmOffset);
13191319
encodingString += fixedParamsString;
13201320
encodingString += paramsString;
1321-
return IGM.getAddrOfGlobalString(encodingString);
1321+
return IGM.getAddrOfGlobalString(encodingString,
1322+
CStringSectionType::ObjCMethodType);
13221323
}
13231324

13241325
static llvm::Constant *
@@ -1329,16 +1330,19 @@ getObjectEncodingFromClangNode(IRGenModule &IGM, Decl *d,
13291330
auto clangDecl = d->getClangNode().castAsDecl();
13301331
auto &clangASTContext = IGM.getClangASTContext();
13311332
std::string typeStr;
1333+
CStringSectionType sectionType;
13321334
if (auto objcMethodDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
13331335
typeStr = clangASTContext.getObjCEncodingForMethodDecl(
13341336
objcMethodDecl, useExtendedEncoding /*extended*/);
1337+
sectionType = CStringSectionType::ObjCMethodType;
13351338
}
13361339
if (auto objcPropertyDecl = dyn_cast<clang::ObjCPropertyDecl>(clangDecl)) {
13371340
typeStr = clangASTContext.getObjCEncodingForPropertyDecl(objcPropertyDecl,
13381341
nullptr);
1342+
sectionType = CStringSectionType::ObjCPropertyName;
13391343
}
13401344
if (!typeStr.empty()) {
1341-
return IGM.getAddrOfGlobalString(typeStr.c_str());
1345+
return IGM.getAddrOfGlobalString(typeStr.c_str(), sectionType);
13421346
}
13431347
}
13441348
return nullptr;
@@ -1434,7 +1438,8 @@ irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM, VarDecl *property) {
14341438
TypeStr += llvm::itostr(ParmOffset);
14351439
TypeStr += "@0:";
14361440
TypeStr += llvm::itostr(PtrSize.getValue());
1437-
descriptor.typeEncoding = IGM.getAddrOfGlobalString(TypeStr.c_str());
1441+
descriptor.typeEncoding = IGM.getAddrOfGlobalString(
1442+
TypeStr.c_str(), CStringSectionType::ObjCMethodType);
14381443
descriptor.silFunction = nullptr;
14391444
descriptor.impl = getObjCGetterPointer(IGM, property, descriptor.silFunction);
14401445
return descriptor;
@@ -1511,7 +1516,8 @@ irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
15111516
ParmOffset = 2 * PtrSize.getValue();
15121517
clangASTContext.getObjCEncodingForType(clangType, TypeStr);
15131518
TypeStr += llvm::itostr(ParmOffset);
1514-
descriptor.typeEncoding = IGM.getAddrOfGlobalString(TypeStr.c_str());
1519+
descriptor.typeEncoding = IGM.getAddrOfGlobalString(
1520+
TypeStr.c_str(), CStringSectionType::ObjCMethodType);
15151521
descriptor.silFunction = nullptr;
15161522
descriptor.impl = getObjCSetterPointer(IGM, property, descriptor.silFunction);
15171523
return descriptor;
@@ -1617,7 +1623,8 @@ void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM,
16171623
auto ptrSize = IGM.getPointerSize().getValue();
16181624
llvm::SmallString<8> signature;
16191625
signature = "v" + llvm::itostr(ptrSize * 2) + "@0:" + llvm::itostr(ptrSize);
1620-
descriptor.typeEncoding = IGM.getAddrOfGlobalString(signature);
1626+
descriptor.typeEncoding =
1627+
IGM.getAddrOfGlobalString(signature, CStringSectionType::ObjCMethodType);
16211628

16221629
/// The third element is the method implementation pointer.
16231630
descriptor.impl = llvm::ConstantExpr::getBitCast(objcImpl, IGM.Int8PtrTy);

lib/IRGen/IRGenModule.h

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,18 @@ struct AccessibleFunction {
669669
llvm::Constant *address);
670670
};
671671

672+
enum class CStringSectionType {
673+
Default,
674+
ObjCClassName,
675+
ObjCMethodName,
676+
ObjCMethodType,
677+
OSLogString,
678+
// Place all new section types above this line
679+
NumTypes,
680+
// Place all alias below this line
681+
ObjCPropertyName = ObjCMethodName,
682+
};
683+
672684
/// IRGenModule - Primary class for emitting IR for global declarations.
673685
///
674686
class IRGenModule {
@@ -1203,9 +1215,10 @@ class IRGenModule {
12031215
std::pair<llvm::GlobalVariable *, llvm::Constant *> createStringConstant(
12041216
StringRef Str, bool willBeRelativelyAddressed = false,
12051217
StringRef sectionName = "", StringRef name = "");
1206-
llvm::Constant *getAddrOfGlobalString(StringRef utf8,
1207-
bool willBeRelativelyAddressed = false,
1208-
bool useOSLogSection = false);
1218+
llvm::Constant *getAddrOfGlobalString(
1219+
StringRef utf8,
1220+
CStringSectionType sectionType = CStringSectionType::Default,
1221+
bool willBeRelativelyAddressed = false);
12091222
llvm::Constant *getAddrOfGlobalUTF16String(StringRef utf8);
12101223
llvm::Constant *
12111224
getAddrOfGlobalIdentifierString(StringRef utf8,
@@ -1329,10 +1342,11 @@ class IRGenModule {
13291342
llvm::DenseMap<LinkEntity, llvm::Constant*> GlobalGOTEquivalents;
13301343
llvm::DenseMap<LinkEntity, llvm::Function*> GlobalFuncs;
13311344
llvm::DenseSet<const clang::Decl *> GlobalClangDecls;
1332-
llvm::StringMap<std::pair<llvm::GlobalVariable*, llvm::Constant*>>
1333-
GlobalStrings;
1334-
llvm::StringMap<std::pair<llvm::GlobalVariable*, llvm::Constant*>>
1335-
GlobalOSLogStrings;
1345+
// Maps sectionName -> string data -> constant
1346+
std::array<
1347+
llvm::StringMap<std::pair<llvm::GlobalVariable *, llvm::Constant *>>,
1348+
static_cast<size_t>(CStringSectionType::NumTypes)>
1349+
GlobalStrings;
13361350
llvm::StringMap<llvm::Constant*> GlobalUTF16Strings;
13371351
llvm::StringMap<std::pair<llvm::GlobalVariable*, llvm::Constant*>>
13381352
StringsForTypeRef;
@@ -1543,6 +1557,15 @@ class IRGenModule {
15431557
const char *getReflectionTypeRefSectionName();
15441558
const char *getMultiPayloadEnumDescriptorSectionName();
15451559

1560+
static constexpr const char ObjCClassNameSectionName[] =
1561+
"__TEXT,__objc_classname,cstring_literals";
1562+
static constexpr const char ObjCMethodNameSectionName[] =
1563+
"__TEXT,__objc_methname,cstring_literals";
1564+
static constexpr const char ObjCMethodTypeSectionName[] =
1565+
"__TEXT,__objc_methtype,cstring_literals";
1566+
static constexpr const char OSLogStringSectionName[] =
1567+
"__TEXT,__oslogstring,cstring_literals";
1568+
15461569
/// Returns the special builtin types that should be emitted in the stdlib
15471570
/// module.
15481571
llvm::ArrayRef<CanType> getOrCreateSpecialStlibBuiltinTypes();

0 commit comments

Comments
 (0)