forked from OSchip/llvm-project
Tweaks to EmitLValue in CGExprConstant. Patch by Eli Friedman.
llvm-svn: 46389
This commit is contained in:
parent
a413911373
commit
8a88c3815a
|
@ -22,7 +22,8 @@ using namespace clang;
|
||||||
using namespace CodeGen;
|
using namespace CodeGen;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VISIBILITY_HIDDEN ConstExprEmitter : public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
|
class VISIBILITY_HIDDEN ConstExprEmitter :
|
||||||
|
public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
|
||||||
CodeGenModule &CGM;
|
CodeGenModule &CGM;
|
||||||
public:
|
public:
|
||||||
ConstExprEmitter(CodeGenModule &cgm)
|
ConstExprEmitter(CodeGenModule &cgm)
|
||||||
|
@ -285,7 +286,7 @@ public:
|
||||||
// The source value may be an integer, or a pointer.
|
// The source value may be an integer, or a pointer.
|
||||||
if (isa<llvm::PointerType>(Src->getType()))
|
if (isa<llvm::PointerType>(Src->getType()))
|
||||||
return llvm::ConstantExpr::getBitCast(Src, DstTy);
|
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);
|
return llvm::ConstantExpr::getIntToPtr(Src, DstTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,8 +354,8 @@ public:
|
||||||
CGM.getContext().getTypeSize(RetType, SourceLocation()));
|
CGM.getContext().getTypeSize(RetType, SourceLocation()));
|
||||||
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
|
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Constant *EmitLValue(const Expr *E) {
|
llvm::Constant *EmitLValue(Expr *E) {
|
||||||
switch (E->getStmtClass()) {
|
switch (E->getStmtClass()) {
|
||||||
default: {
|
default: {
|
||||||
CGM.WarnUnsupported(E, "constant l-value expression");
|
CGM.WarnUnsupported(E, "constant l-value expression");
|
||||||
|
@ -367,15 +368,15 @@ public:
|
||||||
case Expr::CompoundLiteralExprClass: {
|
case Expr::CompoundLiteralExprClass: {
|
||||||
// Note that due to the nature of compound literals, this is guaranteed
|
// 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.
|
// to be the only use of the variable, so we just generate it here.
|
||||||
const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
|
CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
|
||||||
llvm::Constant* C = CGM.EmitGlobalInit(CLE->getInitializer());
|
llvm::Constant* C = Visit(CLE->getInitializer());
|
||||||
C =new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(),
|
C = new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(),
|
||||||
llvm::GlobalValue::InternalLinkage,
|
llvm::GlobalValue::InternalLinkage,
|
||||||
C, ".compoundliteral", &CGM.getModule());
|
C, ".compoundliteral", &CGM.getModule());
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
case Expr::DeclRefExprClass: {
|
case Expr::DeclRefExprClass: {
|
||||||
const ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
|
ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
|
||||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
|
||||||
return CGM.GetAddrOfFunctionDecl(FD, false);
|
return CGM.GetAddrOfFunctionDecl(FD, false);
|
||||||
if (const FileVarDecl* FVD = dyn_cast<FileVarDecl>(Decl))
|
if (const FileVarDecl* FVD = dyn_cast<FileVarDecl>(Decl))
|
||||||
|
@ -386,9 +387,13 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case Expr::MemberExprClass: {
|
case Expr::MemberExprClass: {
|
||||||
const MemberExpr* ME = cast<MemberExpr>(E);
|
MemberExpr* ME = cast<MemberExpr>(E);
|
||||||
unsigned FieldNumber = CGM.getTypes().getLLVMFieldNo(ME->getMemberDecl());
|
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 *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
|
||||||
llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
|
llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
|
||||||
FieldNumber);
|
FieldNumber);
|
||||||
|
@ -396,46 +401,46 @@ public:
|
||||||
return llvm::ConstantExpr::getGetElementPtr(Base, Ops, 2);
|
return llvm::ConstantExpr::getGetElementPtr(Base, Ops, 2);
|
||||||
}
|
}
|
||||||
case Expr::ArraySubscriptExprClass: {
|
case Expr::ArraySubscriptExprClass: {
|
||||||
const ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
|
ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
|
||||||
llvm::Constant *Base = EmitLValue(ASExpr->getBase());
|
llvm::Constant *Base = Visit(ASExpr->getBase());
|
||||||
llvm::Constant *Index = EmitLValue(ASExpr->getIdx());
|
llvm::Constant *Index = Visit(ASExpr->getIdx());
|
||||||
assert(!ASExpr->getBase()->getType()->isVectorType() &&
|
assert(!ASExpr->getBase()->getType()->isVectorType() &&
|
||||||
"Taking the address of a vector component is illegal!");
|
"Taking the address of a vector component is illegal!");
|
||||||
return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
|
return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
|
||||||
}
|
}
|
||||||
case Expr::StringLiteralClass: {
|
case Expr::StringLiteralClass: {
|
||||||
const StringLiteral *String = cast<StringLiteral>(E);
|
StringLiteral *String = cast<StringLiteral>(E);
|
||||||
assert(!String->isWide() && "Cannot codegen wide strings yet");
|
assert(!String->isWide() && "Cannot codegen wide strings yet");
|
||||||
const char *StrData = String->getStrData();
|
const char *StrData = String->getStrData();
|
||||||
unsigned Len = String->getByteLength();
|
unsigned Len = String->getByteLength();
|
||||||
|
|
||||||
return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
|
return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
|
||||||
}
|
}
|
||||||
case Expr::UnaryOperatorClass: {
|
case Expr::UnaryOperatorClass: {
|
||||||
const UnaryOperator *Exp = cast<UnaryOperator>(E);
|
UnaryOperator *Exp = cast<UnaryOperator>(E);
|
||||||
switch (Exp->getOpcode()) {
|
switch (Exp->getOpcode()) {
|
||||||
default: assert(0 && "Unsupported unary operator.");
|
default: assert(0 && "Unsupported unary operator.");
|
||||||
case UnaryOperator::Extension:
|
case UnaryOperator::Extension:
|
||||||
// Extension is just a wrapper for expressions
|
// Extension is just a wrapper for expressions
|
||||||
return EmitLValue(Exp->getSubExpr());
|
return EmitLValue(Exp->getSubExpr());
|
||||||
case UnaryOperator::Real:
|
case UnaryOperator::Real:
|
||||||
case UnaryOperator::Imag: {
|
case UnaryOperator::Imag: {
|
||||||
// The address of __real or __imag is just a GEP off the address
|
// The address of __real or __imag is just a GEP off the address
|
||||||
// of the internal expression
|
// of the internal expression
|
||||||
llvm::Constant* C = EmitLValue(Exp->getSubExpr());
|
llvm::Constant* C = EmitLValue(Exp->getSubExpr());
|
||||||
llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
|
llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
|
||||||
llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
|
llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
|
||||||
Exp->getOpcode() == UnaryOperator::Imag);
|
Exp->getOpcode() == UnaryOperator::Imag);
|
||||||
llvm::Value *Ops[] = {Zero, Idx};
|
llvm::Value *Ops[] = {Zero, Idx};
|
||||||
return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
|
return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
|
||||||
}
|
}
|
||||||
case UnaryOperator::Deref:
|
case UnaryOperator::Deref:
|
||||||
// The address of a deref is just the value of the expression
|
// The address of a deref is just the value of the expression
|
||||||
return Visit(Exp->getSubExpr());
|
return Visit(Exp->getSubExpr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F50AC50D416EAA00B9CF60 /* Targets.cpp */; };
|
03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F50AC50D416EAA00B9CF60 /* Targets.cpp */; };
|
||||||
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
|
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
|
||||||
|
1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */; };
|
||||||
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
|
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
|
||||||
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
|
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
|
||||||
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
|
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
|
||||||
|
@ -221,6 +222,7 @@
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
03F50AC50D416EAA00B9CF60 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Targets.cpp; sourceTree = "<group>"; };
|
03F50AC50D416EAA00B9CF60 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Targets.cpp; sourceTree = "<group>"; };
|
||||||
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
|
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
|
||||||
|
1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprConstant.cpp; path = CodeGen/CGExprConstant.cpp; sourceTree = "<group>"; };
|
||||||
1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PPCBuiltins.def; path = clang/AST/PPCBuiltins.def; sourceTree = "<group>"; };
|
1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PPCBuiltins.def; path = clang/AST/PPCBuiltins.def; sourceTree = "<group>"; };
|
||||||
1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetBuiltins.h; path = clang/AST/TargetBuiltins.h; sourceTree = "<group>"; };
|
1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetBuiltins.h; path = clang/AST/TargetBuiltins.h; sourceTree = "<group>"; };
|
||||||
1A68BC130D0CADDD001A28C8 /* X86Builtins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = X86Builtins.def; path = clang/AST/X86Builtins.def; sourceTree = "<group>"; };
|
1A68BC130D0CADDD001A28C8 /* X86Builtins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = X86Builtins.def; path = clang/AST/X86Builtins.def; sourceTree = "<group>"; };
|
||||||
|
@ -580,6 +582,7 @@
|
||||||
DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
|
DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
|
||||||
DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */,
|
DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */,
|
||||||
DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */,
|
DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */,
|
||||||
|
1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */,
|
||||||
DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */,
|
DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */,
|
||||||
1A7342470C7B57D500122F56 /* CGObjC.cpp */,
|
1A7342470C7B57D500122F56 /* CGObjC.cpp */,
|
||||||
DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
|
DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
|
||||||
|
@ -901,6 +904,7 @@
|
||||||
35BB2D7F0D19954000944DB5 /* ASTConsumer.cpp in Sources */,
|
35BB2D7F0D19954000944DB5 /* ASTConsumer.cpp in Sources */,
|
||||||
DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */,
|
DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */,
|
||||||
03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */,
|
03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */,
|
||||||
|
1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue