================
@@ -253,12 +257,229 @@ static void validatePackoffset(Sema &S, HLSLBufferDecl 
*BufDecl) {
   }
 }
 
+// Returns true if the array has a zero size = if any of the dimensions is 0
+static bool isZeroSizedArray(const ConstantArrayType *CAT) {
+  while (CAT && !CAT->isZeroSize())
+    CAT = dyn_cast<ConstantArrayType>(
+        CAT->getElementType()->getUnqualifiedDesugaredType());
+  return CAT != nullptr;
+}
+
+// Returns true if the struct contains at least one element that prevents it
+// from being included inside HLSL Buffer as is, such as an intangible type,
+// empty struct, or zero-sized array. If it does, a new implicit layout struct
+// needs to be created for HLSL Buffer use that will exclude these unwanted
+// declarations (see createHostLayoutStruct function).
+static bool requiresImplicitBufferLayoutStructure(const CXXRecordDecl *RD) {
+  if (RD->getTypeForDecl()->isHLSLIntangibleType() || RD->isEmpty())
+    return true;
+  // check fields
+  for (const FieldDecl *Field : RD->fields()) {
+    QualType Ty = Field->getType();
+    if (Ty->isRecordType()) {
+      if (requiresImplicitBufferLayoutStructure(Ty->getAsCXXRecordDecl()))
+        return true;
+    } else if (Ty->isConstantArrayType()) {
+      if (isZeroSizedArray(cast<ConstantArrayType>(Ty)))
+        return true;
+    }
+  }
+  // check bases
+  for (const CXXBaseSpecifier &Base : RD->bases())
+    if (requiresImplicitBufferLayoutStructure(
+            Base.getType()->getAsCXXRecordDecl()))
+      return true;
+  return false;
+}
+
+static CXXRecordDecl *findRecordDecl(Sema &S, IdentifierInfo *II,
+                                     DeclContext *DC) {
+  DeclarationNameInfo NameInfo =
+      DeclarationNameInfo(DeclarationName(II), SourceLocation());
+  LookupResult R(S, NameInfo, Sema::LookupOrdinaryName);
+  S.LookupName(R, S.getScopeForContext(DC));
+  if (R.isSingleResult())
+    return R.getAsSingle<CXXRecordDecl>();
+  return nullptr;
+}
+
+// Creates a name for buffer layout struct using the provide name base.
+// If the name must be unique (not previously defined), a suffix is added
+// until a unique name is found.
+static IdentifierInfo *getHostLayoutStructName(Sema &S,
+                                               IdentifierInfo *NameBaseII,
+                                               bool MustBeUnique,
+                                               DeclContext *DC) {
+  ASTContext &AST = S.getASTContext();
+  std::string NameBase;
----------------
llvm-beanz wrote:

`llvm::SmallString` might be a better option to reduce the likelihood of 
needing an allocation, and unifying `NameBase` and `Name` to a single 
`SmallString` would potentially reduce dynamic allocations and copying of 
string data.

https://github.com/llvm/llvm-project/pull/122820
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to