diff options
| author | Christopher Lamb <christopher.lamb@gmail.com> | 2007-12-29 05:02:41 +0000 | 
|---|---|---|
| committer | Christopher Lamb <christopher.lamb@gmail.com> | 2007-12-29 05:02:41 +0000 | 
| commit | d91c3d49266b031eca7085623c344c70b76d3538 (patch) | |
| tree | 43c6c7b36177138405d7217e84cb7cbb7369054a | |
| parent | fd9af54ad1a8426732dffc5a9d1fc2bbdbb68f3a (diff) | |
| download | bcm5719-llvm-d91c3d49266b031eca7085623c344c70b76d3538.tar.gz bcm5719-llvm-d91c3d49266b031eca7085623c344c70b76d3538.zip  | |
Enable CodeGen for member expressions based on call expressions returning aggregate types. This enables expressions like 'foo().member.submember'.
llvm-svn: 45395
| -rw-r--r-- | clang/CodeGen/CGExpr.cpp | 7 | ||||
| -rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 3 | ||||
| -rw-r--r-- | clang/test/CodeGen/func-return-member.c | 23 | 
3 files changed, 33 insertions, 0 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 4cb897fe5d1..84879bb28e9 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -87,6 +87,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {      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::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());    case Expr::PreDefinedExprClass: @@ -455,6 +456,12 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *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) {    // The callee type will always be a pointer to function type, get the function    // type. diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index 3b51d43de98..40c7414b982 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -371,6 +371,9 @@ public:    /// is 'Ty'.    void EmitStoreThroughLValue(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 EmitStringLiteralLValue(const StringLiteral *E); diff --git a/clang/test/CodeGen/func-return-member.c b/clang/test/CodeGen/func-return-member.c new file mode 100644 index 00000000000..f31a53afcee --- /dev/null +++ b/clang/test/CodeGen/func-return-member.c @@ -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; +}  | 

