Clean up constant implicit cast emission; fixes a few edge cases 
invlolving implicit casts that cause both a decay to pointer type and a 
type conversion.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47440 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExprConstant.cpp b/CodeGen/CGExprConstant.cpp
index 2cdd5bb..1a60cae 100644
--- a/CodeGen/CGExprConstant.cpp
+++ b/CodeGen/CGExprConstant.cpp
@@ -200,34 +200,36 @@
     // Make sure we have an array at this point
     assert(0 && "Unable to handle InitListExpr");
   }
-  
+
   llvm::Constant *VisitImplicitCastExpr(ImplicitCastExpr *ICExpr) {
-    // If this is due to array->pointer conversion, emit the array expression as
-    // an l-value.
-    if (ICExpr->getSubExpr()->getType()->isArrayType()) {
-      // Note that VLAs can't exist for global variables.
-      llvm::Constant *C = EmitLValue(ICExpr->getSubExpr());
-      assert(isa<llvm::PointerType>(C->getType()) &&
-             isa<llvm::ArrayType>(cast<llvm::PointerType>(C->getType())
-                                  ->getElementType()));
+    Expr* SExpr = ICExpr->getSubExpr();
+    QualType SType = SExpr->getType();
+    llvm::Constant *C; // the intermediate expression
+    QualType T;        // the type of the intermediate expression
+    if (SType->isArrayType()) {
+      // Arrays decay to a pointer to the first element
+      // VLAs would require special handling, but they can't occur here
+      C = EmitLValue(SExpr);
       llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
-      
       llvm::Constant *Ops[] = {Idx0, Idx0};
       C = llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
-      
-      // The resultant pointer type can be implicitly cast to other pointer
-      // types as well, for example void*.
-      const llvm::Type *DestPTy = ConvertType(ICExpr->getType());
-      assert(isa<llvm::PointerType>(DestPTy) &&
-             "Only expect implicit cast to pointer");
-      return llvm::ConstantExpr::getBitCast(C, DestPTy);
+
+      QualType ElemType = SType->getAsArrayType()->getElementType();
+      T = CGM.getContext().getPointerType(ElemType);
+    } else if (SType->isFunctionType()) {
+      // Function types decay to a pointer to the function
+      C = EmitLValue(SExpr);
+      T = CGM.getContext().getPointerType(SType);
+    } else {
+      C = Visit(SExpr);
+      T = SType;
     }
-    
-    llvm::Constant *C = Visit(ICExpr->getSubExpr());
-    
-    return EmitConversion(C, ICExpr->getSubExpr()->getType(),ICExpr->getType());
+
+    // Perform the conversion; note that an implicit cast can both promote
+    // and convert an array/function
+    return EmitConversion(C, T, ICExpr->getType());
   }
-  
+
   llvm::Constant *VisitStringLiteral(StringLiteral *E) {
     const char *StrData = E->getStrData();
     unsigned Len = E->getByteLength();
@@ -254,8 +256,6 @@
 
   llvm::Constant *VisitDeclRefExpr(DeclRefExpr *E) {
     const ValueDecl *Decl = E->getDecl();
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
-      return CGM.GetAddrOfFunctionDecl(FD, false);
     if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(Decl))
       return llvm::ConstantInt::get(EC->getInitVal());
     assert(0 && "Unsupported decl ref type!");