================
@@ -2361,6 +2361,99 @@ static bool DiagnoseHLSLRegisterAttribute(Sema &S, 
SourceLocation &ArgLoc,
   return ValidateMultipleRegisterAnnotations(S, D, RegType);
 }
 
+bool ExceedsUInt32Max(llvm::StringRef S) {
+  constexpr size_t MaxDigits = 10; // UINT32_MAX = 4294967295
+  if (S.size() > MaxDigits)
+    return true;
+
+  if (S.size() < MaxDigits)
+    return false;
+
+  return S.compare("4294967295") > 0;
+}
+
+// return false if the slot count exceeds the limit, true otherwise
+static bool AccumulateHLSLResourceSlots(QualType Ty, llvm::APInt &SlotCount,
+                                        const llvm::APInt &Limit,
+                                        ASTContext &Ctx,
+                                        uint64_t Multiplier = 1) {
+  Ty = Ty.getCanonicalType();
+  const Type *T = Ty.getTypePtr();
+
+  // Early exit if already overflowed
+  if (SlotCount.ugt(Limit))
+    return false;
+
+  // Case 1: array type
+  if (const auto *AT = dyn_cast<ArrayType>(T)) {
+    uint64_t Count = 1;
+
+    if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
+      Count = CAT->getSize().getZExtValue();
+    }
+    // TODO: how do we handle non constant resource arrays?
+
+    QualType ElemTy = AT->getElementType();
+
+    return AccumulateHLSLResourceSlots(ElemTy, SlotCount, Limit, Ctx,
+                                       Multiplier * Count);
+  }
+
+  // Case 2: resource leaf
+  if (T->isHLSLResourceRecord()) {
+    llvm::APInt Add(SlotCount.getBitWidth(), Multiplier);
+    SlotCount += Add;
+    return SlotCount.ule(Limit);
+  }
+
+  // Case 3: struct / record
+  if (const auto *RT = dyn_cast<RecordType>(T)) {
+    const RecordDecl *RD = RT->getDecl();
+    for (const FieldDecl *Field : RD->fields()) {
+      if (!AccumulateHLSLResourceSlots(Field->getType(), SlotCount, Limit, Ctx,
+                                       Multiplier))
+        return false;
+    }
+    return true;
+  }
+
+  // Case 4: everything else
+  return true;
+}
+
+// return true if there is something invalid, false otherwise
+bool ValidateRegisterNumber(StringRef SlotNumStr, Decl *TheDecl,
+                            ASTContext &Ctx) {
+  if (ExceedsUInt32Max(SlotNumStr))
+    return true;
+
+  llvm::APInt SlotNum;
+  if (SlotNumStr.getAsInteger(10, SlotNum))
+    return false;
----------------
bob80905 wrote:

Yeah, there are. The string could be empty. I notice that 
err_hlsl_unsupported_register_number is right below this, and should be the 
diagnostic emitted if this were the case. But I can't just move this under, 
since getAsInteger also errors if the value overflows the datatype, which this 
new diagnostic should be responsible for.
So I'll update ValidateRegisterNumber to account for this.



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

Reply via email to