https://github.com/el-ev updated 
https://github.com/llvm/llvm-project/pull/136854

>From dbe66e5e48f769589592e22bcfb8c122910d91d1 Mon Sep 17 00:00:00 2001
From: Iris Shi <0...@owo.li>
Date: Thu, 8 May 2025 23:40:15 +0800
Subject: [PATCH] [CIR] Cleanup support for C functions

---
 clang/lib/CIR/CodeGen/CIRGenCall.cpp       | 110 ++++++++++++++++++---
 clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 103 +++++++++++++++----
 clang/lib/CIR/CodeGen/CIRGenModule.cpp     |  18 +++-
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp      |  40 ++++----
 clang/lib/CIR/CodeGen/CIRGenTypes.h        |  10 +-
 clang/lib/CIR/CodeGen/TargetInfo.cpp       |   8 +-
 clang/test/CIR/CodeGen/basic.c             |  13 +++
 7 files changed, 244 insertions(+), 58 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index bed0db28818f1..c8c12b509dca8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -13,6 +13,7 @@
 
 #include "CIRGenCall.h"
 #include "CIRGenFunction.h"
+#include "CIRGenFunctionInfo.h"
 #include "clang/CIR/MissingFeatures.h"
 
 using namespace clang;
@@ -20,20 +21,22 @@ using namespace clang::CIRGen;
 
 CIRGenFunctionInfo *
 CIRGenFunctionInfo::create(CanQualType resultType,
-                           llvm::ArrayRef<CanQualType> argTypes) {
+                           llvm::ArrayRef<CanQualType> argTypes,
+                           RequiredArgs required) {
   // The first slot allocated for ArgInfo is for the return value.
   void *buffer = operator new(totalSizeToAlloc<ArgInfo>(argTypes.size() + 1));
 
+  assert(!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo());
+
   CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo();
-  fi->numArgs = argTypes.size();
 
-  assert(!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo());
+  fi->required = required;
+  fi->numArgs = argTypes.size();
 
   ArgInfo *argsBuffer = fi->getArgsBuffer();
   (argsBuffer++)->type = resultType;
   for (CanQualType ty : argTypes)
     (argsBuffer++)->type = ty;
-
   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
 
   return fi;
@@ -45,7 +48,7 @@ namespace {
 /// CIRGenFunctionInfo should be passed to actual CIR function.
 class ClangToCIRArgMapping {
   static constexpr unsigned invalidIndex = ~0U;
-  unsigned totalNumCIRArgs;
+  unsigned totalNumCIRArgs = 0;
 
   /// Arguments of CIR function corresponding to single Clang argument.
   struct CIRArgs {
@@ -61,14 +64,20 @@ class ClangToCIRArgMapping {
 
 public:
   ClangToCIRArgMapping(const ASTContext &astContext,
-                       const CIRGenFunctionInfo &funcInfo)
-      : totalNumCIRArgs(0), argInfo(funcInfo.arg_size()) {
+                       const CIRGenFunctionInfo &funcInfo,
+                       bool onlyRequiredArgs)
+      : argInfo(onlyRequiredArgs ? funcInfo.getNumRequiredArgs()
+                                 : funcInfo.argInfoSize()) {
     unsigned cirArgNo = 0;
 
     assert(!cir::MissingFeatures::opCallABIIndirectArg());
 
     unsigned argNo = 0;
-    for (const CIRGenFunctionInfoArgInfo &i : funcInfo.arguments()) {
+    llvm::ArrayRef<CIRGenFunctionInfoArgInfo> argInfos(
+        funcInfo.argInfoBegin(), onlyRequiredArgs
+                                     ? funcInfo.getNumRequiredArgs()
+                                     : funcInfo.argInfoSize());
+    for (const CIRGenFunctionInfoArgInfo &i : argInfos) {
       // Collect data about CIR arguments corresponding to Clang argument 
ArgNo.
       CIRArgs &cirArgs = argInfo[argNo];
 
@@ -119,6 +128,63 @@ class ClangToCIRArgMapping {
 
 } // namespace
 
+cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) {
+  bool inserted = functionsBeingProcessed.insert(&fi).second;
+  (void)inserted;
+  assert(inserted && "Recursively being processed?");
+
+  mlir::Type resultType;
+  const cir::ABIArgInfo &retInfo = fi.getReturnInfo();
+
+  switch (retInfo.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 = retInfo.getCoerceToType();
+    break;
+  }
+
+  ClangToCIRArgMapping cirFunctionArgs(getASTContext(), fi, true);
+  SmallVector<mlir::Type, 8> argTypes(cirFunctionArgs.totalCIRArgs());
+
+  unsigned argNo = 0;
+  llvm::ArrayRef<CIRGenFunctionInfoArgInfo> argInfos(fi.argInfoBegin(),
+                                                     fi.getNumRequiredArgs());
+  for (const auto &argInfo : argInfos) {
+    const auto &abiArgInfo = argInfo.info;
+
+    unsigned firstCIRArg, numCIRArgs;
+    std::tie(firstCIRArg, numCIRArgs) = cirFunctionArgs.getCIRArgs(argNo);
+
+    switch (abiArgInfo.getKind()) {
+    case cir::ABIArgInfo::Direct: {
+      mlir::Type argType = abiArgInfo.getCoerceToType();
+      // TODO: handle the test against llvm::RecordType from codegen
+      assert(numCIRArgs == 1);
+      argTypes[firstCIRArg] = argType;
+      break;
+    }
+    default:
+      cgm.errorNYI("getFunctionType: unhandled argument kind");
+    }
+
+    ++argNo;
+  }
+  assert(argNo == fi.argInfoSize() &&
+         "Mismatch between function info and args");
+
+  bool erased = functionsBeingProcessed.erase(&fi);
+  (void)erased;
+  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;
@@ -128,6 +194,9 @@ static const CIRGenFunctionInfo &
 arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
                             const CallArgList &args,
                             const FunctionType *fnType) {
+
+  RequiredArgs required = RequiredArgs::All;
+
   if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
     if (proto->isVariadic())
       cgm.errorNYI("call to variadic function");
@@ -144,7 +213,7 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule 
&cgm,
   CanQualType retType = fnType->getReturnType()
                             ->getCanonicalTypeUnqualified()
                             .getUnqualifiedType();
-  return cgt.arrangeCIRFunctionInfo(retType, argTypes);
+  return cgt.arrangeCIRFunctionInfo(retType, argTypes, required);
 }
 
 const CIRGenFunctionInfo &
@@ -168,6 +237,23 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
   return builder.createCallOp(callLoc, directFuncOp, cirCallArgs);
 }
 
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> fpt) {
+  SmallVector<CanQualType, 8> 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,
@@ -177,16 +263,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo 
&funcInfo,
   QualType retTy = funcInfo.getReturnType();
   const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo();
 
-  ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo);
+  ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo, false);
   SmallVector<mlir::Value, 16> cirCallArgs(cirFuncArgs.totalCIRArgs());
 
   assert(!cir::MissingFeatures::emitLifetimeMarkers());
 
   // Translate all of the arguments as necessary to match the CIR lowering.
-  assert(funcInfo.arg_size() == args.size() &&
+  assert(funcInfo.argInfoSize() == args.size() &&
          "Mismatch between function signature & arguments.");
   unsigned argNo = 0;
-  for (const auto &[arg, argInfo] : llvm::zip(args, funcInfo.arguments())) {
+  for (const auto &[arg, argInfo] : llvm::zip(args, funcInfo.argInfos())) {
     // Insert a padding argument to ensure proper alignment.
     assert(!cir::MissingFeatures::opCallPaddingArgs());
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h 
b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
index 4319f7a2be225..50be94dd7ee6f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -27,20 +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,
-                                    llvm::ArrayRef<CanQualType> argTypes);
+                                    llvm::ArrayRef<CanQualType> argTypes,
+                                    RequiredArgs required);
 
   void operator delete(void *p) { ::operator delete(p); }
 
@@ -53,35 +101,52 @@ 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,
-                      llvm::ArrayRef<clang::CanQualType> argTypes) {
+  static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required,
+                      CanQualType resultType,
+                      llvm::ArrayRef<CanQualType> argTypes) {
+    id.AddBoolean(required.getOpaqueData());
     resultType.Profile(id);
-    for (auto i : argTypes)
-      i.Profile(id);
+    for (const CanQualType &arg : argTypes)
+      arg.Profile(id);
   }
 
-  void Profile(llvm::FoldingSetNodeID &id) { getReturnType().Profile(id); }
-
-  llvm::MutableArrayRef<ArgInfo> arguments() {
-    return llvm::MutableArrayRef<ArgInfo>(arg_begin(), numArgs);
-  }
-  llvm::ArrayRef<ArgInfo> arguments() const {
-    return llvm::ArrayRef<ArgInfo>(arg_begin(), numArgs);
+  // NOLINTNEXTLINE(readability-identifier-naming)
+  void Profile(llvm::FoldingSetNodeID &id) {
+    id.AddBoolean(required.getOpaqueData());
+    getReturnType().Profile(id);
+    for (const ArgInfo &argInfo : argInfos())
+      argInfo.type.Profile(id);
   }
 
-  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; }
-
   CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
 
   cir::ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
   const cir::ABIArgInfo &getReturnInfo() const {
     return getArgsBuffer()[0].info;
   }
+
+  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 argInfoSize() const { return numArgs; }
+
+  llvm::MutableArrayRef<ArgInfo> argInfos() {
+    return llvm::MutableArrayRef<ArgInfo>(argInfoBegin(), 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()
+                        : argInfoSize();
+  }
 };
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 82bd139295b10..61ba5aa16a5a0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -23,6 +23,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"
@@ -247,8 +248,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>()) {
+    const CIRGenFunctionInfo &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 89dc5eea7f028..ea25aca8e6ff8 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"
@@ -73,21 +74,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
@@ -518,14 +517,15 @@ bool CIRGenTypes::isZeroInitializable(const RecordDecl 
*rd) {
   return getCIRGenRecordLayout(rd).isZeroInitializable();
 }
 
-const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
-    CanQualType returnType, llvm::ArrayRef<clang::CanQualType> argTypes) {
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType,
+                                    llvm::ArrayRef<CanQualType> argTypes,
+                                    RequiredArgs required) {
   assert(llvm::all_of(argTypes,
-                      [](CanQualType T) { return T.isCanonicalAsParam(); }));
-
+                      [](CanQualType t) { return t.isCanonicalAsParam(); }));
   // Lookup or create unique function info.
   llvm::FoldingSetNodeID id;
-  CIRGenFunctionInfo::Profile(id, returnType, argTypes);
+  CIRGenFunctionInfo::Profile(id, required, returnType, argTypes);
 
   void *insertPos = nullptr;
   CIRGenFunctionInfo *fi = functionInfos.FindNodeOrInsertPos(id, insertPos);
@@ -535,7 +535,7 @@ const CIRGenFunctionInfo 
&CIRGenTypes::arrangeCIRFunctionInfo(
   assert(!cir::MissingFeatures::opCallCallConv());
 
   // Construction the function info. We co-allocate the ArgInfos.
-  fi = CIRGenFunctionInfo::create(returnType, argTypes);
+  fi = CIRGenFunctionInfo::create(returnType, argTypes, required);
   functionInfos.InsertNode(fi, insertPos);
 
   bool inserted = functionsBeingProcessed.insert(fi).second;
@@ -552,7 +552,7 @@ const CIRGenFunctionInfo 
&CIRGenTypes::arrangeCIRFunctionInfo(
   if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
     retInfo.setCoerceToType(convertType(fi->getReturnType()));
 
-  for (CIRGenFunctionInfoArgInfo &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/CIRGenTypes.h 
b/clang/lib/CIR/CodeGen/CIRGenTypes.h
index cf94375d17e12..ff8ce3f87f362 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h
@@ -127,7 +127,15 @@ class CIRGenTypes {
 
   const CIRGenFunctionInfo &
   arrangeCIRFunctionInfo(CanQualType returnType,
-                         llvm::ArrayRef<clang::CanQualType> argTypes);
+                         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 0b70170cadb69..a2b71876026c9 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp
@@ -32,11 +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 (CIRGenFunctionInfoArgInfo &info : funcInfo.arguments()) {
-    if (testIfIsVoidTy(info.type))
-      info.info = cir::ABIArgInfo::getIgnore();
+  for (CIRGenFunctionInfoArgInfo &argInfo : funcInfo.argInfos()) {
+    if (testIfIsVoidTy(argInfo.type))
+      argInfo.info = cir::ABIArgInfo::getIgnore();
     else
-      info.info = cir::ABIArgInfo::getDirect(cgt.convertType(info.type));
+      argInfo.info = cir::ABIArgInfo::getDirect(cgt.convertType(argInfo.type));
   }
 
   CanQualType retTy = funcInfo.getReturnType();
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;
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to