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

Reply via email to