https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/136854
>From fd1d37ebf0f1c4a23f573444f30730b0f65630bf Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Wed, 23 Apr 2025 20:23:09 +0800 Subject: [PATCH 1/2] [CIR] Cleanup support for C functions --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 82 +++++++++++++++++++- clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 90 +++++++++++++++++++++- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 17 +++- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 37 ++++----- clang/lib/CIR/CodeGen/CIRGenTypes.h | 12 ++- clang/lib/CIR/CodeGen/TargetInfo.cpp | 10 ++- clang/test/CIR/CodeGen/basic.c | 13 ++++ 7 files changed, 232 insertions(+), 29 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 69266f79a88a5..b223bc494f928 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -13,20 +13,76 @@ #include "CIRGenCall.h" #include "CIRGenFunction.h" +#include "CIRGenFunctionInfo.h" #include "clang/CIR/MissingFeatures.h" using namespace clang; using namespace clang::CIRGen; -CIRGenFunctionInfo *CIRGenFunctionInfo::create(CanQualType resultType) { - void *buffer = operator new(totalSizeToAlloc<ArgInfo>(1)); +CIRGenFunctionInfo * +CIRGenFunctionInfo::create(CanQualType resultType, + llvm::ArrayRef<CanQualType> argTypes, + RequiredArgs required) { + void *buffer = operator new(totalSizeToAlloc<ArgInfo>(argTypes.size() + 1)); CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo(); + + fi->required = required; + fi->numArgs = argTypes.size(); fi->getArgsBuffer()[0].type = resultType; + for (unsigned i = 0; i < argTypes.size(); ++i) + fi->getArgsBuffer()[i + 1].type = argTypes[i]; return fi; } +cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) { + bool inserted = functionsBeingProcessed.insert(&fi).second; + assert(inserted && "Recursively being processed?"); + + mlir::Type resultType = nullptr; + const cir::ABIArgInfo &retAI = fi.getReturnInfo(); + + switch (retAI.getKind()) { + case cir::ABIArgInfo::Ignore: + // TODO(CIR): This should probably be the None type from the builtin + // dialect. + resultType = nullptr; + break; + + case cir::ABIArgInfo::Direct: + resultType = retAI.getCoerceToType(); + break; + + default: + assert(false && "NYI"); + } + + SmallVector<mlir::Type, 8> argTypes; + unsigned argNo = 0; + CIRGenFunctionInfo::const_arg_iterator it = fi.arg_begin(), + ie = it + fi.getNumRequiredArgs(); + for (; it != ie; ++it, ++argNo) { + const auto &argInfo = it->info; + + switch (argInfo.getKind()) { + default: + llvm_unreachable("NYI"); + case cir::ABIArgInfo::Direct: + mlir::Type argType = argInfo.getCoerceToType(); + argTypes.push_back(argType); + break; + } + } + + bool erased = functionsBeingProcessed.erase(&fi); + assert(erased && "Not in set?"); + + return cir::FuncType::get(argTypes, + (resultType ? resultType : builder.getVoidTy()), + fi.isVariadic()); +} + CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const { assert(!cir::MissingFeatures::opCallVirtual()); return *this; @@ -35,6 +91,9 @@ CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const { static const CIRGenFunctionInfo & arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm, const FunctionType *fnType) { + + RequiredArgs required = RequiredArgs::All; + if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) { if (proto->isVariadic()) cgm.errorNYI("call to variadic function"); @@ -49,7 +108,7 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm, CanQualType retType = fnType->getReturnType() ->getCanonicalTypeUnqualified() .getUnqualifiedType(); - return cgt.arrangeCIRFunctionInfo(retType); + return cgt.arrangeCIRFunctionInfo(retType, {}, required); } const CIRGenFunctionInfo & @@ -71,6 +130,23 @@ static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf, return builder.createCallOp(callLoc, directFuncOp); } +const CIRGenFunctionInfo & +CIRGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> fpt) { + SmallVector<CanQualType, 16> argTypes; + for (unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) + argTypes.push_back(fpt->getParamType(i)); + RequiredArgs required = RequiredArgs::forPrototypePlus(fpt); + + CanQualType resultType = fpt->getReturnType().getUnqualifiedType(); + return arrangeCIRFunctionInfo(resultType, argTypes, required); +} + +const CIRGenFunctionInfo & +CIRGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> fnpt) { + CanQualType resultType = fnpt->getReturnType().getUnqualifiedType(); + return arrangeCIRFunctionInfo(resultType, {}, RequiredArgs(0)); +} + RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index c4a2b238c96ae..f08fe46ad98a1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h @@ -27,17 +27,68 @@ struct CIRGenFunctionInfoArgInfo { cir::ABIArgInfo info; }; +/// A class for recording the number of arguments that a function signature +/// requires. +class RequiredArgs { + /// The number of required arguments, or ~0 if the signature does not permit + /// optional arguments. + unsigned numRequired; + +public: + enum All_t { All }; + + RequiredArgs(All_t _) : numRequired(~0U) {} + explicit RequiredArgs(unsigned n) : numRequired(n) { assert(n != ~0U); } + + unsigned getOpaqueData() const { return numRequired; } + + bool allowsOptionalArgs() const { return numRequired != ~0U; } + + /// Compute the arguments required by the given formal prototype, given that + /// there may be some additional, non-formal arguments in play. + /// + /// If FD is not null, this will consider pass_object_size params in FD. + static RequiredArgs + forPrototypePlus(const clang::FunctionProtoType *prototype) { + if (!prototype->isVariadic()) + return All; + + if (prototype->hasExtParameterInfos()) + llvm_unreachable("NYI"); + + return RequiredArgs(prototype->getNumParams()); + } + + static RequiredArgs + forPrototypePlus(clang::CanQual<clang::FunctionProtoType> prototype) { + return forPrototypePlus(prototype.getTypePtr()); + } + + unsigned getNumRequiredArgs() const { + assert(allowsOptionalArgs()); + return numRequired; + } +}; + class CIRGenFunctionInfo final : public llvm::FoldingSetNode, private llvm::TrailingObjects<CIRGenFunctionInfo, CIRGenFunctionInfoArgInfo> { using ArgInfo = CIRGenFunctionInfoArgInfo; + RequiredArgs required; + + unsigned numArgs; + ArgInfo *getArgsBuffer() { return getTrailingObjects<ArgInfo>(); } const ArgInfo *getArgsBuffer() const { return getTrailingObjects<ArgInfo>(); } + CIRGenFunctionInfo() : required(RequiredArgs::All) {} + public: - static CIRGenFunctionInfo *create(CanQualType resultType); + static CIRGenFunctionInfo *create(CanQualType resultType, + llvm::ArrayRef<CanQualType> argTypes, + RequiredArgs required); void operator delete(void *p) { ::operator delete(p); } @@ -47,11 +98,22 @@ class CIRGenFunctionInfo final // This function has to be CamelCase because llvm::FoldingSet requires so. // NOLINTNEXTLINE(readability-identifier-naming) - static void Profile(llvm::FoldingSetNodeID &id, CanQualType resultType) { + static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required, + CanQualType resultType, + llvm::ArrayRef<CanQualType> argTypes) { + id.AddBoolean(required.getOpaqueData()); resultType.Profile(id); + for (const auto &arg : argTypes) + arg.Profile(id); } - void Profile(llvm::FoldingSetNodeID &id) { getReturnType().Profile(id); } + // NOLINTNEXTLINE(readability-identifier-naming) + void Profile(llvm::FoldingSetNodeID &id) { + id.AddBoolean(required.getOpaqueData()); + getReturnType().Profile(id); + for (const auto &i : arguments()) + i.type.Profile(id); + } CanQualType getReturnType() const { return getArgsBuffer()[0].type; } @@ -59,6 +121,28 @@ class CIRGenFunctionInfo final const cir::ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } + using const_arg_iterator = const ArgInfo *; + using arg_iterator = ArgInfo *; + + const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } + const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + numArgs; } + arg_iterator arg_begin() { return getArgsBuffer() + 1; } + arg_iterator arg_end() { return getArgsBuffer() + 1 + numArgs; } + + unsigned arg_size() const { return numArgs; } + + llvm::MutableArrayRef<ArgInfo> arguments() { + return llvm::MutableArrayRef<ArgInfo>(arg_begin(), numArgs); + } + llvm::ArrayRef<ArgInfo> arguments() const { + return llvm::ArrayRef<ArgInfo>(arg_begin(), numArgs); + } + + bool isVariadic() const { return required.allowsOptionalArgs(); } + RequiredArgs getRequiredArgs() const { return required; } + unsigned getNumRequiredArgs() const { + return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size(); + } }; } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 3b13d495be5e3..fad1416fa2225 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -212,8 +212,21 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, "function definition with a non-identifier for a name"); return; } - cir::FuncType funcType = - cast<cir::FuncType>(convertType(funcDecl->getType())); + + cir::FuncType funcType; + // TODO: Move this to arrangeFunctionDeclaration when it is + // implemented. + // When declaring a function without a prototype, always use a + // non-variadic type. + if (CanQual<FunctionNoProtoType> noProto = + funcDecl->getType() + ->getCanonicalTypeUnqualified() + .getAs<FunctionNoProtoType>()) { + auto &fi = getTypes().arrangeCIRFunctionInfo(noProto->getReturnType(), {}, + RequiredArgs::All); + funcType = getTypes().getFunctionType(fi); + } else + funcType = cast<cir::FuncType>(convertType(funcDecl->getType())); cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op); if (!funcOp || funcOp.getFunctionType() != funcType) { diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index b11f8466607f8..bf3d96af37936 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -73,21 +73,19 @@ mlir::Type CIRGenTypes::convertFunctionTypeInternal(QualType qft) { return cir::FuncType::get(SmallVector<mlir::Type, 1>{}, cgm.VoidTy); } - // TODO(CIR): This is a stub of what the final code will be. See the - // implementation of this function and the implementation of class - // CIRGenFunction in the ClangIR incubator project. - + const CIRGenFunctionInfo *fi; if (const auto *fpt = dyn_cast<FunctionProtoType>(ft)) { - SmallVector<mlir::Type> mlirParamTypes; - for (unsigned i = 0; i < fpt->getNumParams(); ++i) { - mlirParamTypes.push_back(convertType(fpt->getParamType(i))); - } - return cir::FuncType::get( - mlirParamTypes, convertType(fpt->getReturnType().getUnqualifiedType()), - fpt->isVariadic()); + fi = &arrangeFreeFunctionType( + CanQual<FunctionProtoType>::CreateUnsafe(QualType(fpt, 0))); + } else { + const FunctionNoProtoType *fnpt = cast<FunctionNoProtoType>(ft); + fi = &arrangeFreeFunctionType( + CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(fnpt, 0))); } - cgm.errorNYI(SourceLocation(), "non-prototype function type", qft); - return cir::FuncType::get(SmallVector<mlir::Type, 1>{}, cgm.VoidTy); + + mlir::Type resultType = getFunctionType(*fi); + + return resultType; } // This is CIR's version of CodeGenTypes::addRecordTypeName. It isn't shareable @@ -494,10 +492,12 @@ bool CIRGenTypes::isZeroInitializable(clang::QualType t) { } const CIRGenFunctionInfo & -CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType) { +CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType, + llvm::ArrayRef<CanQualType> argTypes, + RequiredArgs required) { // Lookup or create unique function info. llvm::FoldingSetNodeID id; - CIRGenFunctionInfo::Profile(id, returnType); + CIRGenFunctionInfo::Profile(id, required, returnType, argTypes); void *insertPos = nullptr; CIRGenFunctionInfo *fi = functionInfos.FindNodeOrInsertPos(id, insertPos); @@ -507,14 +507,13 @@ CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType) { assert(!cir::MissingFeatures::opCallCallConv()); // Construction the function info. We co-allocate the ArgInfos. - fi = CIRGenFunctionInfo::create(returnType); + fi = CIRGenFunctionInfo::create(returnType, argTypes, required); functionInfos.InsertNode(fi, insertPos); bool inserted = functionsBeingProcessed.insert(fi).second; (void)inserted; assert(inserted && "Are functions being processed recursively?"); - assert(!cir::MissingFeatures::opCallCallConv()); getABIInfo().computeInfo(*fi); // Loop over all of the computed argument and return value info. If any of @@ -524,7 +523,9 @@ CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType) { if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr) retInfo.setCoerceToType(convertType(fi->getReturnType())); - assert(!cir::MissingFeatures::opCallArgs()); + for (auto &i : fi->arguments()) + if (i.info.canHaveCoerceToType() && i.info.getCoerceToType() == nullptr) + i.info.setCoerceToType(convertType(i.type)); bool erased = functionsBeingProcessed.erase(fi); (void)erased; diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h b/clang/lib/CIR/CodeGen/CIRGenTypes.h index 5b4027601ca3a..e82bf5197d4a2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h @@ -123,7 +123,17 @@ class CIRGenTypes { const CIRGenFunctionInfo &arrangeFreeFunctionCall(const FunctionType *fnType); - const CIRGenFunctionInfo &arrangeCIRFunctionInfo(CanQualType returnType); + const CIRGenFunctionInfo & + arrangeCIRFunctionInfo(CanQualType returnType, + llvm::ArrayRef<CanQualType> argTypes, + RequiredArgs required); + + const CIRGenFunctionInfo & + arrangeFreeFunctionType(CanQual<FunctionProtoType> fpt); + const CIRGenFunctionInfo & + arrangeFreeFunctionType(CanQual<FunctionNoProtoType> fnpt); + + cir::FuncType getFunctionType(const CIRGenFunctionInfo &fi); }; } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp index 0d0ffb93d4e7e..efba2c2345ff4 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.cpp +++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp @@ -32,8 +32,14 @@ void X8664ABIInfo::computeInfo(CIRGenFunctionInfo &funcInfo) const { // Top level CIR has unlimited arguments and return types. Lowering for ABI // specific concerns should happen during a lowering phase. Assume everything // is direct for now. - assert(!cir::MissingFeatures::opCallArgs()); - + for (CIRGenFunctionInfo::arg_iterator it = funcInfo.arg_begin(), + ie = funcInfo.arg_end(); + it != ie; ++it) { + if (testIfIsVoidTy(it->type)) + it->info = cir::ABIArgInfo::getIgnore(); + else + it->info = cir::ABIArgInfo::getDirect(cgt.convertType(it->type)); + } CanQualType retTy = funcInfo.getReturnType(); if (testIfIsVoidTy(retTy)) funcInfo.getReturnInfo() = cir::ABIArgInfo::getIgnore(); diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c index 1845d3b64bf68..70dd885f4f6d7 100644 --- a/clang/test/CIR/CodeGen/basic.c +++ b/clang/test/CIR/CodeGen/basic.c @@ -233,6 +233,19 @@ int f8(int *p) { // OGCG: %[[P2:.*]] = load ptr, ptr %[[P_PTR]], align 8 // OGCG: %[[STAR_P:.*]] = load i32, ptr %[[P2]], align 4 + +void f9() {} + +// CIR: cir.func @f9() +// CIR-NEXT: cir.return + +// LLVM: define void @f9() +// LLVM-NEXT: ret void + +// OGCG: define{{.*}} void @f9() +// OGCG-NEXT: entry: +// OGCG-NEXT: ret void + typedef unsigned long size_type; typedef unsigned long _Tp; >From 02b5829537c3861f245df4bfff692ee05f61826d Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Thu, 24 Apr 2025 18:51:22 +0800 Subject: [PATCH 2/2] apply suggestions --- clang/include/clang/CIR/MissingFeatures.h | 2 + clang/lib/CIR/CodeGen/CIRGenCall.cpp | 54 ++++++++++++++-------- clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 29 ++++++------ clang/lib/CIR/CodeGen/CIRGenModule.cpp | 5 +- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 3 +- clang/lib/CIR/CodeGen/TargetInfo.cpp | 10 ++-- 6 files changed, 61 insertions(+), 42 deletions(-) diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 6bfc1199aea55..c4cc863ff26f7 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -159,6 +159,8 @@ struct MissingFeatures { static bool bitfields() { return false; } static bool typeChecks() { return false; } static bool lambdaFieldToName() { return false; } + static bool paramInfo() { return false; } + static bool funcTypeExtInfo() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index b223bc494f928..f1bbfd2c513db 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -25,25 +25,34 @@ CIRGenFunctionInfo::create(CanQualType resultType, RequiredArgs required) { void *buffer = operator new(totalSizeToAlloc<ArgInfo>(argTypes.size() + 1)); + assert(!cir::MissingFeatures::paramInfo()); + assert(!cir::MissingFeatures::funcTypeExtInfo()); + CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo(); fi->required = required; fi->numArgs = argTypes.size(); - fi->getArgsBuffer()[0].type = resultType; - for (unsigned i = 0; i < argTypes.size(); ++i) - fi->getArgsBuffer()[i + 1].type = argTypes[i]; + + // ArgsBuffer contains the return type at index 0, and the argument types + // starting at index 1, so there are argTypes.size() + 1 elements in total. + unsigned idx = 1; + ArgInfo *argsBuffer = fi->getArgsBuffer(); + argsBuffer[0].type = resultType; + for (const auto &argType : argTypes) + argsBuffer[idx++].type = argType; return fi; } cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) { bool inserted = functionsBeingProcessed.insert(&fi).second; + (void)inserted; assert(inserted && "Recursively being processed?"); - mlir::Type resultType = nullptr; - const cir::ABIArgInfo &retAI = fi.getReturnInfo(); + mlir::Type resultType; + const cir::ABIArgInfo &retInfo = fi.getReturnInfo(); - switch (retAI.getKind()) { + switch (retInfo.getKind()) { case cir::ABIArgInfo::Ignore: // TODO(CIR): This should probably be the None type from the builtin // dialect. @@ -51,31 +60,36 @@ cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) { break; case cir::ABIArgInfo::Direct: - resultType = retAI.getCoerceToType(); + resultType = retInfo.getCoerceToType(); break; default: - assert(false && "NYI"); + cgm.errorNYI("getFunctionType: unhandled return kind"); } - SmallVector<mlir::Type, 8> argTypes; - unsigned argNo = 0; - CIRGenFunctionInfo::const_arg_iterator it = fi.arg_begin(), - ie = it + fi.getNumRequiredArgs(); - for (; it != ie; ++it, ++argNo) { - const auto &argInfo = it->info; + // TODO(cir): ClangToCIRArgMapping - switch (argInfo.getKind()) { - default: - llvm_unreachable("NYI"); - case cir::ABIArgInfo::Direct: - mlir::Type argType = argInfo.getCoerceToType(); - argTypes.push_back(argType); + SmallVector<mlir::Type, 8> argTypes(fi.getNumRequiredArgs()); + + unsigned argNo = 0; + llvm::ArrayRef<CIRGenFunctionInfoArgInfo> argInfos(fi.argInfoBegin(), + fi.getNumRequiredArgs()); + for (const auto &argInfo : argInfos) { + const auto &abiArgInfo = argInfo.info; + + switch (abiArgInfo.getKind()) { + case cir::ABIArgInfo::Direct: { + mlir::Type argType = abiArgInfo.getCoerceToType(); + argTypes[argNo++] = argType; break; } + default: + cgm.errorNYI("getFunctionType: unhandled argument kind"); + } } bool erased = functionsBeingProcessed.erase(&fi); + (void)erased; assert(erased && "Not in set?"); return cir::FuncType::get(argTypes, diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index f08fe46ad98a1..05463a1412a5b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h @@ -103,7 +103,7 @@ class CIRGenFunctionInfo final llvm::ArrayRef<CanQualType> argTypes) { id.AddBoolean(required.getOpaqueData()); resultType.Profile(id); - for (const auto &arg : argTypes) + for (const CanQualType &arg : argTypes) arg.Profile(id); } @@ -111,8 +111,8 @@ class CIRGenFunctionInfo final void Profile(llvm::FoldingSetNodeID &id) { id.AddBoolean(required.getOpaqueData()); getReturnType().Profile(id); - for (const auto &i : arguments()) - i.type.Profile(id); + for (const ArgInfo &argInfo : argInfos()) + argInfo.type.Profile(id); } CanQualType getReturnType() const { return getArgsBuffer()[0].type; } @@ -124,24 +124,27 @@ class CIRGenFunctionInfo final using const_arg_iterator = const ArgInfo *; using arg_iterator = ArgInfo *; - const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } - const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + numArgs; } - arg_iterator arg_begin() { return getArgsBuffer() + 1; } - arg_iterator arg_end() { return getArgsBuffer() + 1 + numArgs; } + const_arg_iterator argInfoBegin() const { return getArgsBuffer() + 1; } + const_arg_iterator argInfoEnd() const { + return getArgsBuffer() + 1 + numArgs; + } + arg_iterator argInfoBegin() { return getArgsBuffer() + 1; } + arg_iterator argInfoEnd() { return getArgsBuffer() + 1 + numArgs; } - unsigned arg_size() const { return numArgs; } + unsigned argInfoSize() const { return numArgs; } - llvm::MutableArrayRef<ArgInfo> arguments() { - return llvm::MutableArrayRef<ArgInfo>(arg_begin(), numArgs); + llvm::MutableArrayRef<ArgInfo> argInfos() { + return llvm::MutableArrayRef<ArgInfo>(argInfoBegin(), numArgs); } - llvm::ArrayRef<ArgInfo> arguments() const { - return llvm::ArrayRef<ArgInfo>(arg_begin(), numArgs); + llvm::ArrayRef<ArgInfo> argInfos() const { + return llvm::ArrayRef<ArgInfo>(argInfoBegin(), numArgs); } bool isVariadic() const { return required.allowsOptionalArgs(); } RequiredArgs getRequiredArgs() const { return required; } unsigned getNumRequiredArgs() const { - return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size(); + return isVariadic() ? getRequiredArgs().getNumRequiredArgs() + : argInfoSize(); } }; diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index fad1416fa2225..9b5423c69c94c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -22,6 +22,7 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/MissingFeatures.h" +#include "CIRGenFunctionInfo.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Location.h" #include "mlir/IR/MLIRContext.h" @@ -222,8 +223,8 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, funcDecl->getType() ->getCanonicalTypeUnqualified() .getAs<FunctionNoProtoType>()) { - auto &fi = getTypes().arrangeCIRFunctionInfo(noProto->getReturnType(), {}, - RequiredArgs::All); + const CIRGenFunctionInfo &fi = getTypes().arrangeCIRFunctionInfo( + noProto->getReturnType(), {}, RequiredArgs::All); funcType = getTypes().getFunctionType(fi); } else funcType = cast<cir::FuncType>(convertType(funcDecl->getType())); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index bf3d96af37936..e46960ad895bb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -1,5 +1,6 @@ #include "CIRGenTypes.h" +#include "CIRGenFunctionInfo.h" #include "CIRGenModule.h" #include "clang/AST/ASTContext.h" @@ -523,7 +524,7 @@ CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType, if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr) retInfo.setCoerceToType(convertType(fi->getReturnType())); - for (auto &i : fi->arguments()) + for (CIRGenFunctionInfoArgInfo &i : fi->argInfos()) if (i.info.canHaveCoerceToType() && i.info.getCoerceToType() == nullptr) i.info.setCoerceToType(convertType(i.type)); diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp index efba2c2345ff4..0eb9debff62a6 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.cpp +++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp @@ -32,13 +32,11 @@ void X8664ABIInfo::computeInfo(CIRGenFunctionInfo &funcInfo) const { // Top level CIR has unlimited arguments and return types. Lowering for ABI // specific concerns should happen during a lowering phase. Assume everything // is direct for now. - for (CIRGenFunctionInfo::arg_iterator it = funcInfo.arg_begin(), - ie = funcInfo.arg_end(); - it != ie; ++it) { - if (testIfIsVoidTy(it->type)) - it->info = cir::ABIArgInfo::getIgnore(); + for (CIRGenFunctionInfoArgInfo &argInfo : funcInfo.argInfos()) { + if (testIfIsVoidTy(argInfo.type)) + argInfo.info = cir::ABIArgInfo::getIgnore(); else - it->info = cir::ABIArgInfo::getDirect(cgt.convertType(it->type)); + argInfo.info = cir::ABIArgInfo::getDirect(cgt.convertType(argInfo.type)); } CanQualType retTy = funcInfo.getReturnType(); if (testIfIsVoidTy(retTy)) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits