diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 51 |
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(); |