Tweaks to EmitLValue in CGExprConstant. Patch by Eli Friedman.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46389 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExprConstant.cpp b/CodeGen/CGExprConstant.cpp
index 4b3b3cb..5808da4 100644
--- a/CodeGen/CGExprConstant.cpp
+++ b/CodeGen/CGExprConstant.cpp
@@ -22,7 +22,8 @@
using namespace CodeGen;
namespace {
-class VISIBILITY_HIDDEN ConstExprEmitter : public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
+class VISIBILITY_HIDDEN ConstExprEmitter :
+ public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
CodeGenModule &CGM;
public:
ConstExprEmitter(CodeGenModule &cgm)
@@ -285,7 +286,7 @@
// The source value may be an integer, or a pointer.
if (isa<llvm::PointerType>(Src->getType()))
return llvm::ConstantExpr::getBitCast(Src, DstTy);
- assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
+ assert(SrcType->isIntegerType() &&"Not ptr->ptr or int->ptr conversion?");
return llvm::ConstantExpr::getIntToPtr(Src, DstTy);
}
@@ -353,8 +354,8 @@
CGM.getContext().getTypeSize(RetType, SourceLocation()));
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
}
-
- llvm::Constant *EmitLValue(const Expr *E) {
+
+ llvm::Constant *EmitLValue(Expr *E) {
switch (E->getStmtClass()) {
default: {
CGM.WarnUnsupported(E, "constant l-value expression");
@@ -367,15 +368,15 @@
case Expr::CompoundLiteralExprClass: {
// Note that due to the nature of compound literals, this is guaranteed
// to be the only use of the variable, so we just generate it here.
- const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
- llvm::Constant* C = CGM.EmitGlobalInit(CLE->getInitializer());
- C =new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(),
+ CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+ llvm::Constant* C = Visit(CLE->getInitializer());
+ C = new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(),
llvm::GlobalValue::InternalLinkage,
C, ".compoundliteral", &CGM.getModule());
return C;
- }
+ }
case Expr::DeclRefExprClass: {
- const ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
+ ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
return CGM.GetAddrOfFunctionDecl(FD, false);
if (const FileVarDecl* FVD = dyn_cast<FileVarDecl>(Decl))
@@ -386,9 +387,13 @@
return 0;
}
case Expr::MemberExprClass: {
- const MemberExpr* ME = cast<MemberExpr>(E);
+ MemberExpr* ME = cast<MemberExpr>(E);
unsigned FieldNumber = CGM.getTypes().getLLVMFieldNo(ME->getMemberDecl());
- llvm::Constant *Base = EmitLValue(ME->getBase());
+ llvm::Constant *Base;
+ if (ME->isArrow())
+ Base = Visit(ME->getBase());
+ else
+ Base = EmitLValue(ME->getBase());
llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
FieldNumber);
@@ -396,46 +401,46 @@
return llvm::ConstantExpr::getGetElementPtr(Base, Ops, 2);
}
case Expr::ArraySubscriptExprClass: {
- const ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
- llvm::Constant *Base = EmitLValue(ASExpr->getBase());
- llvm::Constant *Index = EmitLValue(ASExpr->getIdx());
+ ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
+ llvm::Constant *Base = Visit(ASExpr->getBase());
+ llvm::Constant *Index = Visit(ASExpr->getIdx());
assert(!ASExpr->getBase()->getType()->isVectorType() &&
"Taking the address of a vector component is illegal!");
return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
}
case Expr::StringLiteralClass: {
- const StringLiteral *String = cast<StringLiteral>(E);
+ StringLiteral *String = cast<StringLiteral>(E);
assert(!String->isWide() && "Cannot codegen wide strings yet");
- const char *StrData = String->getStrData();
- unsigned Len = String->getByteLength();
+ const char *StrData = String->getStrData();
+ unsigned Len = String->getByteLength();
- return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
- }
- case Expr::UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(E);
- switch (Exp->getOpcode()) {
- default: assert(0 && "Unsupported unary operator.");
- case UnaryOperator::Extension:
- // Extension is just a wrapper for expressions
- return EmitLValue(Exp->getSubExpr());
- case UnaryOperator::Real:
- case UnaryOperator::Imag: {
- // The address of __real or __imag is just a GEP off the address
- // of the internal expression
- llvm::Constant* C = EmitLValue(Exp->getSubExpr());
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
+ return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
+ }
+ case Expr::UnaryOperatorClass: {
+ UnaryOperator *Exp = cast<UnaryOperator>(E);
+ switch (Exp->getOpcode()) {
+ default: assert(0 && "Unsupported unary operator.");
+ case UnaryOperator::Extension:
+ // Extension is just a wrapper for expressions
+ return EmitLValue(Exp->getSubExpr());
+ case UnaryOperator::Real:
+ case UnaryOperator::Imag: {
+ // The address of __real or __imag is just a GEP off the address
+ // of the internal expression
+ llvm::Constant* C = EmitLValue(Exp->getSubExpr());
+ llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+ llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
Exp->getOpcode() == UnaryOperator::Imag);
- llvm::Value *Ops[] = {Zero, Idx};
- return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
+ llvm::Value *Ops[] = {Zero, Idx};
+ return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
+ }
+ case UnaryOperator::Deref:
+ // The address of a deref is just the value of the expression
+ return Visit(Exp->getSubExpr());
+ }
}
- case UnaryOperator::Deref:
- // The address of a deref is just the value of the expression
- return Visit(Exp->getSubExpr());
- }
+ }
}
- }
-}
};