summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2008-02-21 17:57:49 +0000
committerEli Friedman <eli.friedman@gmail.com>2008-02-21 17:57:49 +0000
commita243311f1d799019a55eae2ad02aa1352b8a6a35 (patch)
tree10e36f18930dd1a82b83d99bf1bf8d2e762470a7
parent115e98998560978c51239c012cb3160bf37882d9 (diff)
downloadbcm5719-llvm-a243311f1d799019a55eae2ad02aa1352b8a6a35.tar.gz
bcm5719-llvm-a243311f1d799019a55eae2ad02aa1352b8a6a35.zip
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. llvm-svn: 47440
-rw-r--r--clang/CodeGen/CGExprConstant.cpp48
1 files changed, 24 insertions, 24 deletions
diff --git a/clang/CodeGen/CGExprConstant.cpp b/clang/CodeGen/CGExprConstant.cpp
index 2cdd5bbb3ea..1a60cae5a07 100644
--- a/clang/CodeGen/CGExprConstant.cpp
+++ b/clang/CodeGen/CGExprConstant.cpp
@@ -200,34 +200,36 @@ public:
// 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 @@ public:
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!");
OpenPOWER on IntegriCloud