================
@@ -4843,6 +4796,200 @@ bool SemaHLSL::transformInitList(const 
InitializedEntity &Entity,
   return true;
 }
 
+QualType SemaHLSL::checkMatrixComponent(Sema &S, QualType baseType,
+                                        ExprValueKind &VK, SourceLocation 
OpLoc,
+                                        const IdentifierInfo *CompName,
+                                        SourceLocation CompLoc) {
+  const auto *MT = baseType->getAs<ConstantMatrixType>();
+  StringRef AccessorName = CompName->getName();
+  assert(MT &&
+         "checkMatrixComponent is intended to be used on ConstantMatrixType");
+  assert(!AccessorName.empty() && "Matrix Accessor must have a name");
+
+  unsigned Rows = MT->getNumRows();
+  unsigned Cols = MT->getNumColumns();
+  bool IsZeroBasedAccessor = false;
+  unsigned ChunkLen = 0;
+  if (AccessorName.size() < 2) {
+    const char Expected[] = "length 4 for zero based: \'_mRC\' or length 3 for 
"
+                            "one-based: \'_RC\' accessor";
+    S.Diag(OpLoc, diag::err_builtin_matrix_invalid_member)
+        << CompName->getName() << StringRef(Expected, sizeof(Expected) - 1)
+        << SourceRange(CompLoc);
+    return QualType();
+  }
+  if (AccessorName[0] == '_') {
+    if (AccessorName[1] == 'm') {
+      IsZeroBasedAccessor = true;
+      ChunkLen = 4; // zero-based: "_mRC"
+    } else {
+      ChunkLen = 3; // one-based: "_RC"
+    }
+  } else {
+    const char Expected[] =
+        "zero based: \'_mRC\' or one-based: \'_RC\' accessor";
+    S.Diag(OpLoc, diag::err_builtin_matrix_invalid_member)
+        << CompName->getName() << StringRef(Expected, sizeof(Expected) - 1)
+        << SourceRange(CompLoc);
+    return QualType();
+  }
+
+  if (AccessorName.size() % ChunkLen != 0) {
+    const llvm::StringRef Expected = IsZeroBasedAccessor
+                                         ? "zero based: '_mRC' accessor"
+                                         : "one-based: '_RC' accessor";
+
+    S.Diag(OpLoc, diag::err_builtin_matrix_invalid_member)
+        << CompName->getName() << Expected << SourceRange(CompLoc);
+    return QualType();
+  }
+
+  auto isDigit = [](char c) { return c >= '0' && c <= '9'; };
+  auto isZeroBasedIndex = [](unsigned i) { return i <= 3; };
+  auto isOneBasedIndex = [](unsigned i) { return i >= 1 && i <= 4; };
+
+  bool HasRepeated = false;
+  SmallVector<bool, 16> Seen(Rows * Cols, false);
+  unsigned NumComponents = 0;
+  const char *Begin = AccessorName.data();
+
+  for (unsigned I = 0, E = AccessorName.size(); I < E; I += ChunkLen) {
+    const char *Chunk = Begin + I;
+    char RowChar = 0, ColChar = 0;
+    if (IsZeroBasedAccessor) {
+      // Zero-based: "_mRC"
+      if (Chunk[0] != '_' || Chunk[1] != 'm') {
+        char Bad = (Chunk[0] != '_') ? Chunk[0] : Chunk[1];
+        const char Expected[] = "\'_m\' prefix";
+        S.Diag(OpLoc.getLocWithOffset(I + (Bad == Chunk[0] ? 1 : 2)),
+               diag::err_builtin_matrix_invalid_member)
+            << StringRef(&Bad, 1) << StringRef(Expected, sizeof(Expected) - 1)
+            << SourceRange(CompLoc);
+        return QualType();
+      }
+      RowChar = Chunk[2];
+      ColChar = Chunk[3];
+    } else {
+      // One-based: "_RC"
+      if (Chunk[0] != '_') {
+        const char Expected[] = "\'_\' prefix";
+        S.Diag(OpLoc.getLocWithOffset(I + 1),
+               diag::err_builtin_matrix_invalid_member)
+            << StringRef(&Chunk[0], 1)
+            << StringRef(Expected, sizeof(Expected) - 1)
+            << SourceRange(CompLoc);
+        return QualType();
+      }
+      RowChar = Chunk[1];
+      ColChar = Chunk[2];
+    }
+
+    // Must be digits.
+    bool isDigitsError = false;
----------------
farzonl wrote:

It is so I can emit two errors for row and column and give the user more 
information before giving up on the semantic parsing 

https://github.com/llvm/llvm-project/pull/171225
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to