[clang] [CIR] Make ClangIR compatible with latest nested name specifier AST representation (PR #152846)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 9 03:01:38 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Amr Hesham (AmrDeveloper)
<details>
<summary>Changes</summary>
After AST representation, new modifications landed in (https://github.com/llvm/llvm-project/pull/147835). ClangIR requires some changes in how we use Clang AST to be compatible with the new changes
---
Full diff: https://github.com/llvm/llvm-project/pull/152846.diff
11 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp (+2-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+7-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenClass.cpp (+5-5)
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+4-3)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+1-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+3-6)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+1-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+2-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+17-13)
- (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+5-5)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp
index 67d8988a5fbbd..bc30c7bd130af 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp
@@ -75,7 +75,7 @@ static MemberCallInfo commonBuildCXXMemberOrOperatorCall(
RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
const CallExpr *ce, const CXXMethodDecl *md, ReturnValueSlot returnValue,
- bool hasQualifier, NestedNameSpecifier *qualifier, bool isArrow,
+ bool hasQualifier, NestedNameSpecifier qualifier, bool isArrow,
const Expr *base) {
assert(isa<CXXMemberCallExpr>(ce) || isa<CXXOperatorCallExpr>(ce));
@@ -169,7 +169,7 @@ CIRGenFunction::emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e,
assert(md->isInstance() &&
"Trying to emit a member call expr on a static method!");
return emitCXXMemberOrOperatorMemberCallExpr(
- e, md, returnValue, /*HasQualifier=*/false, /*Qualifier=*/nullptr,
+ e, md, returnValue, /*HasQualifier=*/false, /*Qualifier=*/std::nullopt,
/*IsArrow=*/false, e->getArg(0));
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index fc208fffe216f..8fac6fd6c6aca 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -205,7 +205,7 @@ CanQualType CIRGenTypes::deriveThisType(const CXXRecordDecl *rd,
const CXXMethodDecl *md) {
QualType recTy;
if (rd) {
- recTy = getASTContext().getTagDeclType(rd)->getCanonicalTypeInternal();
+ recTy = getASTContext().getCanonicalTagType(rd);
} else {
// This can happen with the MS ABI. It shouldn't need anything more than
// setting recTy to VoidTy here, but we're flagging it for now because we
@@ -267,7 +267,9 @@ void CIRGenFunction::emitDelegateCallArg(CallArgList &args,
// Deactivate the cleanup for the callee-destructed param that was pushed.
assert(!cir::MissingFeatures::thunks());
if (type->isRecordType() &&
- type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee() &&
+ type->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->isParamDestroyedInCallee() &&
param->needsDestruction(getContext())) {
cgm.errorNYI(param->getSourceRange(),
"emitDelegateCallArg: callee-destructed param");
@@ -667,8 +669,9 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
// In the Microsoft C++ ABI, aggregate arguments are destructed by the callee.
// However, we still have to push an EH-only cleanup in case we unwind before
// we make it to the call.
- if (argType->isRecordType() &&
- argType->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
+ if (argType->isRecordType() && argType->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->isParamDestroyedInCallee()) {
assert(!cir::MissingFeatures::msabi());
cgm.errorNYI(e->getSourceRange(), "emitCallArg: msabi is NYI");
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 72b9d177e4c63..27e798f2280b3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -86,7 +86,7 @@ static void emitMemberInitializer(CIRGenFunction &cgf,
QualType fieldType = field->getType();
mlir::Value thisPtr = cgf.loadCXXThis();
- QualType recordTy = cgf.getContext().getTypeDeclType(classDecl);
+ QualType recordTy = cgf.getContext().getCanonicalTypeDeclType(classDecl);
// If a base constructor is being emitted, create an LValue that has the
// non-virtual alignment.
@@ -121,7 +121,7 @@ static void emitMemberInitializer(CIRGenFunction &cgf,
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit) {
const Type *baseType = baseInit->getBaseClass();
const auto *baseClassDecl =
- cast<CXXRecordDecl>(baseType->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(baseType->castAs<RecordType>()->getOriginalDecl());
return baseClassDecl->isDynamicClass();
}
@@ -161,7 +161,7 @@ void CIRGenFunction::emitBaseInitializer(mlir::Location loc,
const Type *baseType = baseInit->getBaseClass();
const auto *baseClassDecl =
- cast<CXXRecordDecl>(baseType->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(baseType->castAs<RecordType>()->getOriginalDecl());
bool isBaseVirtual = baseInit->isBaseVirtual();
@@ -377,7 +377,7 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
//
// Note that these are complete objects and so we don't need to
// use the non-virtual size or alignment.
- QualType type = getContext().getTypeDeclType(ctor->getParent());
+ QualType type = getContext().getCanonicalTypeDeclType(ctor->getParent());
CharUnits eltAlignment = arrayBase.getAlignment().alignmentOfArrayElement(
getContext().getTypeSizeInChars(type));
@@ -484,7 +484,7 @@ void CIRGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &args) {
void CIRGenFunction::destroyCXXObject(CIRGenFunction &cgf, Address addr,
QualType type) {
const RecordType *rtype = type->castAs<RecordType>();
- const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl());
+ const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getOriginalDecl());
const CXXDestructorDecl *dtor = record->getDestructor();
// TODO(cir): Unlike traditional codegen, CIRGen should actually emit trivial
// dtors which shall be removed on later CIR passes. However, only remove this
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index a0ff08ea3de3a..6114f4ff75d01 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1013,7 +1013,8 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {
case CK_DerivedToBase: {
const auto *derivedClassTy =
e->getSubExpr()->getType()->castAs<clang::RecordType>();
- auto *derivedClassDecl = cast<CXXRecordDecl>(derivedClassTy->getDecl());
+ auto *derivedClassDecl =
+ cast<CXXRecordDecl>(derivedClassTy->getOriginalDecl());
LValue lv = emitLValue(e->getSubExpr());
Address thisAddr = lv.getAddress();
@@ -1167,7 +1168,7 @@ static void pushTemporaryCleanup(CIRGenFunction &cgf,
->getBaseElementTypeUnsafe()
->getAs<clang::RecordType>()) {
// Get the destructor for the reference temporary.
- auto *classDecl = cast<CXXRecordDecl>(rt->getDecl());
+ auto *classDecl = cast<CXXRecordDecl>(rt->getOriginalDecl());
if (!classDecl->hasTrivialDestructor())
referenceTemporaryDtor = classDecl->getDestructor();
}
@@ -1831,7 +1832,7 @@ RValue CIRGenFunction::emitCXXMemberCallExpr(const CXXMemberCallExpr *ce,
}
bool hasQualifier = me->hasQualifier();
- NestedNameSpecifier *qualifier = hasQualifier ? me->getQualifier() : nullptr;
+ NestedNameSpecifier qualifier = me->getQualifier();
bool isArrow = me->isArrow();
const Expr *base = me->getBase();
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 51aab95e02e66..e2c4e13ab6773 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -376,7 +376,7 @@ void AggExprEmitter::visitCXXParenListOrInitListExpr(
// the disadvantage is that the generated code is more difficult for
// the optimizer, especially with bitfields.
unsigned numInitElements = args.size();
- RecordDecl *record = e->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *record = e->getType()->castAs<RecordType>()->getOriginalDecl();
// We'll need to enter cleanup scopes in case any of the element
// initializers throws an exception.
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 5b3bf85cefbb0..3d46af91773ea 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -591,7 +591,7 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) {
// be a problem for the near future.
if (cd->isTrivial() && cd->isDefaultConstructor()) {
const auto *cxxrd =
- cast<CXXRecordDecl>(ty->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(ty->getAs<RecordType>()->getOriginalDecl());
if (cxxrd->getNumBases() != 0) {
// There may not be anything additional to do here, but this will
// force us to pause and test this path when it is supported.
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index dedd01ce5e685..a4d4d210cf876 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -356,7 +356,8 @@ static bool mayDropFunctionReturn(const ASTContext &astContext,
// destructor or a non-trivially copyable type.
if (const RecordType *recordType =
returnType.getCanonicalType()->getAs<RecordType>()) {
- if (const auto *classDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl()))
+ if (const auto *classDecl =
+ dyn_cast<CXXRecordDecl>(recordType->getOriginalDecl()))
return classDecl->hasTrivialDestructor();
}
return returnType.isTriviallyCopyableType(astContext);
@@ -827,7 +828,7 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
// Ignore empty classes in C++.
if (getLangOpts().CPlusPlus) {
if (const RecordType *rt = ty->getAs<RecordType>()) {
- if (cast<CXXRecordDecl>(rt->getDecl())->isEmpty())
+ if (cast<CXXRecordDecl>(rt->getOriginalDecl())->isEmpty())
return;
}
}
@@ -978,10 +979,6 @@ void CIRGenFunction::emitVariablyModifiedType(QualType type) {
case Type::BitInt:
llvm_unreachable("type class is never variably-modified!");
- case Type::Elaborated:
- type = cast<clang::ElaboratedType>(ty)->getNamedType();
- break;
-
case Type::Adjusted:
type = cast<clang::AdjustedType>(ty)->getAdjustedType();
break;
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index bdbc77c0a7c4a..68447082a5a1f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1011,7 +1011,7 @@ class CIRGenFunction : public CIRGenTypeCache {
RValue emitCXXMemberOrOperatorMemberCallExpr(
const clang::CallExpr *ce, const clang::CXXMethodDecl *md,
ReturnValueSlot returnValue, bool hasQualifier,
- clang::NestedNameSpecifier *qualifier, bool isArrow,
+ clang::NestedNameSpecifier qualifier, bool isArrow,
const clang::Expr *base);
mlir::Value emitCXXNewExpr(const CXXNewExpr *e);
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index ff6d293aae229..d6b0278ab0b6f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -997,7 +997,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &astContext,
return true;
if (const auto *rt = varType->getAs<RecordType>()) {
- const RecordDecl *rd = rt->getDecl();
+ const RecordDecl *rd = rt->getOriginalDecl();
for (const FieldDecl *fd : rd->fields()) {
if (fd->isBitField())
continue;
@@ -2067,7 +2067,7 @@ CharUnits CIRGenModule::computeNonVirtualBaseClassOffset(
const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd);
const auto *baseDecl = cast<CXXRecordDecl>(
- base->getType()->castAs<clang::RecordType>()->getDecl());
+ base->getType()->castAs<clang::RecordType>()->getOriginalDecl());
// Add the offset.
offset += layout.getBaseClassOffset(baseDecl);
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 3e07f6d3e54cc..34c74da351262 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -103,7 +103,8 @@ std::string CIRGenTypes::getRecordTypeName(const clang::RecordDecl *recordDecl,
policy.SuppressTagKeyword = true;
if (recordDecl->getIdentifier())
- astContext.getRecordType(recordDecl).print(outStream, policy);
+ QualType(astContext.getCanonicalTagType(recordDecl))
+ .print(outStream, policy);
else if (auto *typedefNameDecl = recordDecl->getTypedefNameForAnonDecl())
typedefNameDecl->printQualifiedName(outStream, policy);
else
@@ -138,7 +139,7 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt,
if (!alreadyChecked.insert(rd).second)
return true;
- const Type *key = cgt.getASTContext().getTagDeclType(rd).getTypePtr();
+ const Type *key = cgt.getASTContext().getCanonicalTagType(rd).getTypePtr();
// If this type is already laid out, converting it is a noop.
if (cgt.isRecordLayoutComplete(key))
@@ -182,7 +183,7 @@ isSafeToConvert(QualType qt, CIRGenTypes &cgt,
// If this is a record, check it.
if (const auto *rt = qt->getAs<RecordType>())
- return isSafeToConvert(rt->getDecl(), cgt, alreadyChecked);
+ return isSafeToConvert(rt->getOriginalDecl(), cgt, alreadyChecked);
// If this is an array, check the elements, which are embedded inline.
if (const auto *at = cgt.getASTContext().getAsArrayType(qt))
@@ -210,7 +211,7 @@ static bool isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt) {
mlir::Type CIRGenTypes::convertRecordDeclType(const clang::RecordDecl *rd) {
// TagDecl's are not necessarily unique, instead use the (clang) type
// connected to the decl.
- const Type *key = astContext.getTagDeclType(rd).getTypePtr();
+ const Type *key = astContext.getCanonicalTagType(rd).getTypePtr();
cir::RecordType entry = recordDeclTypes[key];
// If we don't have an entry for this record yet, create one.
@@ -242,7 +243,8 @@ mlir::Type CIRGenTypes::convertRecordDeclType(const clang::RecordDecl *rd) {
for (const auto &base : cxxRecordDecl->bases()) {
if (base.isVirtual())
continue;
- convertRecordDeclType(base.getType()->castAs<RecordType>()->getDecl());
+ convertRecordDeclType(
+ base.getType()->castAs<RecordType>()->getOriginalDecl());
}
}
@@ -275,7 +277,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->getDecl());
+ return convertRecordDeclType(recordType->getOriginalDecl());
// Has the type already been processed?
TypeCacheTy::iterator tci = typeCache.find(ty);
@@ -457,7 +459,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
}
case Type::Enum: {
- const EnumDecl *ed = cast<EnumType>(ty)->getDecl();
+ const EnumDecl *ed = cast<EnumType>(ty)->getOriginalDecl();
if (auto integerType = ed->getIntegerType(); !integerType.isNull())
return convertType(integerType);
// Return a placeholder 'i32' type. This can be changed later when the
@@ -516,7 +518,7 @@ mlir::Type CIRGenTypes::convertTypeForMem(clang::QualType qualType,
/// Return record layout info for the given record decl.
const CIRGenRecordLayout &
CIRGenTypes::getCIRGenRecordLayout(const RecordDecl *rd) {
- const auto *key = astContext.getTagDeclType(rd).getTypePtr();
+ const auto *key = astContext.getCanonicalTagType(rd).getTypePtr();
// If we have already computed the layout, return it.
auto it = cirGenRecordLayouts.find(key);
@@ -548,7 +550,7 @@ bool CIRGenTypes::isZeroInitializable(clang::QualType t) {
}
if (const RecordType *rt = t->getAs<RecordType>()) {
- const RecordDecl *rd = rt->getDecl();
+ const RecordDecl *rd = rt->getOriginalDecl();
return isZeroInitializable(rd);
}
@@ -622,9 +624,11 @@ void CIRGenTypes::updateCompletedType(const TagDecl *td) {
// a test case that meets that condition. C++ doesn't allow forward
// declaration of enums, and C doesn't allow an incomplete forward
// declaration with a non-default type.
- assert(
- !typeCache.count(ed->getTypeForDecl()) ||
- (convertType(ed->getIntegerType()) == typeCache[ed->getTypeForDecl()]));
+
+ CanQualType t = astContext.getCanonicalTagType(td);
+ assert(!typeCache.count(t->getTypePtr()) ||
+ (convertType(ed->getIntegerType()) == typeCache[t->getTypePtr()]));
+
// If necessary, provide the full definition of a type only used with a
// declaration so far.
assert(!cir::MissingFeatures::generateDebugInfo());
@@ -639,7 +643,7 @@ void CIRGenTypes::updateCompletedType(const TagDecl *td) {
// Only complete if we converted it already. If we haven't converted it yet,
// we'll just do it lazily.
- if (recordDeclTypes.count(astContext.getTagDeclType(rd).getTypePtr()))
+ if (recordDeclTypes.count(astContext.getCanonicalTagType(rd).getTypePtr()))
convertRecordDeclType(rd);
// If necessary, provide the full definition of a type only used with a
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp
index d2d32bbd9403c..dd20183b69b91 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp
@@ -10,20 +10,20 @@ bool clang::CIRGen::isEmptyRecordForLayout(const ASTContext &context,
if (!rt)
return false;
- const RecordDecl *rd = rt->getDecl();
+ const RecordDecl *rd = rt->getOriginalDecl();
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
if (cxxrd->isDynamicClass())
return false;
- for (const auto &I : cxxrd->bases())
- if (!isEmptyRecordForLayout(context, I.getType()))
+ for (const auto &i : cxxrd->bases())
+ if (!isEmptyRecordForLayout(context, i.getType()))
return false;
}
- for (const auto *I : rd->fields())
- if (!isEmptyFieldForLayout(context, I))
+ for (const auto *i : rd->fields())
+ if (!isEmptyFieldForLayout(context, i))
return false;
return true;
``````````
</details>
https://github.com/llvm/llvm-project/pull/152846
More information about the cfe-commits
mailing list