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
This commit is contained in:
Eli Friedman 2008-02-21 17:57:49 +00:00
parent 115e989985
commit a243311f1d
1 changed files with 24 additions and 24 deletions

View File

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