forked from OSchip/llvm-project
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:
parent
115e989985
commit
a243311f1d
|
@ -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!");
|
||||||
|
|
Loading…
Reference in New Issue