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/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2af6ab1..373296f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1178,8 +1178,8 @@
   InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
   if (!InitList) {
     // FIXME: Handle wide strings
-    if (StringLiteral *strLiteral = IsStringLiteralInit(Init, DeclType))
-      return CheckStringLiteralInit(strLiteral, DeclType);
+    if (StringLiteral *StrLiteral = IsStringLiteralInit(Init, DeclType))
+      return CheckStringLiteralInit(StrLiteral, DeclType);
 
     // C++ [dcl.init]p14:
     //   -- If the destination type is a (possibly cv-qualified) class
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 9bcc810..7696cf0 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -95,8 +95,19 @@
                                                  SourceLocation RParenLoc) {
   QualType EncodedType = QualType::getFromOpaquePtr(ty);
 
-  QualType Ty = Context.getPointerType(Context.CharTy);
-  return new (Context) ObjCEncodeExpr(Ty, EncodedType, AtLoc, RParenLoc);
+  std::string Str;
+  Context.getObjCEncodingForType(EncodedType, Str);
+
+  // The type of @encode is the same as the type of the corresponding string,
+  // which is an array type.
+  QualType StrTy = Context.CharTy;
+  // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+  if (getLangOptions().CPlusPlus)
+    StrTy.addConst();
+  StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
+                                       ArrayType::Normal, 0);
+  
+  return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
 }
 
 Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,