================ @@ -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