From 0fbf0a918a1a461ee95519de78b14358c273bf56 Mon Sep 17 00:00:00 2001
From: gitoleg <forown@yandex.ru>
Date: Mon, 25 Sep 2023 14:05:43 +0300
Subject: [PATCH] [CIR][Codegen][Bugfix] use record layout to generate index
 for a field

---
 clang/lib/CIR/CodeGen/CIRGenClass.cpp      |  3 +--
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp       |  6 ++++--
 clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp    |  6 ++----
 clang/lib/CIR/CodeGen/CIRGenFunction.h     |  3 +--
 clang/test/CIR/CodeGen/derived-to-base.cpp | 13 +++++++++++++
 5 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index d5d7e85c603b..b28e6f0efcae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -206,8 +206,7 @@ static void buildLValueForAnyFieldInitialization(CIRGenFunction &CGF,
   if (MemberInit->isIndirectMemberInitializer()) {
     llvm_unreachable("NYI");
   } else {
-    LHS = CGF.buildLValueForFieldInitialization(LHS, Field, Field->getName(),
-                                                Field->getFieldIndex());
+    LHS = CGF.buildLValueForFieldInitialization(LHS, Field, Field->getName());
   }
 }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 9760fc7d9063..c35aae0d852a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -318,13 +318,15 @@ LValue CIRGenFunction::buildLValueForField(LValue base,
 }
 
 LValue CIRGenFunction::buildLValueForFieldInitialization(
-    LValue Base, const clang::FieldDecl *Field, llvm::StringRef FieldName,
-    unsigned FieldIndex) {
+    LValue Base, const clang::FieldDecl *Field, llvm::StringRef FieldName) {
   QualType FieldType = Field->getType();
 
   if (!FieldType->isReferenceType())
     return buildLValueForField(Base, Field);
 
+  auto& layout = CGM.getTypes().getCIRGenRecordLayout(Field->getParent());
+  unsigned FieldIndex = layout.getCIRFieldNo(Field);
+  
   Address V = buildAddrOfFieldStorage(*this, Base.getAddress(), Field,
                                       FieldName, FieldIndex);
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
index f44d5281cf76..761537534409 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
@@ -9,7 +9,6 @@
 // This contains code to emit Aggregate Expr nodes as CIR code.
 //
 //===----------------------------------------------------------------------===//
-
 #include "CIRGenCall.h"
 #include "CIRGenFunction.h"
 #include "CIRGenModule.h"
@@ -551,7 +550,7 @@ void AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
 
     // Emit initialization
     LValue LV = CGF.buildLValueForFieldInitialization(
-        SlotLV, *CurField, fieldName, CurField->getFieldIndex());
+        SlotLV, *CurField, fieldName);
     if (CurField->hasCapturedVLAType()) {
       llvm_unreachable("NYI");
     }
@@ -816,9 +815,8 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
     if (curInitIndex == NumInitElements && Dest.isZeroed() &&
         CGF.getTypes().isZeroInitializable(ExprToVisit->getType()))
       break;
-
     LValue LV = CGF.buildLValueForFieldInitialization(
-        DestLV, field, field->getName(), field->getFieldIndex());
+        DestLV, field, field->getName());
     // We never generate write-barries for initialized fields.
     assert(!UnimplementedFeature::setNonGC());
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 819a99f81ec7..d49b71abd148 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1520,8 +1520,7 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// stored in the reference.
   LValue buildLValueForFieldInitialization(LValue Base,
                                            const clang::FieldDecl *Field,
-                                           llvm::StringRef FieldName,
-                                           unsigned FieldIndex);
+                                           llvm::StringRef FieldName);
 
   void buildInitializerForField(clang::FieldDecl *Field, LValue LHS,
                                 clang::Expr *Init);
diff --git a/clang/test/CIR/CodeGen/derived-to-base.cpp b/clang/test/CIR/CodeGen/derived-to-base.cpp
index 42a4279e4cff..ee282693a224 100644
--- a/clang/test/CIR/CodeGen/derived-to-base.cpp
+++ b/clang/test/CIR/CodeGen/derived-to-base.cpp
@@ -156,3 +156,16 @@ void t() {
   B b;
   b.foo();
 }
+
+struct C : public A {
+  int& ref;
+  C(int& x) : ref(x) {}
+};
+
+// CHECK: cir.func @_Z8test_refv()
+// CHECK: cir.get_member %2[1] {name = "ref"} 
+int test_ref() {
+  int x = 42;
+  C c(x);
+  return c.ref;
+}
\ No newline at end of file