Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,8 @@ def CIR_RecordType : CIR_Type<"Record", "record", [
uint64_t getElementOffset(const mlir::DataLayout &dataLayout,
unsigned idx) const;

bool isLayoutIdentical(const RecordType &other);

private:
unsigned computeStructSize(const mlir::DataLayout &dataLayout) const;
uint64_t computeStructAlignment(const mlir::DataLayout &dataLayout) const;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct MissingFeatures {
static bool astRecordDeclAttr() { return false; }
static bool cxxSupport() { return false; }
static bool recordZeroInit() { return false; }
static bool recordZeroInitPadding() { return false; }
static bool zeroSizeRecordMembers() { return false; }
static bool recordLayoutVirtualBases() { return false; }

Expand Down
36 changes: 36 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
25 changes: 21 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
#include "Address.h"
#include "CIRGenRecordLayout.h"
#include "CIRGenTypeCache.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/Support/LLVM.h"
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
#include "clang/CIR/Interfaces/CIRTypeInterfaces.h"
#include "clang/CIR/MissingFeatures.h"

#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
Expand Down Expand Up @@ -60,6 +62,16 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
trailingZerosNum);
}

cir::ConstArrayAttr getConstArray(mlir::Attribute attrs,
cir::ArrayType arrayTy) const {
return cir::ConstArrayAttr::get(arrayTy, attrs);
}

mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr,
bool packed = false,
bool padded = false,
mlir::Type type = {});

cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr,
bool packed = false,
bool padded = false,
Expand Down Expand Up @@ -126,9 +138,9 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
///
/// If a record already exists and is complete, but the client tries to fetch
/// it with a different set of attributes, this method will crash.
cir::RecordType getCompleteRecordTy(llvm::ArrayRef<mlir::Type> members,
llvm::StringRef name, bool packed,
bool padded) {
cir::RecordType getCompleteNamedRecordType(llvm::ArrayRef<mlir::Type> members,
bool packed, bool padded,
llvm::StringRef name) {
const auto nameAttr = getStringAttr(name);
auto kind = cir::RecordType::RecordKind::Struct;
assert(!cir::MissingFeatures::astRecordDeclAttr());
Expand All @@ -150,6 +162,11 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return type;
}

cir::RecordType getCompleteRecordType(mlir::ArrayAttr fields,
bool packed = false,
bool padded = false,
llvm::StringRef name = "");

/// Get an incomplete CIR struct type. If we have a complete record
/// declaration, we may create an incomplete type and then add the
/// members, so \p rd here may be complete.
Expand Down
12 changes: 11 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ class ConstantEmitter {
// side effects, or emitting an initialization that requires a
// reference to its current location.
mlir::Attribute emitForMemory(mlir::Attribute c, QualType destType);
static mlir::Attribute emitForMemory(CIRGenModule &cgm, mlir::Attribute c,
clang::QualType destTy);

mlir::Attribute emitNullForMemory(mlir::Location loc, QualType t) {
return emitNullForMemory(loc, cgm, t);
}
static mlir::Attribute emitNullForMemory(mlir::Location loc,
CIRGenModule &cgm, QualType t);

/// Try to emit the initializer of the given declaration as an abstract
/// constant.
Expand All @@ -104,7 +112,9 @@ class ConstantEmitter {

mlir::TypedAttr tryEmitPrivate(const Expr *e, QualType destType);
mlir::Attribute tryEmitPrivate(const APValue &value, QualType destType);
mlir::Attribute tryEmitPrivateForMemory(const APValue &value, QualType t);
mlir::Attribute tryEmitPrivateForMemory(const Expr *e, QualType destTy);
mlir::Attribute tryEmitPrivateForMemory(const APValue &value,
QualType destTy);

private:
#ifndef NDEBUG
Expand Down
Loading