summaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenBuilder.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuilder.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
index 755c76c89a64..670a431e47f4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
@@ -7,6 +7,9 @@
//===----------------------------------------------------------------------===//
#include "CIRGenBuilder.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "clang/CIR/MissingFeatures.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/TypeSwitch.h"
using namespace clang::CIRGen;
@@ -130,6 +133,39 @@ void CIRGenBuilderTy::computeGlobalViewIndicesFromFlatOffset(
computeGlobalViewIndicesFromFlatOffset(offset, subType, layout, indices);
}
+cir::RecordType clang::CIRGen::CIRGenBuilderTy::getCompleteRecordType(
+ mlir::ArrayAttr fields, bool packed, bool padded, llvm::StringRef name) {
+ assert(!cir::MissingFeatures::astRecordDeclAttr());
+ llvm::SmallVector<mlir::Type> members;
+ members.reserve(fields.size());
+ llvm::transform(fields, std::back_inserter(members),
+ [](mlir::Attribute attr) {
+ return mlir::cast<mlir::TypedAttr>(attr).getType();
+ });
+
+ if (name.empty())
+ return getAnonRecordTy(members, packed, padded);
+
+ return getCompleteNamedRecordType(members, packed, padded, name);
+}
+
+mlir::Attribute clang::CIRGen::CIRGenBuilderTy::getConstRecordOrZeroAttr(
+ mlir::ArrayAttr arrayAttr, bool packed, bool padded, mlir::Type type) {
+ auto recordTy = mlir::cast_or_null<cir::RecordType>(type);
+
+ // Record type not specified: create anon record type from members.
+ if (!recordTy) {
+ recordTy = getCompleteRecordType(arrayAttr, packed, padded);
+ }
+
+ // Return zero or anonymous constant record.
+ const bool isZero = llvm::all_of(
+ arrayAttr, [&](mlir::Attribute a) { return isNullValue(a); });
+ if (isZero)
+ return cir::ZeroAttr::get(recordTy);
+ return cir::ConstRecordAttr::get(recordTy, arrayAttr);
+}
+
// This can't be defined in Address.h because that file is included by
// CIRGenBuilder.h
Address Address::withElementType(CIRGenBuilderTy &builder,