Add support for generating reference initialization code.

llvm-svn: 68852
This commit is contained in:
Anders Carlsson 2009-04-11 01:08:03 +00:00
parent 4531be138c
commit d8e39bbb84
2 changed files with 32 additions and 2 deletions

View File

@ -474,7 +474,26 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
CodeGenFunction *CGF) {
Expr::EvalResult Result;
if (E->Evaluate(Result, Context)) {
bool Success = false;
if (DestType->isReferenceType()) {
// If the destination type is a reference type, we need to evaluate it
// as an lvalue.
if (E->EvaluateAsLValue(Result, Context)) {
if (const Expr *LVBase = Result.Val.getLValueBase()) {
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LVBase)) {
const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl());
// We can only initialize a reference with an lvalue if the lvalue
// is not a reference itself.
Success = !VD->getType()->isReferenceType();
}
}
}
} else
Success = E->Evaluate(Result, Context);
if (Success) {
assert(!Result.HasSideEffects &&
"Constant expr should not have any side effects!");
switch (Result.Val.getKind()) {
@ -482,7 +501,7 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
assert(0 && "Constant expressions should be initialized.");
return 0;
case APValue::LValue: {
const llvm::Type *DestTy = getTypes().ConvertTypeForMem(E->getType());
const llvm::Type *DestTy = getTypes().ConvertTypeForMem(DestType);
llvm::Constant *Offset =
llvm::ConstantInt::get(llvm::Type::Int64Ty,
Result.Val.getLValueOffset());

View File

@ -0,0 +1,11 @@
// RUN: clang-cc -verify -emit-llvm -o %t %s
int a = 10;
int &ar = a;
void f();
void (&fr)() = f;
struct S { int& a; };
S s = { a };