forked from OSchip/llvm-project
Enable CodeGen for member expressions based on call expressions returning aggregate types. This enables expressions like 'foo().member.submember'.
llvm-svn: 45395
This commit is contained in:
parent
fd9af54ad1
commit
d91c3d4926
|
@ -87,6 +87,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
||||||
return LValue::MakeAddr(llvm::UndefValue::get(Ty));
|
return LValue::MakeAddr(llvm::UndefValue::get(Ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Expr::CallExprClass: return EmitCallExprLValue(cast<CallExpr>(E));
|
||||||
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
|
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
|
||||||
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
|
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
|
||||||
case Expr::PreDefinedExprClass:
|
case Expr::PreDefinedExprClass:
|
||||||
|
@ -455,6 +456,12 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
|
||||||
return EmitCallExpr(Callee, E);
|
return EmitCallExpr(Callee, E);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
|
||||||
|
// Can only get l-value for call expression returning aggregate type
|
||||||
|
RValue RV = EmitCallExpr(E);
|
||||||
|
return LValue::MakeAddr(RV.getAggregateAddr());
|
||||||
|
}
|
||||||
|
|
||||||
RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, const CallExpr *E) {
|
RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, const CallExpr *E) {
|
||||||
// The callee type will always be a pointer to function type, get the function
|
// The callee type will always be a pointer to function type, get the function
|
||||||
// type.
|
// type.
|
||||||
|
|
|
@ -371,6 +371,9 @@ public:
|
||||||
/// is 'Ty'.
|
/// is 'Ty'.
|
||||||
void EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty);
|
void EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty);
|
||||||
void EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst, QualType Ty);
|
void EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst, QualType Ty);
|
||||||
|
|
||||||
|
// Note: only availabe for agg return types
|
||||||
|
LValue EmitCallExprLValue(const CallExpr *E);
|
||||||
|
|
||||||
LValue EmitDeclRefLValue(const DeclRefExpr *E);
|
LValue EmitDeclRefLValue(const DeclRefExpr *E);
|
||||||
LValue EmitStringLiteralLValue(const StringLiteral *E);
|
LValue EmitStringLiteralLValue(const StringLiteral *E);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// RUN: clang -emit-llvm < %s 2>&1 | not grep 'cannot codegen this l-value expression yet'
|
||||||
|
|
||||||
|
struct frk { float _Complex c; int x; };
|
||||||
|
struct faz { struct frk f; };
|
||||||
|
struct fuz { struct faz f; };
|
||||||
|
|
||||||
|
extern struct fuz foo(void);
|
||||||
|
|
||||||
|
int X;
|
||||||
|
struct frk F;
|
||||||
|
float _Complex C;
|
||||||
|
|
||||||
|
void bar(void) {
|
||||||
|
X = foo().f.f.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bun(void) {
|
||||||
|
F = foo().f.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ban(void) {
|
||||||
|
C = foo().f.f.c;
|
||||||
|
}
|
Loading…
Reference in New Issue