Ver código fonte

Added support for returning arrays from functions. (#1988)

Tristan Labelle 6 anos atrás
pai
commit
7b70d0144a

+ 6 - 11
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -780,14 +780,9 @@ MatrixOrientation GetMatrixMajor(QualType Ty, bool bDefaultRowMajor) {
                           : MatrixOrientation::ColumnMajor;
 }
 
-QualType GetArrayEltType(QualType Ty) {
-  // Get element type.
-  if (Ty->isArrayType()) {
-    while (isa<clang::ArrayType>(Ty)) {
-      const clang::ArrayType *ATy = dyn_cast<clang::ArrayType>(Ty);
-      Ty = ATy->getElementType();
-    }
-  }
+QualType GetArrayEltType(ASTContext& Context, QualType Ty) {
+  while (const clang::ArrayType *ArrayTy = Context.getAsArrayType(Ty))
+    Ty = ArrayTy->getElementType();
   return Ty;
 }
 
@@ -801,7 +796,7 @@ void CGMSHLSLRuntime::ConstructFieldAttributedAnnotation(
     Ty = Ty.getNonReferenceType();
 
   // Get element type.
-  Ty = GetArrayEltType(Ty);
+  Ty = GetArrayEltType(CGM.getContext(), Ty);
 
   QualType EltTy = Ty;
   if (hlsl::IsHLSLMatType(Ty)) {
@@ -6789,8 +6784,8 @@ void CGMSHLSLRuntime::EmitHLSLFlatConversionAggregateCopy(CodeGenFunction &CGF,
   if (SrcPtrTy == DestPtrTy) {
     bool bMatArrayRotate = false;
     if (HLMatrixType::isMatrixArrayPtr(SrcPtr->getType())) {
-      QualType SrcEltTy = GetArrayEltType(SrcTy);
-      QualType DestEltTy = GetArrayEltType(DestTy);
+      QualType SrcEltTy = GetArrayEltType(CGM.getContext(), SrcTy);
+      QualType DestEltTy = GetArrayEltType(CGM.getContext(), DestTy);
       if (GetMatrixMajor(SrcEltTy, bDefaultRowMajor) !=
           GetMatrixMajor(DestEltTy, bDefaultRowMajor)) {
         bMatArrayRotate = true;

+ 1 - 1
tools/clang/lib/Sema/SemaType.cpp

@@ -3762,7 +3762,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
 
       // C99 6.7.5.3p1: The return type may not be a function or array type.
       // For conversion functions, we'll diagnose this particular error later.
-      if ((T->isArrayType() || T->isFunctionType()) &&
+      if (((T->isArrayType() && !S.getLangOpts().HLSL) || T->isFunctionType()) && // HLSL Change - Allow array return types
           (D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId)) {
         unsigned diagID = diag::err_func_returning_array_function;
         // Last processing chunk in block context means this function chunk

+ 13 - 0
tools/clang/test/CodeGenHLSL/declarations/functions/array_return_type/entrypoint.hlsl

@@ -0,0 +1,13 @@
+// RUN: %dxc -E main -T vs_6_2 %s | FileCheck %s
+
+// Tests that entry point functions can return arrays,
+// and that elements are considered to be on different rows.
+
+typedef int A[2];
+A main() : OUT
+{
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 1)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 1, i8 0, i32 2)
+  A a = { 1, 2 };
+  return a;
+}

+ 18 - 0
tools/clang/test/CodeGenHLSL/declarations/functions/array_return_type/entrypoint_matrix.hlsl

@@ -0,0 +1,18 @@
+// RUN: %dxc -E main -T vs_6_2 /Zpr %s | FileCheck %s
+
+// Tests that entry point functions can return arrays of vectors.
+
+typedef int2x2 A[2];
+A main() : OUT
+{
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 11)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 12)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 1, i8 0, i32 21)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 1, i8 1, i32 22)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 2, i8 0, i32 111)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 2, i8 1, i32 112)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 3, i8 0, i32 121)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 3, i8 1, i32 122)
+  A a = { int2x2(11, 12, 21, 22), int2x2(111, 112, 121, 122) };
+  return a;
+}

+ 14 - 0
tools/clang/test/CodeGenHLSL/declarations/functions/array_return_type/entrypoint_vector.hlsl

@@ -0,0 +1,14 @@
+// RUN: %dxc -E main -T vs_6_2 %s | FileCheck %s
+
+// Tests that entry point functions can return arrays of vectors.
+
+typedef int2 A[2];
+A main() : OUT
+{
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 1)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 2)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 1, i8 0, i32 3)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 1, i8 1, i32 4)
+  A a = { int2(1, 2), int2(3, 4) };
+  return a;
+}

+ 17 - 0
tools/clang/test/CodeGenHLSL/declarations/functions/array_return_type/non_entrypoint.hlsl

@@ -0,0 +1,17 @@
+// RUN: %dxc -E main -T vs_6_2 %s | FileCheck %s
+
+// Tests that non-entry point functions can return arrays.
+
+typedef int A[2];
+A getA()
+{
+  A a = { 1, 2 };
+  return a;
+}
+
+int2 main() : OUT
+{
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 1)
+  // CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 2)
+  return (int2)getA();
+}