first wave of fixes for @encode sema support.  This is part of PR3648.

The big difference here is that (like string literal) @encode has 
array type, not pointer type.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65391 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 1141c0d..487b274 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -76,7 +76,10 @@
         cast<llvm::ArrayType>(ConvertType(ILE->getType()));
     unsigned NumInitElements = ILE->getNumInits();
     // FIXME: Check for wide strings
-    if (NumInitElements > 0 && isa<StringLiteral>(ILE->getInit(0)) &&
+    // FIXME: Check for NumInitElements exactly equal to 1??
+    if (NumInitElements > 0 && 
+        (isa<StringLiteral>(ILE->getInit(0)) ||
+         isa<ObjCEncodeExpr>(ILE->getInit(0))) &&
         ILE->getType()->getArrayElementTypeNoTypeQual()->isCharType())
       return Visit(ILE->getInit(0));
     const llvm::Type *ElemTy = AType->getElementType();
@@ -346,12 +349,26 @@
   llvm::Constant *VisitStringLiteral(StringLiteral *E) {
     assert(!E->getType()->isPointerType() && "Strings are always arrays");
     
-    // 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.
+    // 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);
   }
 
+  llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+    // This must be an @encode 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.
+    std::string Str;
+    CGM.getContext().getObjCEncodingForType(E->getEncodedType(), Str);
+    const ConstantArrayType *CAT = cast<ConstantArrayType>(E->getType());
+    
+    // Resize the string to the right size, adding zeros at the end, or
+    // truncating as needed.
+    Str.resize(CAT->getSize().getZExtValue(), '\0');
+    return llvm::ConstantArray::get(Str, false);
+  }
+    
   llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) {
     return Visit(E->getSubExpr());
   }
@@ -398,6 +415,8 @@
     }
     case Expr::StringLiteralClass:
       return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
+    case Expr::ObjCEncodeExprClass:
+      return CGM.GetAddrOfConstantStringFromObjCEncode(cast<ObjCEncodeExpr>(E));
     case Expr::ObjCStringLiteralClass: {
       ObjCStringLiteral* SL = cast<ObjCStringLiteral>(E);
       std::string S(SL->getString()->getStrData(),