[cfe-commits] r47440 - /cfe/trunk/CodeGen/CGExprConstant.cpp

Eli Friedman eli.friedman at gmail.com
Thu Feb 21 09:57:49 PST 2008


Author: efriedma
Date: Thu Feb 21 11:57:49 2008
New Revision: 47440

URL: http://llvm.org/viewvc/llvm-project?rev=47440&view=rev
Log:
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.


Modified:
    cfe/trunk/CodeGen/CGExprConstant.cpp

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

==============================================================================
--- cfe/trunk/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/CodeGen/CGExprConstant.cpp Thu Feb 21 11:57:49 2008
@@ -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!");





More information about the cfe-commits mailing list