aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index f0e9b03..78d995b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -74,6 +74,57 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
builder.getStringAttr(getTriple().str()));
}
+CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t) {
+ assert(!cir::MissingFeatures::opTBAA());
+
+ // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But
+ // that doesn't return the information we need to compute BaseInfo.
+
+ // Honor alignment typedef attributes even on incomplete types.
+ // We also honor them straight for C++ class types, even as pointees;
+ // there's an expressivity gap here.
+ if (const auto *tt = t->getAs<TypedefType>()) {
+ if (unsigned align = tt->getDecl()->getMaxAlignment()) {
+ assert(!cir::MissingFeatures::lvalueBaseInfo());
+ return astContext.toCharUnitsFromBits(align);
+ }
+ }
+
+ // Analyze the base element type, so we don't get confused by incomplete
+ // array types.
+ t = astContext.getBaseElementType(t);
+
+ if (t->isIncompleteType()) {
+ // We could try to replicate the logic from
+ // ASTContext::getTypeAlignIfKnown, but nothing uses the alignment if the
+ // type is incomplete, so it's impossible to test. We could try to reuse
+ // getTypeAlignIfKnown, but that doesn't return the information we need
+ // to set BaseInfo. So just ignore the possibility that the alignment is
+ // greater than one.
+ assert(!cir::MissingFeatures::lvalueBaseInfo());
+ return CharUnits::One();
+ }
+
+ assert(!cir::MissingFeatures::lvalueBaseInfo());
+
+ CharUnits alignment;
+ if (t.getQualifiers().hasUnaligned()) {
+ alignment = CharUnits::One();
+ } else {
+ assert(!cir::MissingFeatures::alignCXXRecordDecl());
+ alignment = astContext.getTypeAlignInChars(t);
+ }
+
+ // Cap to the global maximum type alignment unless the alignment
+ // was somehow explicit on the type.
+ if (unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
+ if (alignment.getQuantity() > maxAlign &&
+ !astContext.isAlignmentRequired(t))
+ alignment = CharUnits::fromQuantity(maxAlign);
+ }
+ return alignment;
+}
+
mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
assert(cLoc.isValid() && "expected valid source location");
const SourceManager &sm = astContext.getSourceManager();