================
@@ -0,0 +1,212 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to compute the layout of a record.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenBuilder.h"
+#include "CIRGenModule.h"
+#include "CIRGenTypes.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "llvm/Support/Casting.h"
+
+#include <memory>
+
+using namespace llvm;
+using namespace clang;
+using namespace clang::CIRGen;
+
+namespace {
+/// The CIRRecordLowering is responsible for lowering an ASTRecordLayout to an
+/// mlir::Type. Some of the lowering is straightforward, some is not.
+// TODO: Detail some of the complexities and weirdnesses?
+// (See CGRecordLayoutBuilder.cpp)
+struct CIRRecordLowering final {
+
+  // MemberInfo is a helper structure that contains information about a record
+  // member. In addition to the standard member types, there exists a sentinel
+  // member type that ensures correct rounding.
+  struct MemberInfo final {
+    CharUnits offset;
+    enum class InfoKind { Field } kind;
+    mlir::Type data;
+    union {
+      const FieldDecl *fieldDecl;
+      // CXXRecordDecl will be used here when supported.
+    };
+    MemberInfo(CharUnits offset, InfoKind kind, mlir::Type data,
+               const FieldDecl *fieldDecl = nullptr)
+        : offset(offset), kind(kind), data(data), fieldDecl(fieldDecl) {};
+    // MemberInfos are sorted so we define a < operator.
+    bool operator<(const MemberInfo &other) const {
+      return offset < other.offset;
+    }
+  };
+  // The constructor.
+  CIRRecordLowering(CIRGenTypes &cirGenTypes, const RecordDecl *recordDecl,
+                    bool isPacked);
+
+  void lower();
+
+  void accumulateFields();
+
+  CharUnits bitsToCharUnits(uint64_t bitOffset) {
+    return astContext.toCharUnitsFromBits(bitOffset);
+  }
+
+  CharUnits getSize(mlir::Type Ty) {
+    assert(!cir::MissingFeatures::recordTypeLayoutInfo());
+    return CharUnits::One();
+  }
+  CharUnits getAlignment(mlir::Type Ty) {
+    assert(!cir::MissingFeatures::recordTypeLayoutInfo());
+    return CharUnits::One();
+  }
+
+  mlir::Type getStorageType(const FieldDecl *fieldDecl) {
+    mlir::Type type = cirGenTypes.convertTypeForMem(fieldDecl->getType());
+    if (fieldDecl->isBitField()) {
+      cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
+                                         "getStorageType for bitfields");
+    }
+    return type;
+  }
+
+  uint64_t getFieldBitOffset(const FieldDecl *fieldDecl) {
+    return astRecordLayout.getFieldOffset(fieldDecl->getFieldIndex());
+  }
+
+  /// Fills out the structures that are ultimately consumed.
+  void fillOutputFields();
+
+  CIRGenTypes &cirGenTypes;
+  CIRGenBuilderTy &builder;
+  const ASTContext &astContext;
+  const RecordDecl *recordDecl;
+  const ASTRecordLayout &astRecordLayout;
+  // Helpful intermediate data-structures
+  std::vector<MemberInfo> members;
+  // Output fields, consumed by CIRGenTypes::computeRecordLayout
+  llvm::SmallVector<mlir::Type, 16> fieldTypes;
+  llvm::DenseMap<const FieldDecl *, unsigned> fields;
+  bool zeroInitializable : 1;
+  bool packed : 1;
+  bool padded : 1;
+
+private:
+  CIRRecordLowering(const CIRRecordLowering &) = delete;
+  void operator=(const CIRRecordLowering &) = delete;
+}; // CIRRecordLowering
+} // namespace
+
+CIRRecordLowering::CIRRecordLowering(CIRGenTypes &cirGenTypes,
+                                     const RecordDecl *recordDecl,
+                                     bool isPacked)
+    : cirGenTypes(cirGenTypes), builder(cirGenTypes.getBuilder()),
+      astContext(cirGenTypes.getASTContext()), recordDecl(recordDecl),
+      astRecordLayout(
+          cirGenTypes.getASTContext().getASTRecordLayout(recordDecl)),
+      zeroInitializable(true), packed(isPacked), padded(false) {}
+
+void CIRRecordLowering::lower() {
+  if (recordDecl->isUnion()) {
----------------
erichkeane wrote:

Should we also NYI on base types?  Particularly with virtual base types this 
gets ugly.

https://github.com/llvm/llvm-project/pull/135844
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to