]> granicus.if.org Git - clang/commitdiff
Make sema and codegen allow __builtin___CFStringMakeConstantString as a valid
authorChris Lattner <sabre@nondot.org>
Mon, 6 Oct 2008 07:26:43 +0000 (07:26 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 6 Oct 2008 07:26:43 +0000 (07:26 +0000)
constant lvalue.  Implement this in codegen by moving the code out of CGBuiltin
into EmitConstantExpr.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57163 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/CGExprConstant.cpp
lib/Sema/SemaDecl.cpp
test/CodeGen/cfstring.c

index fc7cc027104654808a63a1478a6f89f08270fa6d..29d77b6e82b3b559655e9e46a06fa5383670a441 100644 (file)
@@ -48,23 +48,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
       
   switch (BuiltinID) {
   default: break;  // Handle intrinsics and libm functions below.
-  case Builtin::BI__builtin___CFStringMakeConstantString: {
-    const Expr *Arg = E->getArg(0);
-    
-    while (1) {
-      if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
-        Arg = PE->getSubExpr();
-      else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
-        Arg = CE->getSubExpr();
-      else
-        break;
-    }
-    
-    const StringLiteral *Literal = cast<StringLiteral>(Arg);
-    std::string S(Literal->getStrData(), Literal->getByteLength());
-    
-    return RValue::get(CGM.GetAddrOfConstantCFString(S));
-  }
+  case Builtin::BI__builtin___CFStringMakeConstantString:
+    return RValue::get(CGM.EmitConstantExpr(E, 0));
   case Builtin::BI__builtin_stdarg_start:
   case Builtin::BI__builtin_va_start:
   case Builtin::BI__builtin_va_end: {
index 50f0d122405ff7d06ff4991c3b1a2a12810b7a03..69abbcc984c1b7a66b8b0e4ad451e8c903a6e5d2 100644 (file)
@@ -617,6 +617,24 @@ public:
         return llvm::ConstantFP::get(Result.getFloat());
     }
 
+    // Handle __builtin___CFStringMakeConstantString.
+    if (E->isBuiltinCall() ==Builtin::BI__builtin___CFStringMakeConstantString){
+      const Expr *Arg = E->getArg(0);
+      
+      while (1) {
+        if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
+          Arg = PE->getSubExpr();
+        else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
+          Arg = CE->getSubExpr();
+        else
+          break;
+      }
+      
+      const StringLiteral *Literal = cast<StringLiteral>(Arg);
+      std::string S(Literal->getStrData(), Literal->getByteLength());
+      return CGM.GetAddrOfConstantCFString(S);
+    }
+    
     CGM.ErrorUnsupported(E, "constant call expression");
     return llvm::Constant::getNullValue(ConvertType(E->getType()));
   }
index 125d91cdbafbd1dbe15b3d4fdc52afaeb8b7cb58..1b6ff878f57e4da89ee033e0ebca7e5202121e2d 100644 (file)
@@ -872,13 +872,21 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) {
     Diag(Init->getExprLoc(),
          diag::err_init_element_not_constant, Init->getSourceRange());
     return true;
-  case Expr::ParenExprClass: {
-    const ParenExpr* PE = cast<ParenExpr>(Init);
-    return CheckAddressConstantExpression(PE->getSubExpr());
-  }
+  case Expr::ParenExprClass:
+    return CheckAddressConstantExpression(cast<ParenExpr>(Init)->getSubExpr());
   case Expr::StringLiteralClass:
   case Expr::ObjCStringLiteralClass:
     return false;
+  case Expr::CallExprClass:
+    // __builtin___CFStringMakeConstantString is a valid constant l-value.
+    if (cast<CallExpr>(Init)->isBuiltinCall() == 
+           Builtin::BI__builtin___CFStringMakeConstantString)
+      return false;
+      
+    Diag(Init->getExprLoc(),
+         diag::err_init_element_not_constant, Init->getSourceRange());
+    return true;
+      
   case Expr::UnaryOperatorClass: {
     const UnaryOperator *Exp = cast<UnaryOperator>(Init);
 
index ef42d062839ff3e14712b20678b6aedca42149f0..7d7edeca3cb3a2f17ce10e0c0570914bef0cd341 100644 (file)
@@ -4,3 +4,8 @@
 void f() {
   CFSTR("Hello, World!");
 }
+
+// rdar://6248329
+void *G = CFSTR("yo joe");
+
+