diff options
author | Andy Kaylor <akaylor@nvidia.com> | 2025-04-08 10:32:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-08 10:32:03 -0700 |
commit | 4928093a21cea9bd76d1e47455e990874ad352df (patch) | |
tree | 84552dc868642a1b67ff52927ce8b3964cd75d05 /clang/lib/CIR/CodeGen/CIRGenModule.cpp | |
parent | 9bfb4b8fb194c1df5b082888abc03d095e39b6e9 (diff) | |
download | llvm-4928093a21cea9bd76d1e47455e990874ad352df.zip llvm-4928093a21cea9bd76d1e47455e990874ad352df.tar.gz llvm-4928093a21cea9bd76d1e47455e990874ad352df.tar.bz2 |
[CIR] Upstream support for address of and dereference (#134317)
This adds support for handling the address of and dereference unary
operations in ClangIR code generation. This also adds handling for
nullptr and proper initialization via the NullToPointer cast.
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(); |