[clang] [flang] [Flang] LoongArch64 support for BIND(C) derived types in mabi=lp64d. (PR #117108)

Zhaoxin Yang via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 06:52:46 PST 2024


================
@@ -1151,6 +1154,311 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> {
 
     return GenericTarget::integerArgumentType(loc, argTy);
   }
+
+  /// Flatten non-basic types, resulting in an array of types containing only
+  /// `IntegerType` and `FloatType`.
+  std::vector<mlir::Type> flattenTypeList(mlir::Location loc,
+                                          const mlir::Type type) const {
+    std::vector<mlir::Type> flatTypes;
+
+    llvm::TypeSwitch<mlir::Type>(type)
+        .template Case<mlir::IntegerType>([&](mlir::IntegerType intTy) {
+          if (intTy.getWidth() != 0)
+            flatTypes.push_back(intTy);
+        })
+        .template Case<mlir::FloatType>([&](mlir::FloatType floatTy) {
+          if (floatTy.getWidth() != 0)
+            flatTypes.push_back(floatTy);
+        })
+        .template Case<mlir::ComplexType>([&](mlir::ComplexType cmplx) {
+          const auto *sem = &floatToSemantics(kindMap, cmplx.getElementType());
+          if (sem == &llvm::APFloat::IEEEsingle() ||
+              sem == &llvm::APFloat::IEEEdouble() ||
+              sem == &llvm::APFloat::IEEEquad())
+            std::fill_n(std::back_inserter(flatTypes), 2,
+                        cmplx.getElementType());
+          else
+            TODO(loc, "unsupported complx type(not IEEEsingle, IEEEdouble, "
+                      "IEEEquad) as a structure component for BIND(C), "
+                      "VALUE derived type argument and type return");
+        })
+        .template Case<fir::LogicalType>([&](fir::LogicalType logicalTy) {
+          const auto width = kindMap.getLogicalBitsize(logicalTy.getFKind());
+          if (width != 0)
+            flatTypes.push_back(
+                mlir::IntegerType::get(type.getContext(), width));
+        })
+        .template Case<fir::CharacterType>([&](fir::CharacterType charTy) {
+          flatTypes.push_back(mlir::IntegerType::get(type.getContext(), 8));
----------------
ylzsx wrote:

It seems that the demo you provided can only be used outside of ISO_C_BINDING. Below is a test I created:
```
program main
    implicit none

    character(kind=4) :: i
    call foo(i)

contains
    subroutine foo(i) bind(c)
        character(kind=4) :: i
    end subroutine foo
end program main
```
and when I compile it in a X86-64 machine using flang, I got a compilation error:
```
error: Semantic errors in char-struct.f90
./char-struct.f90:9:30: error: A BIND(C) object must have an interoperable type
          character(kind=4) :: i
```
When I delete the `bind(c)` attribute, it compile success. However, the argument is passed by reference, and it does not enter functions for architecture-specific processing.

>From the results above, it appears that the `character` type used for Interoperability with C is only one byte, which seems to be the same as the last line of Table 18.2 in section 18.3.1 of the manual [18-007r1](https://j3-fortran.org/doc/year/18/18-007r1.pdf#subsection.3437) I'm still a beginner in Fortran, I'm not sure if there is any misunderstanding. I would appreciate your suggestions.

https://github.com/llvm/llvm-project/pull/117108


More information about the cfe-commits mailing list