aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuilder.h8
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenClass.cpp5
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenDecl.cpp98
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp12
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp58
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h32
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp28
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenStmt.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypeCache.h3
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypes.cpp15
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp14
13 files changed, 217 insertions, 62 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index a6f10e6..84acc74 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -519,6 +519,14 @@ public:
return createGlobal(module, loc, uniqueName, type, isConstant, linkage);
}
+ cir::StackSaveOp createStackSave(mlir::Location loc, mlir::Type ty) {
+ return cir::StackSaveOp::create(*this, loc, ty);
+ }
+
+ cir::StackRestoreOp createStackRestore(mlir::Location loc, mlir::Value v) {
+ return cir::StackRestoreOp::create(*this, loc, v);
+ }
+
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType,
Address dstAddr, mlir::Type storageType,
mlir::Value src, const CIRGenBitFieldInfo &info,
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index dd357ce..89f4926 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -478,8 +478,7 @@ void CIRGenFunction::getVTablePointers(BaseSubobject base,
for (const auto &nextBase : rd->bases()) {
const auto *baseDecl =
- cast<CXXRecordDecl>(
- nextBase.getType()->castAs<RecordType>()->getOriginalDecl())
+ cast<CXXRecordDecl>(nextBase.getType()->castAs<RecordType>()->getDecl())
->getDefinitionOrSelf();
// Ignore classes without a vtable.
@@ -1025,7 +1024,7 @@ void CIRGenFunction::enterDtorCleanups(const CXXDestructorDecl *dd,
// Anonymous union members do not have their destructors called.
const RecordType *rt = type->getAsUnionType();
- if (rt && rt->getOriginalDecl()->isAnonymousStructOrUnion())
+ if (rt && rt->getDecl()->isAnonymousStructOrUnion())
continue;
CleanupKind cleanupKind = getCleanupKind(dtorKind);
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 039d290..4a19d91 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -44,38 +44,70 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
// If the type is variably-modified, emit all the VLA sizes for it.
if (ty->isVariablyModifiedType())
- cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: variably modified type");
+ emitVariablyModifiedType(ty);
assert(!cir::MissingFeatures::openMP());
Address address = Address::invalid();
- if (!ty->isConstantSizeType())
- cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: non-constant size type");
-
- // A normal fixed sized variable becomes an alloca in the entry block,
- // unless:
- // - it's an NRVO variable.
- // - we are compiling OpenMP and it's an OpenMP local variable.
- if (nrvo) {
- // The named return value optimization: allocate this variable in the
- // return slot, so that we can elide the copy when returning this
- // variable (C++0x [class.copy]p34).
- address = returnValue;
-
- if (const RecordDecl *rd = ty->getAsRecordDecl()) {
- if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
- (cxxrd && !cxxrd->hasTrivialDestructor()) ||
- rd->isNonTrivialToPrimitiveDestroy())
- cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag");
+ if (ty->isConstantSizeType()) {
+ // A normal fixed sized variable becomes an alloca in the entry block,
+ // unless:
+ // - it's an NRVO variable.
+ // - we are compiling OpenMP and it's an OpenMP local variable.
+ if (nrvo) {
+ // The named return value optimization: allocate this variable in the
+ // return slot, so that we can elide the copy when returning this
+ // variable (C++0x [class.copy]p34).
+ address = returnValue;
+
+ if (const RecordDecl *rd = ty->getAsRecordDecl()) {
+ if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
+ (cxxrd && !cxxrd->hasTrivialDestructor()) ||
+ rd->isNonTrivialToPrimitiveDestroy())
+ cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag");
+ }
+ } else {
+ // A normal fixed sized variable becomes an alloca in the entry block,
+ mlir::Type allocaTy = convertTypeForMem(ty);
+ // Create the temp alloca and declare variable using it.
+ address = createTempAlloca(allocaTy, alignment, loc, d.getName(),
+ /*arraySize=*/nullptr, /*alloca=*/nullptr, ip);
+ declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()),
+ alignment);
}
} else {
- // A normal fixed sized variable becomes an alloca in the entry block,
- mlir::Type allocaTy = convertTypeForMem(ty);
- // Create the temp alloca and declare variable using it.
- address = createTempAlloca(allocaTy, alignment, loc, d.getName(),
- /*arraySize=*/nullptr, /*alloca=*/nullptr, ip);
- declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()),
- alignment);
+ // Non-constant size type
+ assert(!cir::MissingFeatures::openMP());
+ if (!didCallStackSave) {
+ // Save the stack.
+ cir::PointerType defaultTy = AllocaInt8PtrTy;
+ CharUnits align = CharUnits::fromQuantity(
+ cgm.getDataLayout().getAlignment(defaultTy, false));
+ Address stack = createTempAlloca(defaultTy, align, loc, "saved_stack");
+
+ mlir::Value v = builder.createStackSave(loc, defaultTy);
+ assert(v.getType() == AllocaInt8PtrTy);
+ builder.createStore(loc, v, stack);
+
+ didCallStackSave = true;
+
+ // Push a cleanup block and restore the stack there.
+ // FIXME: in general circumstances, this should be an EH cleanup.
+ pushStackRestore(NormalCleanup, stack);
+ }
+
+ VlaSizePair vlaSize = getVLASize(ty);
+ mlir::Type memTy = convertTypeForMem(vlaSize.type);
+
+ // Allocate memory for the array.
+ address =
+ createTempAlloca(memTy, alignment, loc, d.getName(), vlaSize.numElts,
+ /*alloca=*/nullptr, builder.saveInsertionPoint());
+
+ // If we have debug info enabled, properly describe the VLA dimensions for
+ // this type by registering the vla size expression for each of the
+ // dimensions.
+ assert(!cir::MissingFeatures::generateDebugInfo());
}
emission.addr = address;
@@ -696,6 +728,16 @@ struct DestroyObject final : EHScopeStack::Cleanup {
cgf.emitDestroy(addr, type, destroyer);
}
};
+
+struct CallStackRestore final : EHScopeStack::Cleanup {
+ Address stack;
+ CallStackRestore(Address stack) : stack(stack) {}
+ void emit(CIRGenFunction &cgf) override {
+ mlir::Location loc = stack.getPointer().getLoc();
+ mlir::Value v = cgf.getBuilder().createLoad(loc, stack);
+ cgf.getBuilder().createStackRestore(loc, v);
+ }
+};
} // namespace
void CIRGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
@@ -805,6 +847,10 @@ CIRGenFunction::getDestroyer(QualType::DestructionKind kind) {
llvm_unreachable("Unknown DestructionKind");
}
+void CIRGenFunction::pushStackRestore(CleanupKind kind, Address spMem) {
+ ehStack.pushCleanup<CallStackRestore>(kind, spMem);
+}
+
/// Enter a destroy cleanup for the given local variable.
void CIRGenFunction::emitAutoVarTypeCleanup(
const CIRGenFunction::AutoVarEmission &emission,
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index f416571..4897c29 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2068,7 +2068,7 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
mlir::OpBuilder::InsertionGuard guard(builder);
builder.restoreInsertionPoint(ip);
addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy,
- /*var type*/ ty, name, alignIntAttr);
+ /*var type*/ ty, name, alignIntAttr, arraySize);
assert(!cir::MissingFeatures::astVarDeclInterface());
}
return addr;
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 89e9ec4..81e5fe2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -614,7 +614,7 @@ bool ConstRecordBuilder::applyZeroInitPadding(const ASTRecordLayout &layout,
bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) {
RecordDecl *rd = ile->getType()
->castAs<clang::RecordType>()
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf();
const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd);
@@ -817,9 +817,8 @@ bool ConstRecordBuilder::build(const APValue &val, const RecordDecl *rd,
mlir::Attribute ConstRecordBuilder::finalize(QualType type) {
type = type.getNonReferenceType();
- RecordDecl *rd = type->castAs<clang::RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ RecordDecl *rd =
+ type->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
mlir::Type valTy = cgm.convertType(type);
return builder.build(valTy, rd->hasFlexibleArrayMember());
}
@@ -842,9 +841,8 @@ mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter,
ConstantAggregateBuilder constant(emitter.cgm);
ConstRecordBuilder builder(emitter, constant, CharUnits::Zero());
- const RecordDecl *rd = valTy->castAs<clang::RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ const RecordDecl *rd =
+ valTy->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd);
if (!builder.build(val, rd, false, cd, CharUnits::Zero()))
return nullptr;
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 01a43a99..ba36cbe 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -410,6 +410,8 @@ void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType,
curFn = fn;
const Decl *d = gd.getDecl();
+
+ didCallStackSave = false;
curCodeDecl = d;
const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
curFuncDecl = d->getNonClosureContext();
@@ -1006,6 +1008,41 @@ mlir::Value CIRGenFunction::emitAlignmentAssumption(
offsetValue);
}
+CIRGenFunction::VlaSizePair CIRGenFunction::getVLASize(QualType type) {
+ const VariableArrayType *vla =
+ cgm.getASTContext().getAsVariableArrayType(type);
+ assert(vla && "type was not a variable array type!");
+ return getVLASize(vla);
+}
+
+CIRGenFunction::VlaSizePair
+CIRGenFunction::getVLASize(const VariableArrayType *type) {
+ // The number of elements so far; always size_t.
+ mlir::Value numElements;
+
+ QualType elementType;
+ do {
+ elementType = type->getElementType();
+ mlir::Value vlaSize = vlaSizeMap[type->getSizeExpr()];
+ assert(vlaSize && "no size for VLA!");
+ assert(vlaSize.getType() == SizeTy);
+
+ if (!numElements) {
+ numElements = vlaSize;
+ } else {
+ // It's undefined behavior if this wraps around, so mark it that way.
+ // FIXME: Teach -fsanitize=undefined to trap this.
+
+ numElements =
+ builder.createMul(numElements.getLoc(), numElements, vlaSize,
+ cir::OverflowBehavior::NoUnsignedWrap);
+ }
+ } while ((type = getContext().getAsVariableArrayType(elementType)));
+
+ assert(numElements && "Undefined elements number");
+ return {numElements, elementType};
+}
+
// TODO(cir): Most of this function can be shared between CIRGen
// and traditional LLVM codegen
void CIRGenFunction::emitVariablyModifiedType(QualType type) {
@@ -1086,7 +1123,26 @@ void CIRGenFunction::emitVariablyModifiedType(QualType type) {
break;
case Type::VariableArray: {
- cgm.errorNYI("CIRGenFunction::emitVariablyModifiedType VLA");
+ // Losing element qualification here is fine.
+ const VariableArrayType *vat = cast<clang::VariableArrayType>(ty);
+
+ // Unknown size indication requires no size computation.
+ // Otherwise, evaluate and record it.
+ if (const Expr *sizeExpr = vat->getSizeExpr()) {
+ // It's possible that we might have emitted this already,
+ // e.g. with a typedef and a pointer to it.
+ mlir::Value &entry = vlaSizeMap[sizeExpr];
+ if (!entry) {
+ mlir::Value size = emitScalarExpr(sizeExpr);
+ assert(!cir::MissingFeatures::sanitizers());
+
+ // Always zexting here would be wrong if it weren't
+ // undefined behavior to have a negative bound.
+ // FIXME: What about when size's type is larger than size_t?
+ entry = builder.createIntCast(size, SizeTy);
+ }
+ }
+ type = vat->getElementType();
break;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index d71de2f..0d64c31 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -149,6 +149,10 @@ public:
using SymTableTy = llvm::ScopedHashTable<const clang::Decl *, mlir::Value>;
SymTableTy symbolTable;
+ /// Whether a cir.stacksave operation has been added. Used to avoid
+ /// inserting cir.stacksave for multiple VLAs in the same scope.
+ bool didCallStackSave = false;
+
/// Whether or not a Microsoft-style asm block has been processed within
/// this fuction. These can potentially set the return value.
bool sawAsmBlock = false;
@@ -188,6 +192,14 @@ public:
llvm::DenseMap<const OpaqueValueExpr *, LValue> opaqueLValues;
llvm::DenseMap<const OpaqueValueExpr *, RValue> opaqueRValues;
+ // This keeps track of the associated size for each VLA type.
+ // We track this by the size expression rather than the type itself because
+ // in certain situations, like a const qualifier applied to an VLA typedef,
+ // multiple VLA types can share the same size expression.
+ // FIXME: Maybe this could be a stack of maps that is pushed/popped as we
+ // enter/leave scopes.
+ llvm::DenseMap<const Expr *, mlir::Value> vlaSizeMap;
+
public:
/// A non-RAII class containing all the information about a bound
/// opaque value. OpaqueValueMapping, below, is a RAII wrapper for
@@ -436,6 +448,20 @@ public:
}
};
+ struct VlaSizePair {
+ mlir::Value numElts;
+ QualType type;
+
+ VlaSizePair(mlir::Value num, QualType ty) : numElts(num), type(ty) {}
+ };
+
+ /// Returns an MLIR::Value+QualType pair that corresponds to the size,
+ /// in non-variably-sized elements, of a variable length array type,
+ /// plus that largest non-variably-sized element type. Assumes that
+ /// the type has already been emitted with emitVariablyModifiedType.
+ VlaSizePair getVLASize(const VariableArrayType *type);
+ VlaSizePair getVLASize(QualType type);
+
void finishFunction(SourceLocation endLoc);
/// Determine whether the given initializer is trivial in the sense
@@ -583,6 +609,8 @@ public:
return needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup;
}
+ void pushStackRestore(CleanupKind kind, Address spMem);
+
/// Set the address of a local variable.
void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr) {
assert(!localDeclMap.count(vd) && "Decl already exists in LocalDeclMap!");
@@ -854,6 +882,7 @@ public:
protected:
bool performCleanup;
+ bool oldDidCallStackSave;
private:
RunCleanupsScope(const RunCleanupsScope &) = delete;
@@ -867,6 +896,8 @@ public:
explicit RunCleanupsScope(CIRGenFunction &cgf)
: performCleanup(true), cgf(cgf) {
cleanupStackDepth = cgf.ehStack.stable_begin();
+ oldDidCallStackSave = cgf.didCallStackSave;
+ cgf.didCallStackSave = false;
oldCleanupStackDepth = cgf.currentCleanupStackDepth;
cgf.currentCleanupStackDepth = cleanupStackDepth;
}
@@ -883,6 +914,7 @@ public:
assert(performCleanup && "Already forced cleanup");
{
mlir::OpBuilder::InsertionGuard guard(cgf.getBuilder());
+ cgf.didCallStackSave = oldDidCallStackSave;
cgf.popCleanupBlocks(cleanupStackDepth);
performCleanup = false;
cgf.currentCleanupStackDepth = oldCleanupStackDepth;
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index d30c975..1b85a53 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -744,8 +744,8 @@ static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
return false;
if (const auto *recordTy = dyn_cast<RecordType>(ty)) {
- const CXXRecordDecl *rd =
- cast<CXXRecordDecl>(recordTy->getOriginalDecl())->getDefinitionOrSelf();
+ const auto *rd =
+ cast<CXXRecordDecl>(recordTy->getDecl())->getDefinitionOrSelf();
if (!rd->hasDefinition())
return false;
@@ -859,9 +859,7 @@ static bool canUseSingleInheritance(const CXXRecordDecl *rd) {
/// IsIncompleteClassType - Returns whether the given record type is incomplete.
static bool isIncompleteClassType(const RecordType *recordTy) {
- return !recordTy->getOriginalDecl()
- ->getDefinitionOrSelf()
- ->isCompleteDefinition();
+ return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
}
/// Returns whether the given type contains an
@@ -939,8 +937,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
case Type::Atomic:
// FIXME: GCC treats block pointers as fundamental types?!
case Type::BlockPointer:
- cgm.errorNYI("VTableClassNameForType: __fundamental_type_info");
- break;
+ return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
@@ -957,9 +954,8 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
break;
case Type::Record: {
- const CXXRecordDecl *rd =
- cast<CXXRecordDecl>(cast<RecordType>(ty)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *rd = cast<CXXRecordDecl>(cast<RecordType>(ty)->getDecl())
+ ->getDefinitionOrSelf();
if (!rd->hasDefinition() || !rd->getNumBases()) {
return classTypeInfo;
@@ -1031,8 +1027,8 @@ static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm,
return cir::GlobalLinkageKind::LinkOnceODRLinkage;
if (const RecordType *record = dyn_cast<RecordType>(ty)) {
- const CXXRecordDecl *rd =
- cast<CXXRecordDecl>(record->getOriginalDecl())->getDefinitionOrSelf();
+ const auto *rd =
+ cast<CXXRecordDecl>(record->getDecl())->getDefinitionOrSelf();
if (rd->hasAttr<WeakAttr>())
return cir::GlobalLinkageKind::WeakODRLinkage;
@@ -1382,9 +1378,8 @@ mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
break;
case Type::Record: {
- const auto *rd =
- cast<CXXRecordDecl>(cast<RecordType>(ty)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *rd = cast<CXXRecordDecl>(cast<RecordType>(ty)->getDecl())
+ ->getDefinitionOrSelf();
if (!rd->hasDefinition() || !rd->getNumBases()) {
// We don't need to emit any fields.
break;
@@ -1651,8 +1646,7 @@ void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
// Lowering pass to skip passing the trivial function.
//
if (const RecordType *recordTy = clangThrowType->getAs<RecordType>()) {
- CXXRecordDecl *rec =
- cast<CXXRecordDecl>(recordTy->getOriginalDecl()->getDefinition());
+ auto *rec = cast<CXXRecordDecl>(recordTy->getDecl()->getDefinition());
assert(!cir::MissingFeatures::isTrivialCtorOrDtor());
if (!rec->hasTrivialDestructor()) {
cgm.errorNYI("emitThrow: non-trivial destructor");
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 82b1051..57c7a44 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -88,6 +88,8 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
FP80Ty = cir::FP80Type::get(&getMLIRContext());
FP128Ty = cir::FP128Type::get(&getMLIRContext());
+ AllocaInt8PtrTy = cir::PointerType::get(UInt8Ty, cirAllocaAddressSpace);
+
PointerAlignInBytes =
astContext
.toCharUnitsFromBits(
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index cfd48a2..5ba64dd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -536,7 +536,7 @@ mlir::LogicalResult CIRGenFunction::emitLabel(const clang::LabelDecl &d) {
mlir::Block *currBlock = builder.getBlock();
mlir::Block *labelBlock = currBlock;
- if (!currBlock->empty()) {
+ if (!currBlock->empty() || currBlock->isEntryBlock()) {
{
mlir::OpBuilder::InsertionGuard guard(builder);
labelBlock = builder.createBlock(builder.getBlock()->getParent());
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
index 273ec7f..b5612d9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
@@ -65,6 +65,9 @@ struct CIRGenTypeCache {
cir::PointerType VoidPtrTy;
cir::PointerType UInt8PtrTy;
+ /// void* in alloca address space
+ cir::PointerType AllocaInt8PtrTy;
+
/// The size and alignment of a pointer into the generic address space.
union {
unsigned char PointerAlignInBytes;
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 2ab1ea0c..d1b91d0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -159,7 +159,7 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt,
for (const clang::CXXBaseSpecifier &i : crd->bases())
if (!isSafeToConvert(i.getType()
->castAs<RecordType>()
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf(),
cgt, alreadyChecked))
return false;
@@ -279,8 +279,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
// Process record types before the type cache lookup.
if (const auto *recordType = dyn_cast<RecordType>(type))
- return convertRecordDeclType(
- recordType->getOriginalDecl()->getDefinitionOrSelf());
+ return convertRecordDeclType(recordType->getDecl()->getDefinitionOrSelf());
// Has the type already been processed?
TypeCacheTy::iterator tci = typeCache.find(ty);
@@ -421,6 +420,16 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
break;
}
+ case Type::VariableArray: {
+ const VariableArrayType *a = cast<VariableArrayType>(ty);
+ if (a->getIndexTypeCVRQualifiers() != 0)
+ cgm.errorNYI(SourceLocation(), "non trivial array types", type);
+ // VLAs resolve to the innermost element type; this matches
+ // the return of alloca, and there isn't any obviously better choice.
+ resultType = convertTypeForMem(a->getElementType());
+ break;
+ }
+
case Type::IncompleteArray: {
const IncompleteArrayType *arrTy = cast<IncompleteArrayType>(ty);
if (arrTy->getIndexTypeCVRQualifiers() != 0)
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 3abba3d..e61b65f 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1793,12 +1793,20 @@ CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op,
if (!comdatOp) {
builder.setInsertionPointToStart(module.getBody());
comdatOp =
- builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
+ mlir::LLVM::ComdatOp::create(builder, module.getLoc(), comdatName);
+ }
+
+ if (auto comdatSelector = comdatOp.lookupSymbol<mlir::LLVM::ComdatSelectorOp>(
+ op.getSymName())) {
+ return mlir::SymbolRefAttr::get(
+ builder.getContext(), comdatName,
+ mlir::FlatSymbolRefAttr::get(comdatSelector.getSymNameAttr()));
}
builder.setInsertionPointToStart(&comdatOp.getBody().back());
- auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>(
- comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
+ auto selectorOp = mlir::LLVM::ComdatSelectorOp::create(
+ builder, comdatOp.getLoc(), op.getSymName(),
+ mlir::LLVM::comdat::Comdat::Any);
return mlir::SymbolRefAttr::get(
builder.getContext(), comdatName,
mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));