]> granicus.if.org Git - clang/commitdiff
Implement codegen of aggregates as lvalues in binary expressions,
authorDaniel Dunbar <daniel@zuster.org>
Thu, 4 Sep 2008 03:20:13 +0000 (03:20 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 4 Sep 2008 03:20:13 +0000 (03:20 +0000)
e.g. "(a = b).somefield".

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55758 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/struct.c

index e1893493b0695368f99e4d9bf4028e284269b73c..cc5e705c39224cb6dd9fd4ab55798873d8b8fcbf 100644 (file)
@@ -99,6 +99,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
   switch (E->getStmtClass()) {
   default: return EmitUnsupportedLValue(E, "l-value expression");
 
+  case Expr::BinaryOperatorClass: 
+    return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
   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());
@@ -738,7 +740,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
           dyn_cast<const FunctionDecl>(DRExpr->getDecl()))
         if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
           return EmitBuiltinExpr(builtinID, E);
-        
+
   llvm::Value *Callee = EmitScalarExpr(E->getCallee());
   return EmitCallExpr(Callee, E->getCallee()->getType(),
                       E->arg_begin(), E->arg_end());
@@ -752,6 +754,18 @@ RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr,
   return EmitCallExpr(Callee, FnExpr->getType(), ArgBeg, ArgEnd);
 }
 
+LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
+  // Can only get l-value for binary operator expressions which are a
+  // simple assignment of aggregate type.
+  if (E->getOpcode() != BinaryOperator::Assign)
+    return EmitUnsupportedLValue(E, "binary l-value expression");
+
+  llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
+  EmitAggExpr(E, Temp, false);
+  // FIXME: Are these qualifiers correct?
+  return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers());
+}
+
 LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
   // Can only get l-value for call expression returning aggregate type
   RValue RV = EmitCallExpr(E);
index e43b2d39614f993ead8ffdbeea72d41abd33ae9c..853f44538412bc0fae4500eab7c92c93013aa5f2 100644 (file)
@@ -281,6 +281,8 @@ public:
   void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty);
   void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst, QualType Ty);
    
+  // Note: only availabe for agg return types
+  LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
   // Note: only availabe for agg return types
   LValue EmitCallExprLValue(const CallExpr *E);
   
index 9af684b1140eec399cb2da221a440a1ede5764ab..76d9b772742e278d9ad7550e9e94a54037d0ddc1 100644 (file)
@@ -69,7 +69,6 @@ typedef struct {
   int location;
   int length;
 } range;
-
 extern range f6();
 void f7()
 {
@@ -166,3 +165,27 @@ struct __attribute__((packed)) S2839 { double a[19];  signed char b; } s2839[5];
 
 struct __attribute__((packed)) SS { long double a; char b; } SS;
 
+
+/* As lvalue */
+
+int f15() {
+  extern range f15_ext();
+  return f15_ext().location;
+}
+
+range f16() {
+  extern rangepair f16_ext();
+  return f16_ext().range1;
+}
+
+int f17() {
+  extern range f17_ext();
+  range r;
+  return (r = f17_ext()).location;
+}
+
+range f18() {
+  extern rangepair f18_ext();
+  rangepair rp;
+  return (rp = f18_ext()).range1;
+}