diff --git a/clang/include/clang/Sema/HLSLExternalSemaSource.h b/clang/include/clang/Sema/HLSLExternalSemaSource.h index 4b6bc96f72e22..c0bfff327139f 100644 --- a/clang/include/clang/Sema/HLSLExternalSemaSource.h +++ b/clang/include/clang/Sema/HLSLExternalSemaSource.h @@ -30,9 +30,9 @@ class HLSLExternalSemaSource : public ExternalSemaSource { void defineHLSLVectorAlias(); void defineTrivialHLSLTypes(); - void forwardDeclareHLSLTypes(); + void defineHLSLTypesWithForwardDeclarations(); - void completeBufferType(CXXRecordDecl *Record); + void onCompletion(CXXRecordDecl *Record, CompletionFunction Fn); public: ~HLSLExternalSemaSource() override; diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 5057bc6629f04..8ed6480a9f5c9 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -306,6 +306,7 @@ struct BuiltinTypeDeclBuilder { } TemplateParameterListBuilder addTemplateArgumentList(); + BuiltinTypeDeclBuilder &addSimpleTemplateParams(ArrayRef Names); }; struct TemplateParameterListBuilder { @@ -360,11 +361,19 @@ struct TemplateParameterListBuilder { return Builder; } }; +} // namespace TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() { return TemplateParameterListBuilder(*this); } -} // namespace + +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef Names) { + TemplateParameterListBuilder Builder = this->addTemplateArgumentList(); + for (StringRef Name : Names) + Builder.addTypeParameter(Name); + return Builder.finalizeTemplateArgs(); +} HLSLExternalSemaSource::~HLSLExternalSemaSource() {} @@ -390,7 +399,7 @@ void HLSLExternalSemaSource::InitializeSema(Sema &S) { // Force external decls in the HLSL namespace to load from the PCH. (void)HLSLNamespace->getCanonicalDecl()->decls_begin(); defineTrivialHLSLTypes(); - forwardDeclareHLSLTypes(); + defineHLSLTypesWithForwardDeclarations(); // This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's // built in types inside a namespace, but we are planning to change that in @@ -467,18 +476,32 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() { .Record; } -void HLSLExternalSemaSource::forwardDeclareHLSLTypes() { +/// Set up common members and attributes for buffer types +static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, + ResourceClass RC, + ResourceKind RK) { + return BuiltinTypeDeclBuilder(Decl) + .addHandleMember() + .addDefaultHandleConstructor(S, RC) + .annotateResourceClass(RC, RK); +} + +void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addTemplateArgumentList() - .addTypeParameter("element_type") - .finalizeTemplateArgs() + .addSimpleTemplateParams({"element_type"}) .Record; - if (!Decl->isCompleteDefinition()) - Completions.insert( - std::make_pair(Decl->getCanonicalDecl(), - std::bind(&HLSLExternalSemaSource::completeBufferType, - this, std::placeholders::_1))); + onCompletion(Decl, [this](CXXRecordDecl *Decl) { + setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, + ResourceKind::TypedBuffer) + .addArraySubscriptOperators() + .completeDefinition(); + }); +} + +void HLSLExternalSemaSource::onCompletion(CXXRecordDecl *Record, + CompletionFunction Fn) { + Completions.insert(std::make_pair(Record->getCanonicalDecl(), Fn)); } void HLSLExternalSemaSource::CompleteType(TagDecl *Tag) { @@ -496,12 +519,3 @@ void HLSLExternalSemaSource::CompleteType(TagDecl *Tag) { return; It->second(Record); } - -void HLSLExternalSemaSource::completeBufferType(CXXRecordDecl *Record) { - BuiltinTypeDeclBuilder(Record) - .addHandleMember() - .addDefaultHandleConstructor(*SemaPtr, ResourceClass::UAV) - .addArraySubscriptOperators() - .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer) - .completeDefinition(); -}