CodeGen: refactor the ObjC cstring literal creation
authorSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 16 Sep 2016 23:41:13 +0000 (23:41 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 16 Sep 2016 23:41:13 +0000 (23:41 +0000)
This refactors the cstring literal creation as mentioned in the couple of FIXMEs
littered in the various invocations to CreateMetadataVar.  This centralises the
definition of the literals, and will enable changing the literal creation to a
single site.  NFC.

llvm-svn: 281798

clang/lib/CodeGen/CGObjCMac.cpp

index 97e9925..fad36f6 100644 (file)
@@ -733,6 +733,13 @@ public:
   ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
 };
 
+enum class ObjCLabelType {
+  ClassName,
+  MethodVarName,
+  MethodVarType,
+  PropertyName,
+};
+
 class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
 public:
   class SKIP_SCAN {
@@ -1018,6 +1025,9 @@ public:
                                           StringRef Section, CharUnits Align,
                                           bool AddToUsed);
 
+  llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
+                                             ObjCLabelType LabelType);
+
 protected:
   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
                                   ReturnValueSlot Return,
@@ -3650,6 +3660,46 @@ llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
   return GV;
 }
 
+llvm::GlobalVariable *
+CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type) {
+  StringRef Label;
+  switch (Type) {
+  case ObjCLabelType::ClassName:     Label = "OBJC_CLASS_NAME_"; break;
+  case ObjCLabelType::MethodVarName: Label = "OBJC_METH_VAR_NAME_"; break;
+  case ObjCLabelType::MethodVarType: Label = "OBJC_METH_VAR_TYPE_"; break;
+  case ObjCLabelType::PropertyName:  Label = "OBJC_PROP_NAME_ATTR_"; break;
+  }
+
+  StringRef Section;
+  switch (Type) {
+  case ObjCLabelType::ClassName:
+    Section = isNonFragileABI() ? "__TEXT,__objc_classname,cstring_literals"
+                                : "__TEXT,__cstring,cstring_literals";
+    break;
+  case ObjCLabelType::MethodVarName:
+    Section = isNonFragileABI() ? "__TEXT,__objc_methname,cstring_literals"
+                                : "__TEXT,__cstring,cstring_literals";
+    break;
+  case ObjCLabelType::MethodVarType:
+    Section = isNonFragileABI() ? "__TEXT,__objc_methtype,cstring_literals"
+                                : "__TEXT,__cstring,cstring_literals";
+    break;
+  case ObjCLabelType::PropertyName:
+    Section = "__TEXT,__cstring,cstring_literals";
+    break;
+  }
+
+  llvm::Constant *Value = llvm::ConstantDataArray::getString(VMContext, Name);
+  llvm::GlobalVariable *GV =
+      new llvm::GlobalVariable(CGM.getModule(), Value->getType(), false,
+                               llvm::GlobalValue::PrivateLinkage, Value, Label);
+  GV->setSection(Section);
+  GV->setAlignment(CharUnits::One().getQuantity());
+  CGM.addCompilerUsedGlobal(GV);
+
+  return GV;
+}
+
 llvm::Function *CGObjCMac::ModuleInitFunction() {
   // Abuse this interface function as a place to finalize.
   FinishModule();
@@ -4707,12 +4757,7 @@ Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) {
 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
     llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
     if (!Entry)
-      Entry = CreateMetadataVar(
-          "OBJC_CLASS_NAME_",
-          llvm::ConstantDataArray::getString(VMContext, RuntimeName),
-          ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
-                          : "__TEXT,__cstring,cstring_literals"),
-          CharUnits::One(), true);
+      Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
     return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
@@ -4960,14 +5005,8 @@ llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
   // Null terminate the string.
   buffer.push_back(0);
 
-  bool isNonFragileABI = CGObjC.isNonFragileABI();
-
-  llvm::GlobalVariable *Entry = CGObjC.CreateMetadataVar(
-      "OBJC_CLASS_NAME_",
-      llvm::ConstantDataArray::get(CGM.getLLVMContext(), buffer),
-      (isNonFragileABI ? "__TEXT,__objc_classname,cstring_literals"
-                       : "__TEXT,__cstring,cstring_literals"),
-      CharUnits::One(), true);
+  auto *Entry = CGObjC.CreateCStringLiteral(
+      reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);
   return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
 }
 
@@ -5062,16 +5101,9 @@ CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
 
 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
   llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
-
   // FIXME: Avoid std::string in "Sel.getAsString()"
   if (!Entry)
-    Entry = CreateMetadataVar(
-        "OBJC_METH_VAR_NAME_",
-        llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
-        ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals"
-                        : "__TEXT,__cstring,cstring_literals"),
-        CharUnits::One(), true);
-
+    Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
@@ -5085,15 +5117,8 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
   CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
 
   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
-
   if (!Entry)
-    Entry = CreateMetadataVar(
-        "OBJC_METH_VAR_TYPE_",
-        llvm::ConstantDataArray::getString(VMContext, TypeStr),
-        ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
-                        : "__TEXT,__cstring,cstring_literals"),
-        CharUnits::One(), true);
-
+    Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
@@ -5104,28 +5129,16 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
     return nullptr;
 
   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
-
   if (!Entry)
-    Entry = CreateMetadataVar(
-        "OBJC_METH_VAR_TYPE_",
-        llvm::ConstantDataArray::getString(VMContext, TypeStr),
-        ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
-                        : "__TEXT,__cstring,cstring_literals"),
-        CharUnits::One(), true);
-
+    Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
 // FIXME: Merge into a single cstring creation function.
 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
   llvm::GlobalVariable *&Entry = PropertyNames[Ident];
-
   if (!Entry)
-    Entry = CreateMetadataVar(
-        "OBJC_PROP_NAME_ATTR_",
-        llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
-        "__TEXT,__cstring,cstring_literals", CharUnits::One(), true);
-
+    Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
   return getConstantGEP(VMContext, Entry, 0, 0);
 }