[cfe-commits] r54768 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CGObjCGNU.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/c-strings.c

Daniel Dunbar daniel at zuster.org
Wed Aug 13 16:20:11 PDT 2008


Author: ddunbar
Date: Wed Aug 13 18:20:05 2008
New Revision: 54768

URL: http://llvm.org/viewvc/llvm-project?rev=54768&view=rev
Log:
Add GetAddrOfConstantCString method
 - Returns addr of constant for argument + '\0'.
 - I couldn't think of a better name.
 - Move appropriate users of GetAddrOfConstantString to this.

Rename getStringForStringLiteral to GetStringForStringLiteral.

Add GetAddrOfConstantStringFromLiteral
 - This combines GetAddrOfConstantString and
   GetStringForStringLiteral. This method can be, but is not yet, more
   efficient.

Change GetAddrOfConstantString to not add terminating '\0'
 - <rdar://problem/6140956>

Added:
    cfe/trunk/test/CodeGen/c-strings.c
Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=54768&r1=54767&r2=54768&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Aug 13 18:20:05 2008
@@ -488,10 +488,7 @@
 }
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
-  llvm::Constant *C = 
-    CGM.GetAddrOfConstantString(CGM.getStringForStringLiteral(E));
-
-  return LValue::MakeAddr(C,0);
+  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E), 0);
 }
 
 LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=54768&r1=54767&r2=54768&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Aug 13 18:20:05 2008
@@ -363,7 +363,7 @@
     // Otherwise this must be a string initializing an array in a static
     // initializer.  Don't emit it as the address of the string, emit the string
     // data itself as an inline array.
-    return llvm::ConstantArray::get(CGM.getStringForStringLiteral(E), false);
+    return llvm::ConstantArray::get(CGM.GetStringForStringLiteral(E), false);
   }
 
   llvm::Constant *VisitDeclRefExpr(DeclRefExpr *E) {
@@ -762,10 +762,8 @@
              "Taking the address of a vector component is illegal!");
       return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
     }
-    case Expr::StringLiteralClass: {
-      StringLiteral *S = cast<StringLiteral>(E);
-      return CGM.GetAddrOfConstantString(CGM.getStringForStringLiteral(S));
-    }
+    case Expr::StringLiteralClass:
+      return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
     case Expr::UnaryOperatorClass: {
       UnaryOperator *Exp = cast<UnaryOperator>(E);
       switch (Exp->getOpcode()) {

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=54768&r1=54767&r2=54768&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Wed Aug 13 18:20:05 2008
@@ -52,7 +52,7 @@
     if (!strcmp(classname, "super")) {
       classname = E->getMethodDecl()->getClassInterface()->getName();
     }
-    llvm::Value *ClassName = CGM.GetAddrOfConstantString(classname);
+    llvm::Value *ClassName = CGM.GetAddrOfConstantCString(classname);
     ClassName = Builder.CreateStructGEP(ClassName, 0);
     Receiver = Runtime.LookupClass(Builder, ClassName);
   } else if (const PredefinedExpr *PDE =

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=54768&r1=54767&r2=54768&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Wed Aug 13 18:20:05 2008
@@ -370,7 +370,7 @@
   std::vector<llvm::Constant*> Elements;
   for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
     Elements.clear();
-    llvm::Constant *C = CGM.GetAddrOfConstantString(MethodSels[i].getName());
+    llvm::Constant *C = CGM.GetAddrOfConstantCString(MethodSels[i].getName());
     Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2));
     Elements.push_back(
           llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
@@ -581,8 +581,8 @@
     std::string TypeStr;
     Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
     InstanceMethodNames.push_back(
-        CGM.GetAddrOfConstantString((*iter)->getSelector().getName()));
-    InstanceMethodTypes.push_back(CGM.GetAddrOfConstantString(TypeStr));
+        CGM.GetAddrOfConstantCString((*iter)->getSelector().getName()));
+    InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
   }
   // Collect information about class methods:
   llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
@@ -592,8 +592,8 @@
     std::string TypeStr;
     Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
     ClassMethodNames.push_back(
-        CGM.GetAddrOfConstantString((*iter)->getSelector().getName()));
-    ClassMethodTypes.push_back(CGM.GetAddrOfConstantString(TypeStr));
+        CGM.GetAddrOfConstantCString((*iter)->getSelector().getName()));
+    ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
   }
 
   llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=54768&r1=54767&r2=54768&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Aug 13 18:20:05 2008
@@ -261,7 +261,7 @@
     InstanceMethodSels.push_back((*iter)->getSelector());
     std::string TypeStr;
     Context.getObjCEncodingForMethodDecl(*iter,TypeStr);
-    InstanceMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
+    InstanceMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
   }
 
   // Collect information about class methods
@@ -272,7 +272,7 @@
     ClassMethodSels.push_back((*iter)->getSelector());
     std::string TypeStr;
     Context.getObjCEncodingForMethodDecl(*iter,TypeStr);
-    ClassMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
+    ClassMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
   }
 
   // Collect the names of referenced protocols
@@ -325,13 +325,13 @@
   for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
       endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
       // Store the name
-      IvarNames.push_back(GetAddrOfConstantString((*iter)->getName()));
+      IvarNames.push_back(GetAddrOfConstantCString((*iter)->getName()));
       // Get the type encoding for this ivar
       std::string TypeStr;
       llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
       Context.getObjCEncodingForType((*iter)->getType(), TypeStr,
                                      EncodingRecordTypes);
-      IvarTypes.push_back(GetAddrOfConstantString(TypeStr));
+      IvarTypes.push_back(GetAddrOfConstantCString(TypeStr));
       // Get the offset
       int offset =
         (int)Layout->getElementOffset(getTypes().getLLVMFieldNo(*iter));
@@ -347,7 +347,7 @@
     InstanceMethodSels.push_back((*iter)->getSelector());
     std::string TypeStr;
     Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
-    InstanceMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
+    InstanceMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
   }
 
   // Collect information about class methods
@@ -358,7 +358,7 @@
     ClassMethodSels.push_back((*iter)->getSelector());
     std::string TypeStr;
     Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
-    ClassMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
+    ClassMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
   }
   // Collect the names of referenced protocols
   llvm::SmallVector<std::string, 16> Protocols;
@@ -888,9 +888,9 @@
   return GV;
 }
 
-/// getStringForStringLiteral - Return the appropriate bytes for a
+/// GetStringForStringLiteral - Return the appropriate bytes for a
 /// string literal, properly padded to match the literal type.
-std::string CodeGenModule::getStringForStringLiteral(const StringLiteral *E) {
+std::string CodeGenModule::GetStringForStringLiteral(const StringLiteral *E) {
   assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
   const char *StrData = E->getStrData();
   unsigned Len = E->getByteLength();
@@ -908,22 +908,37 @@
   return Str;
 }
 
+/// GetAddrOfConstantStringFromLiteral - Return a pointer to a
+/// constant array for the given string literal.
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
+  // FIXME: This can be more efficient.
+  return GetAddrOfConstantString(GetStringForStringLiteral(S));
+}
+
 /// GenerateWritableString -- Creates storage for a string literal.
 static llvm::Constant *GenerateStringLiteral(const std::string &str, 
                                              bool constant,
                                              CodeGenModule &CGM) {
-  // Create Constant for this string literal
-  llvm::Constant *C = llvm::ConstantArray::get(str);
+  // Create Constant for this string literal. Don't add a '\0'.
+  llvm::Constant *C = llvm::ConstantArray::get(str, false);
   
   // Create a global variable for this string
   C = new llvm::GlobalVariable(C->getType(), constant, 
                                llvm::GlobalValue::InternalLinkage,
                                C, ".str", &CGM.getModule());
+
   return C;
 }
 
-/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the character
-/// array containing the literal.  The result is pointer to array type.
+/// GetAddrOfConstantString - Returns a pointer to a character array
+/// containing the literal. This contents are exactly that of the
+/// given string, i.e. it will not be null terminated automatically;
+/// see GetAddrOfConstantCString. Note that whether the result is
+/// actually a pointer to an LLVM constant depends on
+/// Feature.WriteableStrings.
+///
+/// The result has pointer to array type.
 llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) {
   // Don't share any string literals if writable-strings is turned on.
   if (Features.WritableStrings)
@@ -940,3 +955,10 @@
   Entry.setValue(C);
   return C;
 }
+
+/// GetAddrOfConstantCString - Returns a pointer to a character
+/// array containing the literal and a terminating '\-'
+/// character. The result has pointer to array type.
+llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str) {
+  return GetAddrOfConstantCString(str + "\0");
+}

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=54768&r1=54767&r2=54768&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Aug 13 18:20:05 2008
@@ -143,15 +143,34 @@
   /// "__builtin_fabsf", return a Function* for "fabsf".
   ///
   llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
-  llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
 
-  /// getStringForStringLiteral - Return the appropriate bytes for a
-  /// string literal, properly padded to match the literal type.
-  std::string getStringForStringLiteral(const StringLiteral *E);
+  /// GetStringForStringLiteral - Return the appropriate bytes for a
+  /// string literal, properly padded to match the literal type. If
+  /// only the address of a constant is needed consider using
+  /// GetAddrOfConstantStringLiteral.
+  std::string GetStringForStringLiteral(const StringLiteral *E);
+
+  llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
 
-  /// GetAddrOfConstantString -- returns a pointer to the character
-  /// array containing the literal.  The result is pointer to array type.
+  /// GetAddrOfConstantStringFromLiteral - Return a pointer to a
+  /// constant array for the given string literal.
+  llvm::Constant *GetAddrOfConstantStringFromLiteral(const StringLiteral *S);
+
+  /// GetAddrOfConstantString - Returns a pointer to a character array
+  /// containing the literal. This contents are exactly that of the
+  /// given string, i.e. it will not be null terminated automatically;
+  /// see GetAddrOfConstantCString. Note that whether the result is
+  /// actually a pointer to an LLVM constant depends on
+  /// Feature.WriteableStrings.
+  ///
+  /// The result has pointer to array type.
   llvm::Constant *GetAddrOfConstantString(const std::string& str);
+
+  /// GetAddrOfConstantCString - Returns a pointer to a character
+  /// array containing the literal and a terminating '\-'
+  /// character. The result has pointer to array type.
+  llvm::Constant *GetAddrOfConstantCString(const std::string &str);
+
   llvm::Function *getMemCpyFn();
   llvm::Function *getMemMoveFn();
   llvm::Function *getMemSetFn();

Added: cfe/trunk/test/CodeGen/c-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/c-strings.c?rev=54768&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/c-strings.c (added)
+++ cfe/trunk/test/CodeGen/c-strings.c Wed Aug 13 18:20:05 2008
@@ -0,0 +1,34 @@
+// RUN: clang -emit-llvm -o %t %s &&
+// RUN: grep "hello" %t | count 3 &&
+// RUN: grep 'c"hello\\00"' %t | count 2 &&
+// RUN: grep 'c"hello\\00\\00\\00"' %t | count 1
+
+/* Should be 3 hello string, two global (of different sizes), the rest
+   are shared. */
+
+void f0() {
+  bar("hello");
+}
+
+void f1() {
+  static char *x = "hello";
+  bar(x);
+}
+
+void f2() {
+  static char x[] = "hello";
+  bar(x);
+}
+
+void f3() {
+  static char x[8] = "hello";
+  bar(x);
+}
+
+void f4() {
+  static struct s {
+    char *name;
+  } x = { "hello" };
+  gaz(&x);
+}
+





More information about the cfe-commits mailing list