https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/112600
>From 0739f6da81d7c1edd9578ae4ff9dd699e5c828c6 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 10 Oct 2024 14:31:25 -0700 Subject: [PATCH 01/14] ConceptSpecializationExpr shows up in AST!!! --- .../clang/Sema/HLSLExternalSemaSource.h | 2 + clang/lib/AST/DeclTemplate.cpp | 6 +- clang/lib/Sema/HLSLExternalSemaSource.cpp | 154 +++++++++++++++++- 3 files changed, 158 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Sema/HLSLExternalSemaSource.h b/clang/include/clang/Sema/HLSLExternalSemaSource.h index 3c7495e66055dc..0266bc0f8b336e 100644 --- a/clang/include/clang/Sema/HLSLExternalSemaSource.h +++ b/clang/include/clang/Sema/HLSLExternalSemaSource.h @@ -47,6 +47,8 @@ class HLSLExternalSemaSource : public ExternalSemaSource { using ExternalASTSource::CompleteType; /// Complete an incomplete HLSL builtin type void CompleteType(TagDecl *Tag) override; + + ConceptDecl *getTypedBufferConceptDecl(Sema &S, CXXRecordDecl *Decl); }; } // namespace clang diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 6fe817c5ef1c6b..2eae6d14718b86 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1080,10 +1080,10 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, TemplateParameterList *Params, Expr *ConstraintExpr) { bool Invalid = AdoptTemplateParameterList(Params, DC); - auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); + auto *CD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); if (Invalid) - TD->setInvalidDecl(); - return TD; + CD->setInvalidDecl(); + return CD; } ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 2913d16fca4823..8104513857027c 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -304,6 +304,7 @@ struct BuiltinTypeDeclBuilder { TemplateParameterListBuilder addTemplateArgumentList(Sema &S); BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S, ArrayRef<StringRef> Names); + BuiltinTypeDeclBuilder &addConceptSpecializationExpr(Sema &S); }; struct TemplateParameterListBuilder { @@ -326,7 +327,8 @@ struct TemplateParameterListBuilder { SourceLocation(), /* TemplateDepth */ 0, Position, &S.Context.Idents.get(Name, tok::TokenKind::identifier), /* Typename */ false, - /* ParameterPack */ false); + /* ParameterPack */ false, + /* HasTypeConstraint*/ true); if (!DefaultValue.isNull()) Decl->setDefaultArgument( S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), @@ -336,6 +338,152 @@ struct TemplateParameterListBuilder { return *this; } + Expr *getTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, + TemplateTypeParmDecl *T) { + clang::ASTContext &context = S.getASTContext(); + // Obtain the QualType for 'unsigned long' + clang::QualType unsignedLongType = context.UnsignedLongTy; + + // Create a QualType that points to this TemplateTypeParmDecl + clang::QualType TType = context.getTypeDeclType(T); + + // Create a TypeSourceInfo for the template type parameter 'T' + clang::TypeSourceInfo *TTypeSourceInfo = + context.getTrivialTypeSourceInfo(TType, NameLoc); + + clang::UnaryExprOrTypeTraitExpr *sizeofExpr = new (S.getASTContext()) + clang::UnaryExprOrTypeTraitExpr(clang::UETT_SizeOf, TTypeSourceInfo, + unsignedLongType, NameLoc, NameLoc); + + // Create an IntegerLiteral for the value '16' + llvm::APInt intValue(context.getIntWidth(context.IntTy), 4); + clang::IntegerLiteral *intLiteral = new (context) + clang::IntegerLiteral(context, intValue, context.IntTy, NameLoc); + + // Create an ImplicitCastExpr to cast 'int' to 'unsigned long' + FPOptionsOverride fpoo = FPOptionsOverride(); + clang::ImplicitCastExpr *implicitCastExpr = clang::ImplicitCastExpr::Create( + context, + unsignedLongType, // The type we are casting to (QualType for 'unsigned + // long') + clang::CK_IntegralCast, // CastKind (e.g., Integral cast) + intLiteral, // Sub-expression being cast + nullptr, // Base path, usually null for implicit casts + clang::VK_XValue, + fpoo // Value kind, typically VK_RValue for implicit casts + ); + + clang::QualType BoolTy = context.BoolTy; + + clang::BinaryOperator *binaryOperator = clang::BinaryOperator::Create( + context, sizeofExpr, // Left-hand side expression + implicitCastExpr, // Right-hand side expression + clang::BO_LE, // Binary operator kind (<=) + BoolTy, // Result type (bool) + clang::VK_XValue, // Value kind + clang::OK_Ordinary, // Object kind + NameLoc, // Source location of operator + fpoo); + + return binaryOperator; + } + + ConceptDecl *getTypedBufferConceptDecl(Sema &S, CXXRecordDecl *Decl) { + DeclContext *DC = S.CurContext; + clang::ASTContext &context = S.getASTContext(); + SourceLocation NameLoc = Decl->getBeginLoc(); + IdentifierInfo *Name = Decl->getIdentifier(); + + clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( + context, // AST context + context.getTranslationUnitDecl(), // DeclContext + NameLoc, // SourceLocation of 'T' + NameLoc, // SourceLocation of 'T' again + /*depth=*/0, // Depth in the template parameter list + /*position=*/0, // Position in the template parameter list + /*id=*/Name, // Identifier for 'T' + /*Typename=*/true, // Indicates this is a 'typename' or 'class' + /*ParameterPack=*/false // Not a parameter pack + ); + + T->setDeclContext(DC); + T->setReferenced(); + + // Create and Attach Template Parameter List to ConceptDecl + + llvm::ArrayRef<NamedDecl *> TemplateParamArrayRef = {T}; + clang::TemplateParameterList *Params = clang::TemplateParameterList::Create( + context, + NameLoc, // Source location of the template parameter list start + NameLoc, // Source location of the template parameter list end + TemplateParamArrayRef, // Template parameter (list as an ArrayRef) + NameLoc, // Source location of the template parameter list within + // concept + nullptr // Source location of the template parameter list end within + // concept + ); + + Expr *ConstraintExpr = getTypedBufferConstraintExpr(S, NameLoc, T); + + DeclarationName DeclName = DeclarationName(Name); + // Create a ConceptDecl + clang::ConceptDecl *conceptDecl = clang::ConceptDecl::Create( + context, + context.getTranslationUnitDecl(), // DeclContext + NameLoc, // Source location of start of concept + DeclName, // Source location of end of concept + Params, // Template type parameter + ConstraintExpr // Expression defining the concept + ); + + // Attach the template parameter list to the ConceptDecl + conceptDecl->setTemplateParameters(Params); + + // Add the concept declaration to the Translation Unit Decl + context.getTranslationUnitDecl()->addDecl(conceptDecl); + + return conceptDecl; + } + + BuiltinTypeDeclBuilder &addConceptSpecializationExpr(Sema &S) { + ASTContext &context = S.getASTContext(); + SourceLocation loc = Builder.Record->getBeginLoc(); + ConceptDecl *CD = getTypedBufferConceptDecl(S, Builder.Record); + DeclarationNameInfo DNI(Builder.Record->getDeclName(), loc); + NestedNameSpecifierLoc NNS; + ClassTemplateDecl *TD = Builder.Template; + + TemplateArgumentListInfo TALI(loc, loc); + const ASTTemplateArgumentListInfo *ATALI = + ASTTemplateArgumentListInfo::Create(context, TALI); + + ConceptReference *CR = ConceptReference::Create( + S.getASTContext(), NNS, loc, DNI, Builder.Record, CD, ATALI); + + TemplateTypeParmDecl *T = dyn_cast<TemplateTypeParmDecl>( + TD->getTemplateParameters()->getParam(0)); + + clang::QualType TType = context.getTypeDeclType(T); + + ArrayRef<TemplateArgument> ConvertedArgs = {TemplateArgument(TType)}; + + ImplicitConceptSpecializationDecl *IDecl = + ImplicitConceptSpecializationDecl::Create( + context, Builder.Record->getDeclContext(), loc, ConvertedArgs); + const ConstraintSatisfaction CS(CD, ConvertedArgs); + + TemplateParameterList *templateParams = TD->getTemplateParameters(); + ConceptSpecializationExpr *CSE = + ConceptSpecializationExpr::Create(context, CR, IDecl, &CS); + + TD->setTemplateParameters(templateParams); + T->setTypeConstraint(CR, CSE); + + Builder.Record->getDeclContext()->addDecl(IDecl); + + return Builder; + } + BuiltinTypeDeclBuilder &finalizeTemplateArgs() { if (Params.empty()) return Builder; @@ -346,9 +494,12 @@ struct TemplateParameterListBuilder { S.Context, Builder.Record->getDeclContext(), SourceLocation(), DeclarationName(Builder.Record->getIdentifier()), ParamList, Builder.Record); + addConceptSpecializationExpr(S); + Builder.Record->setDescribedClassTemplate(Builder.Template); Builder.Template->setImplicit(true); Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext()); + // NOTE: setPreviousDecl before addDecl so new decl replace old decl when // make visible. Builder.Template->setPreviousDecl(Builder.PrevTemplate); @@ -374,6 +525,7 @@ BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) Builder.addTypeParameter(Name); + return Builder.finalizeTemplateArgs(); } >From d1cb98e4cd2a9ffed967cb673760d44799fb20dd Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 10 Oct 2024 15:51:23 -0700 Subject: [PATCH 02/14] CSE is in the right spot in the AST --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 37 ++++++++++++++--------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 8104513857027c..885ed312d8ed51 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -445,14 +445,13 @@ struct TemplateParameterListBuilder { return conceptDecl; } - BuiltinTypeDeclBuilder &addConceptSpecializationExpr(Sema &S) { + ConceptSpecializationExpr *getConceptSpecializationExpr(Sema &S) { ASTContext &context = S.getASTContext(); SourceLocation loc = Builder.Record->getBeginLoc(); ConceptDecl *CD = getTypedBufferConceptDecl(S, Builder.Record); DeclarationNameInfo DNI(Builder.Record->getDeclName(), loc); NestedNameSpecifierLoc NNS; - ClassTemplateDecl *TD = Builder.Template; - + DeclContext *DC = Builder.Record->getDeclContext(); TemplateArgumentListInfo TALI(loc, loc); const ASTTemplateArgumentListInfo *ATALI = ASTTemplateArgumentListInfo::Create(context, TALI); @@ -460,8 +459,22 @@ struct TemplateParameterListBuilder { ConceptReference *CR = ConceptReference::Create( S.getASTContext(), NNS, loc, DNI, Builder.Record, CD, ATALI); - TemplateTypeParmDecl *T = dyn_cast<TemplateTypeParmDecl>( - TD->getTemplateParameters()->getParam(0)); + clang::TemplateTypeParmDecl *T = + clang::TemplateTypeParmDecl::Create( + context, // AST context + context.getTranslationUnitDecl(), // DeclContext + loc, // SourceLocation of 'T' + loc, // SourceLocation of 'T' again + /*depth=*/0, // Depth in the template parameter list + /*position=*/0, // Position in the template parameter list + /*id=*/Builder.Record->getIdentifier(), // Identifier for 'T' + /*Typename=*/true, // Indicates this is a 'typename' or 'class' + /*ParameterPack=*/false,// Not a parameter pack + /*HasTypeConstraint=*/true // Not a parameter pack + ); + + T->setDeclContext(DC); + T->setReferenced(); clang::QualType TType = context.getTypeDeclType(T); @@ -472,29 +485,25 @@ struct TemplateParameterListBuilder { context, Builder.Record->getDeclContext(), loc, ConvertedArgs); const ConstraintSatisfaction CS(CD, ConvertedArgs); - TemplateParameterList *templateParams = TD->getTemplateParameters(); ConceptSpecializationExpr *CSE = ConceptSpecializationExpr::Create(context, CR, IDecl, &CS); - - TD->setTemplateParameters(templateParams); T->setTypeConstraint(CR, CSE); - - Builder.Record->getDeclContext()->addDecl(IDecl); - - return Builder; + + return CSE; } BuiltinTypeDeclBuilder &finalizeTemplateArgs() { if (Params.empty()) return Builder; + ConceptSpecializationExpr *CSE = getConceptSpecializationExpr(S); + auto *ParamList = TemplateParameterList::Create(S.Context, SourceLocation(), SourceLocation(), Params, - SourceLocation(), nullptr); + SourceLocation(), CSE); Builder.Template = ClassTemplateDecl::Create( S.Context, Builder.Record->getDeclContext(), SourceLocation(), DeclarationName(Builder.Record->getIdentifier()), ParamList, Builder.Record); - addConceptSpecializationExpr(S); Builder.Record->setDescribedClassTemplate(Builder.Template); Builder.Template->setImplicit(true); >From ff195ae2a67a3354f64e037e0af2cf8d48b87d32 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 10 Oct 2024 17:55:46 -0700 Subject: [PATCH 03/14] templateArg is aligned correctly on the AST --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 885ed312d8ed51..eed793256399ff 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -449,15 +449,15 @@ struct TemplateParameterListBuilder { ASTContext &context = S.getASTContext(); SourceLocation loc = Builder.Record->getBeginLoc(); ConceptDecl *CD = getTypedBufferConceptDecl(S, Builder.Record); - DeclarationNameInfo DNI(Builder.Record->getDeclName(), loc); + DeclarationNameInfo DNI(CD->getDeclName(), loc); NestedNameSpecifierLoc NNS; DeclContext *DC = Builder.Record->getDeclContext(); TemplateArgumentListInfo TALI(loc, loc); const ASTTemplateArgumentListInfo *ATALI = ASTTemplateArgumentListInfo::Create(context, TALI); - ConceptReference *CR = ConceptReference::Create( - S.getASTContext(), NNS, loc, DNI, Builder.Record, CD, ATALI); + ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNS, loc, + DNI, CD, CD, ATALI); clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( @@ -478,17 +478,18 @@ struct TemplateParameterListBuilder { clang::QualType TType = context.getTypeDeclType(T); - ArrayRef<TemplateArgument> ConvertedArgs = {TemplateArgument(TType)}; + ArrayRef<TemplateArgument> ConvertedArgs = {TemplateArgument(TType), + TemplateArgument(TType)}; ImplicitConceptSpecializationDecl *IDecl = ImplicitConceptSpecializationDecl::Create( context, Builder.Record->getDeclContext(), loc, ConvertedArgs); + const ConstraintSatisfaction CS(CD, ConvertedArgs); ConceptSpecializationExpr *CSE = ConceptSpecializationExpr::Create(context, CR, IDecl, &CS); T->setTypeConstraint(CR, CSE); - return CSE; } >From 73f932f4179575660135bfb02166e1251a917fa7 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Tue, 15 Oct 2024 11:42:26 -0700 Subject: [PATCH 04/14] template arguments are in the right spot! --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 106 ++++++++++++++-------- 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index eed793256399ff..0135ff096b946d 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -338,6 +338,27 @@ struct TemplateParameterListBuilder { return *this; } + TemplateParameterListBuilder & + addTypenameTypeParameter(StringRef Name, QualType DefaultValue = QualType()) { + if (Builder.Record->isCompleteDefinition()) + return *this; + unsigned Position = static_cast<unsigned>(Params.size()); + auto *Decl = TemplateTypeParmDecl::Create( + S.Context, Builder.Record->getDeclContext(), SourceLocation(), + SourceLocation(), /* TemplateDepth */ 0, Position, + &S.Context.Idents.get(Name, tok::TokenKind::identifier), + /* Typename */ true, + /* ParameterPack */ false, + /* HasTypeConstraint*/ false); + if (!DefaultValue.isNull()) + Decl->setDefaultArgument( + S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), + SourceLocation())); + Decl->setReferenced(); + Params.emplace_back(Decl); + return *this; + } + Expr *getTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T) { clang::ASTContext &context = S.getASTContext(); @@ -369,7 +390,7 @@ struct TemplateParameterListBuilder { clang::CK_IntegralCast, // CastKind (e.g., Integral cast) intLiteral, // Sub-expression being cast nullptr, // Base path, usually null for implicit casts - clang::VK_XValue, + clang::VK_LValue, fpoo // Value kind, typically VK_RValue for implicit casts ); @@ -380,7 +401,7 @@ struct TemplateParameterListBuilder { implicitCastExpr, // Right-hand side expression clang::BO_LE, // Binary operator kind (<=) BoolTy, // Result type (bool) - clang::VK_XValue, // Value kind + clang::VK_LValue, // Value kind clang::OK_Ordinary, // Object kind NameLoc, // Source location of operator fpoo); @@ -392,7 +413,10 @@ struct TemplateParameterListBuilder { DeclContext *DC = S.CurContext; clang::ASTContext &context = S.getASTContext(); SourceLocation NameLoc = Decl->getBeginLoc(); - IdentifierInfo *Name = Decl->getIdentifier(); + + IdentifierInfo &IsValidLineVectorII = + context.Idents.get("is_valid_line_vector"); + IdentifierInfo &TII = context.Idents.get("T"); clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( context, // AST context @@ -401,7 +425,7 @@ struct TemplateParameterListBuilder { NameLoc, // SourceLocation of 'T' again /*depth=*/0, // Depth in the template parameter list /*position=*/0, // Position in the template parameter list - /*id=*/Name, // Identifier for 'T' + /*id=*/&TII, // Identifier for 'T' /*Typename=*/true, // Indicates this is a 'typename' or 'class' /*ParameterPack=*/false // Not a parameter pack ); @@ -412,32 +436,33 @@ struct TemplateParameterListBuilder { // Create and Attach Template Parameter List to ConceptDecl llvm::ArrayRef<NamedDecl *> TemplateParamArrayRef = {T}; - clang::TemplateParameterList *Params = clang::TemplateParameterList::Create( - context, - NameLoc, // Source location of the template parameter list start - NameLoc, // Source location of the template parameter list end - TemplateParamArrayRef, // Template parameter (list as an ArrayRef) - NameLoc, // Source location of the template parameter list within - // concept - nullptr // Source location of the template parameter list end within - // concept - ); + clang::TemplateParameterList *ConceptParams = + clang::TemplateParameterList::Create( + context, + NameLoc, // Source location of the template parameter list start + NameLoc, // Source location of the template parameter list end + TemplateParamArrayRef, // Template parameter (list as an ArrayRef) + NameLoc, // Source location of the template parameter list within + // concept + nullptr // Source location of the template parameter list end within + // concept + ); Expr *ConstraintExpr = getTypedBufferConstraintExpr(S, NameLoc, T); - DeclarationName DeclName = DeclarationName(Name); + DeclarationName DeclName = DeclarationName(&IsValidLineVectorII); // Create a ConceptDecl clang::ConceptDecl *conceptDecl = clang::ConceptDecl::Create( context, context.getTranslationUnitDecl(), // DeclContext NameLoc, // Source location of start of concept DeclName, // Source location of end of concept - Params, // Template type parameter + ConceptParams, // Template type parameter ConstraintExpr // Expression defining the concept ); // Attach the template parameter list to the ConceptDecl - conceptDecl->setTemplateParameters(Params); + conceptDecl->setTemplateParameters(ConceptParams); // Add the concept declaration to the Translation Unit Decl context.getTranslationUnitDecl()->addDecl(conceptDecl); @@ -453,43 +478,43 @@ struct TemplateParameterListBuilder { NestedNameSpecifierLoc NNS; DeclContext *DC = Builder.Record->getDeclContext(); TemplateArgumentListInfo TALI(loc, loc); - const ASTTemplateArgumentListInfo *ATALI = - ASTTemplateArgumentListInfo::Create(context, TALI); - - ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNS, loc, - DNI, CD, CD, ATALI); - clang::TemplateTypeParmDecl *T = - clang::TemplateTypeParmDecl::Create( - context, // AST context - context.getTranslationUnitDecl(), // DeclContext - loc, // SourceLocation of 'T' - loc, // SourceLocation of 'T' again - /*depth=*/0, // Depth in the template parameter list - /*position=*/0, // Position in the template parameter list - /*id=*/Builder.Record->getIdentifier(), // Identifier for 'T' - /*Typename=*/true, // Indicates this is a 'typename' or 'class' - /*ParameterPack=*/false,// Not a parameter pack - /*HasTypeConstraint=*/true // Not a parameter pack - ); + clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( + context, // AST context + context.getTranslationUnitDecl(), // DeclContext + SourceLocation(), SourceLocation(), + /*depth=*/0, // Depth in the template parameter list + /*position=*/0, // Position in the template parameter list + /*id=*/nullptr, // Identifier for 'T' + /*Typename=*/true, // Indicates this is a 'typename' or 'class' + /*ParameterPack=*/false, // Not a parameter pack + /*HasTypeConstraint=*/false // Not a parameter pack + ); T->setDeclContext(DC); T->setReferenced(); clang::QualType TType = context.getTypeDeclType(T); - ArrayRef<TemplateArgument> ConvertedArgs = {TemplateArgument(TType), - TemplateArgument(TType)}; + ArrayRef<TemplateArgument> ConvertedArgs = {TemplateArgument(TType)}; ImplicitConceptSpecializationDecl *IDecl = ImplicitConceptSpecializationDecl::Create( context, Builder.Record->getDeclContext(), loc, ConvertedArgs); const ConstraintSatisfaction CS(CD, ConvertedArgs); + TemplateArgumentLoc tal = S.getTrivialTemplateArgumentLoc( + TemplateArgument(TType), QualType(), SourceLocation()); + + TALI.addArgument(tal); + const ASTTemplateArgumentListInfo *ATALI = + ASTTemplateArgumentListInfo::Create(context, TALI); + ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNS, loc, + DNI, CD, CD, ATALI); ConceptSpecializationExpr *CSE = ConceptSpecializationExpr::Create(context, CR, IDecl, &CS); - T->setTypeConstraint(CR, CSE); + return CSE; } @@ -519,6 +544,9 @@ struct TemplateParameterListBuilder { QualType T = Builder.Template->getInjectedClassNameSpecialization(); T = S.Context.getInjectedClassNameType(Builder.Record, T); + ArrayRef<TemplateArgument> TempArgs = + Builder.Template->getInjectedTemplateArgs(); + return Builder; } }; @@ -534,7 +562,7 @@ BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, ArrayRef<StringRef> Names) { TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) - Builder.addTypeParameter(Name); + Builder.addTypenameTypeParameter(Name); return Builder.finalizeTemplateArgs(); } >From b1718c68a6025ea066e4badf8019b162dcfad68c Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Tue, 15 Oct 2024 14:04:46 -0700 Subject: [PATCH 05/14] template arguments are almost done --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 0135ff096b946d..bcfa3c591be91f 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -479,6 +479,9 @@ struct TemplateParameterListBuilder { DeclContext *DC = Builder.Record->getDeclContext(); TemplateArgumentListInfo TALI(loc, loc); + TemplateTypeParmDecl *ConceptTTPD = dyn_cast<TemplateTypeParmDecl>( + CD->getTemplateParameters()->getParam(0)); + clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( context, // AST context context.getTranslationUnitDecl(), // DeclContext @@ -494,21 +497,31 @@ struct TemplateParameterListBuilder { T->setDeclContext(DC); T->setReferenced(); - clang::QualType TType = context.getTypeDeclType(T); + clang::QualType TType = context.getTypeDeclType(ConceptTTPD); + + TemplateArgument TA = TemplateArgument(TType); + + ArrayRef<TemplateArgument> ConvertedArgs = {TA}; - ArrayRef<TemplateArgument> ConvertedArgs = {TemplateArgument(TType)}; + clang::QualType CSETType = context.getTypeDeclType(T); + + TemplateArgument CSETA = TemplateArgument(CSETType); + + ArrayRef<TemplateArgument> CSEConvertedArgs = {CSETA}; ImplicitConceptSpecializationDecl *IDecl = ImplicitConceptSpecializationDecl::Create( - context, Builder.Record->getDeclContext(), loc, ConvertedArgs); + context, Builder.Record->getDeclContext(), loc, CSEConvertedArgs); const ConstraintSatisfaction CS(CD, ConvertedArgs); - TemplateArgumentLoc tal = S.getTrivialTemplateArgumentLoc( - TemplateArgument(TType), QualType(), SourceLocation()); + TemplateArgumentLoc tal = + S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()); TALI.addArgument(tal); const ASTTemplateArgumentListInfo *ATALI = ASTTemplateArgumentListInfo::Create(context, TALI); + + // In CR, ATALI is what adds the extra TemplateArgument node underneath CSE ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNS, loc, DNI, CD, CD, ATALI); >From 63358a1d90d6e086b22c257e8d61501ae6f07343 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Tue, 15 Oct 2024 14:26:24 -0700 Subject: [PATCH 06/14] IT WORKS! updated template arg name, just need to remove extraneous templatetypeparmdecl --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index bcfa3c591be91f..6c490fe08b670f 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -423,9 +423,9 @@ struct TemplateParameterListBuilder { context.getTranslationUnitDecl(), // DeclContext NameLoc, // SourceLocation of 'T' NameLoc, // SourceLocation of 'T' again - /*depth=*/0, // Depth in the template parameter list - /*position=*/0, // Position in the template parameter list - /*id=*/&TII, // Identifier for 'T' + /*depth=*/0, // Depth in the template parameter list + /*position=*/0, // Position in the template parameter list + /*id=*/Params[0]->getIdentifier(), // Identifier for 'T' /*Typename=*/true, // Indicates this is a 'typename' or 'class' /*ParameterPack=*/false // Not a parameter pack ); >From efaf1254baad2807f9a415418a4cd7988dc71abc Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 16 Oct 2024 11:44:01 -0700 Subject: [PATCH 07/14] break down constraint expression into simpler function --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 41 ++++++++++++----------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 6c490fe08b670f..e2db32eeddc7df 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -359,9 +359,9 @@ struct TemplateParameterListBuilder { return *this; } - Expr *getTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, + BinaryOperator *getSizeOfLEQ16Expr(clang::ASTContext &context, + SourceLocation NameLoc, TemplateTypeParmDecl *T) { - clang::ASTContext &context = S.getASTContext(); // Obtain the QualType for 'unsigned long' clang::QualType unsignedLongType = context.UnsignedLongTy; @@ -376,29 +376,18 @@ struct TemplateParameterListBuilder { clang::UnaryExprOrTypeTraitExpr(clang::UETT_SizeOf, TTypeSourceInfo, unsignedLongType, NameLoc, NameLoc); - // Create an IntegerLiteral for the value '16' - llvm::APInt intValue(context.getIntWidth(context.IntTy), 4); - clang::IntegerLiteral *intLiteral = new (context) - clang::IntegerLiteral(context, intValue, context.IntTy, NameLoc); - - // Create an ImplicitCastExpr to cast 'int' to 'unsigned long' - FPOptionsOverride fpoo = FPOptionsOverride(); - clang::ImplicitCastExpr *implicitCastExpr = clang::ImplicitCastExpr::Create( - context, - unsignedLongType, // The type we are casting to (QualType for 'unsigned - // long') - clang::CK_IntegralCast, // CastKind (e.g., Integral cast) - intLiteral, // Sub-expression being cast - nullptr, // Base path, usually null for implicit casts - clang::VK_LValue, - fpoo // Value kind, typically VK_RValue for implicit casts - ); + // Create an IntegerLiteral for the value '16' with size type + clang::QualType sizeType = context.getSizeType(); + llvm::APInt sizeValue = llvm::APInt(context.getTypeSize(sizeType), 16); + clang::IntegerLiteral *sizeLiteral = new (context) + clang::IntegerLiteral(context, sizeValue, sizeType, NameLoc); clang::QualType BoolTy = context.BoolTy; + FPOptionsOverride fpoo = FPOptionsOverride(); clang::BinaryOperator *binaryOperator = clang::BinaryOperator::Create( context, sizeofExpr, // Left-hand side expression - implicitCastExpr, // Right-hand side expression + sizeLiteral, // Right-hand side expression clang::BO_LE, // Binary operator kind (<=) BoolTy, // Result type (bool) clang::VK_LValue, // Value kind @@ -409,6 +398,18 @@ struct TemplateParameterListBuilder { return binaryOperator; } + Expr *getTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, + TemplateTypeParmDecl *T) { + clang::ASTContext &context = S.getASTContext(); + + // first get the "sizeof(T) <= 16" expression, as a binary operator + // TODO: add the '__builtin_hlsl_is_line_vector_layout_compatible' builtin + // and return a binary operator that evaluates the builtin on the given + // template type parameter 'T' + BinaryOperator *sizeOfLEQ16 = getSizeOfLEQ16Expr(context, NameLoc, T); + return sizeOfLEQ16; + } + ConceptDecl *getTypedBufferConceptDecl(Sema &S, CXXRecordDecl *Decl) { DeclContext *DC = S.CurContext; clang::ASTContext &context = S.getASTContext(); >From 01ef90694786125414c044935e9d9afc5f5cdddc Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 16 Oct 2024 12:48:09 -0700 Subject: [PATCH 08/14] remove useless function --- .../clang/Sema/HLSLExternalSemaSource.h | 2 -- clang/lib/Sema/HLSLExternalSemaSource.cpp | 23 +------------------ 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/clang/include/clang/Sema/HLSLExternalSemaSource.h b/clang/include/clang/Sema/HLSLExternalSemaSource.h index 0266bc0f8b336e..3c7495e66055dc 100644 --- a/clang/include/clang/Sema/HLSLExternalSemaSource.h +++ b/clang/include/clang/Sema/HLSLExternalSemaSource.h @@ -47,8 +47,6 @@ class HLSLExternalSemaSource : public ExternalSemaSource { using ExternalASTSource::CompleteType; /// Complete an incomplete HLSL builtin type void CompleteType(TagDecl *Tag) override; - - ConceptDecl *getTypedBufferConceptDecl(Sema &S, CXXRecordDecl *Decl); }; } // namespace clang diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index a502f1743aa917..4fc1472a722ce6 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -317,27 +317,6 @@ struct TemplateParameterListBuilder { TemplateParameterListBuilder & addTypeParameter(StringRef Name, QualType DefaultValue = QualType()) { - if (Builder.Record->isCompleteDefinition()) - return *this; - unsigned Position = static_cast<unsigned>(Params.size()); - auto *Decl = TemplateTypeParmDecl::Create( - S.Context, Builder.Record->getDeclContext(), SourceLocation(), - SourceLocation(), /* TemplateDepth */ 0, Position, - &S.Context.Idents.get(Name, tok::TokenKind::identifier), - /* Typename */ false, - /* ParameterPack */ false, - /* HasTypeConstraint*/ true); - if (!DefaultValue.isNull()) - Decl->setDefaultArgument( - S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), - SourceLocation())); - - Params.emplace_back(Decl); - return *this; - } - - TemplateParameterListBuilder & - addTypenameTypeParameter(StringRef Name, QualType DefaultValue = QualType()) { if (Builder.Record->isCompleteDefinition()) return *this; unsigned Position = static_cast<unsigned>(Params.size()); @@ -574,7 +553,7 @@ BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, ArrayRef<StringRef> Names) { TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) - Builder.addTypenameTypeParameter(Name); + Builder.addTypeParameter(Name); return Builder.finalizeTemplateArgs(); } >From ee5dbc599fae7127bcee999c4e58405474f4403b Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 16 Oct 2024 13:40:15 -0700 Subject: [PATCH 09/14] some variable renaming, function rearranging --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 232 ++++++++++------------ 1 file changed, 110 insertions(+), 122 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 4fc1472a722ce6..a5f41e23cb7abe 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -301,7 +301,7 @@ struct BuiltinTypeDeclBuilder { TemplateParameterListBuilder addTemplateArgumentList(Sema &S); BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S, - ArrayRef<StringRef> Names); + ArrayRef<StringRef> Names, ConceptDecl *CD); BuiltinTypeDeclBuilder &addConceptSpecializationExpr(Sema &S); }; @@ -309,11 +309,12 @@ struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &Builder; Sema &S; llvm::SmallVector<NamedDecl *> Params; + TemplateParameterListBuilder(Sema &S, BuiltinTypeDeclBuilder &RB) : Builder(RB), S(S) {} - ~TemplateParameterListBuilder() { finalizeTemplateArgs(); } + ~TemplateParameterListBuilder() { finalizeTemplateArgs(nullptr); } TemplateParameterListBuilder & addTypeParameter(StringRef Name, QualType DefaultValue = QualType()) { @@ -334,124 +335,11 @@ struct TemplateParameterListBuilder { Decl->setReferenced(); Params.emplace_back(Decl); return *this; - } - - BinaryOperator *getSizeOfLEQ16Expr(clang::ASTContext &context, - SourceLocation NameLoc, - TemplateTypeParmDecl *T) { - // Obtain the QualType for 'unsigned long' - clang::QualType unsignedLongType = context.UnsignedLongTy; - - // Create a QualType that points to this TemplateTypeParmDecl - clang::QualType TType = context.getTypeDeclType(T); - - // Create a TypeSourceInfo for the template type parameter 'T' - clang::TypeSourceInfo *TTypeSourceInfo = - context.getTrivialTypeSourceInfo(TType, NameLoc); - - clang::UnaryExprOrTypeTraitExpr *sizeofExpr = new (S.getASTContext()) - clang::UnaryExprOrTypeTraitExpr(clang::UETT_SizeOf, TTypeSourceInfo, - unsignedLongType, NameLoc, NameLoc); - - // Create an IntegerLiteral for the value '16' with size type - clang::QualType sizeType = context.getSizeType(); - llvm::APInt sizeValue = llvm::APInt(context.getTypeSize(sizeType), 16); - clang::IntegerLiteral *sizeLiteral = new (context) - clang::IntegerLiteral(context, sizeValue, sizeType, NameLoc); - - clang::QualType BoolTy = context.BoolTy; - FPOptionsOverride fpoo = FPOptionsOverride(); - - clang::BinaryOperator *binaryOperator = clang::BinaryOperator::Create( - context, sizeofExpr, // Left-hand side expression - sizeLiteral, // Right-hand side expression - clang::BO_LE, // Binary operator kind (<=) - BoolTy, // Result type (bool) - clang::VK_LValue, // Value kind - clang::OK_Ordinary, // Object kind - NameLoc, // Source location of operator - fpoo); - - return binaryOperator; - } - - Expr *getTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, - TemplateTypeParmDecl *T) { - clang::ASTContext &context = S.getASTContext(); - - // first get the "sizeof(T) <= 16" expression, as a binary operator - // TODO: add the '__builtin_hlsl_is_line_vector_layout_compatible' builtin - // and return a binary operator that evaluates the builtin on the given - // template type parameter 'T' - BinaryOperator *sizeOfLEQ16 = getSizeOfLEQ16Expr(context, NameLoc, T); - return sizeOfLEQ16; - } - - ConceptDecl *getTypedBufferConceptDecl(Sema &S, CXXRecordDecl *Decl) { - DeclContext *DC = S.CurContext; - clang::ASTContext &context = S.getASTContext(); - SourceLocation NameLoc = Decl->getBeginLoc(); - - IdentifierInfo &IsValidLineVectorII = - context.Idents.get("is_valid_line_vector"); - IdentifierInfo &TII = context.Idents.get("T"); - - clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( - context, // AST context - context.getTranslationUnitDecl(), // DeclContext - NameLoc, // SourceLocation of 'T' - NameLoc, // SourceLocation of 'T' again - /*depth=*/0, // Depth in the template parameter list - /*position=*/0, // Position in the template parameter list - /*id=*/Params[0]->getIdentifier(), // Identifier for 'T' - /*Typename=*/true, // Indicates this is a 'typename' or 'class' - /*ParameterPack=*/false // Not a parameter pack - ); - - T->setDeclContext(DC); - T->setReferenced(); + } - // Create and Attach Template Parameter List to ConceptDecl - - llvm::ArrayRef<NamedDecl *> TemplateParamArrayRef = {T}; - clang::TemplateParameterList *ConceptParams = - clang::TemplateParameterList::Create( - context, - NameLoc, // Source location of the template parameter list start - NameLoc, // Source location of the template parameter list end - TemplateParamArrayRef, // Template parameter (list as an ArrayRef) - NameLoc, // Source location of the template parameter list within - // concept - nullptr // Source location of the template parameter list end within - // concept - ); - - Expr *ConstraintExpr = getTypedBufferConstraintExpr(S, NameLoc, T); - - DeclarationName DeclName = DeclarationName(&IsValidLineVectorII); - // Create a ConceptDecl - clang::ConceptDecl *conceptDecl = clang::ConceptDecl::Create( - context, - context.getTranslationUnitDecl(), // DeclContext - NameLoc, // Source location of start of concept - DeclName, // Source location of end of concept - ConceptParams, // Template type parameter - ConstraintExpr // Expression defining the concept - ); - - // Attach the template parameter list to the ConceptDecl - conceptDecl->setTemplateParameters(ConceptParams); - - // Add the concept declaration to the Translation Unit Decl - context.getTranslationUnitDecl()->addDecl(conceptDecl); - - return conceptDecl; - } - - ConceptSpecializationExpr *getConceptSpecializationExpr(Sema &S) { + ConceptSpecializationExpr *getConceptSpecializationExpr(Sema &S, ConceptDecl *CD) { ASTContext &context = S.getASTContext(); SourceLocation loc = Builder.Record->getBeginLoc(); - ConceptDecl *CD = getTypedBufferConceptDecl(S, Builder.Record); DeclarationNameInfo DNI(CD->getDeclName(), loc); NestedNameSpecifierLoc NNS; DeclContext *DC = Builder.Record->getDeclContext(); @@ -509,10 +397,10 @@ struct TemplateParameterListBuilder { return CSE; } - BuiltinTypeDeclBuilder &finalizeTemplateArgs() { + BuiltinTypeDeclBuilder &finalizeTemplateArgs(ConceptDecl *CD) { if (Params.empty()) return Builder; - ConceptSpecializationExpr *CSE = getConceptSpecializationExpr(S); + ConceptSpecializationExpr *CSE = CD ? getConceptSpecializationExpr(S, CD) : nullptr; auto *ParamList = TemplateParameterList::Create(S.Context, SourceLocation(), SourceLocation(), Params, @@ -550,12 +438,12 @@ BuiltinTypeDeclBuilder::addTemplateArgumentList(Sema &S) { BuiltinTypeDeclBuilder & BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, - ArrayRef<StringRef> Names) { + ArrayRef<StringRef> Names, ConceptDecl *CD = nullptr) { TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) Builder.addTypeParameter(Name); - return Builder.finalizeTemplateArgs(); + return Builder.finalizeTemplateArgs(CD); } HLSLExternalSemaSource::~HLSLExternalSemaSource() {} @@ -666,10 +554,110 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, .addDefaultHandleConstructor(S, RC); } +BinaryOperator *getSizeOfLEQ16Expr(clang::ASTContext &context, + SourceLocation NameLoc, + TemplateTypeParmDecl *T) { + // Obtain the QualType for 'unsigned long' + clang::QualType unsignedLongType = context.UnsignedLongTy; + + // Create a QualType that points to this TemplateTypeParmDecl + clang::QualType TType = context.getTypeDeclType(T); + + // Create a TypeSourceInfo for the template type parameter 'T' + clang::TypeSourceInfo *TTypeSourceInfo = + context.getTrivialTypeSourceInfo(TType, NameLoc); + + clang::UnaryExprOrTypeTraitExpr *sizeOfExpr = new (context) + clang::UnaryExprOrTypeTraitExpr(clang::UETT_SizeOf, TTypeSourceInfo, + unsignedLongType, NameLoc, NameLoc); + + // Create an IntegerLiteral for the value '16' with size type + clang::QualType sizeType = context.getSizeType(); + llvm::APInt sizeValue = llvm::APInt(context.getTypeSize(sizeType), 16); + clang::IntegerLiteral *sizeLiteral = new (context) + clang::IntegerLiteral(context, sizeValue, sizeType, NameLoc); + + clang::QualType BoolTy = context.BoolTy; + + clang::BinaryOperator *binaryOperator = clang::BinaryOperator::Create( + context, sizeOfExpr, // Left-hand side expression + sizeLiteral, // Right-hand side expression + clang::BO_LE, // Binary operator kind (<=) + BoolTy, // Result type (bool) + clang::VK_LValue, // Value kind + clang::OK_Ordinary, // Object kind + NameLoc, // Source location of operator + FPOptionsOverride()); + + return binaryOperator; +} + +Expr *getTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, + TemplateTypeParmDecl *T) { + clang::ASTContext &context = S.getASTContext(); + + // first get the "sizeof(T) <= 16" expression, as a binary operator + BinaryOperator *sizeOfLEQ16 = getSizeOfLEQ16Expr(context, NameLoc, T); + // TODO: add the '__builtin_hlsl_is_line_vector_layout_compatible' builtin + // and return a binary operator that evaluates the builtin on the given + // template type parameter 'T' + return sizeOfLEQ16; +} + +ConceptDecl *getTypedBufferConceptDecl(Sema &S) { + DeclContext *DC = S.CurContext; + clang::ASTContext &context = S.getASTContext(); + SourceLocation DeclLoc = SourceLocation(); + + IdentifierInfo &IsValidLineVectorII = + context.Idents.get("is_valid_line_vector"); + IdentifierInfo &ElementTypeII = + context.Idents.get("element_type"); + clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( + context, context.getTranslationUnitDecl(), DeclLoc, DeclLoc, + /*depth=*/0, + /*position=*/0, + /*id=*/&ElementTypeII, + /*Typename=*/true, + /*ParameterPack=*/false); + + T->setDeclContext(DC); + T->setReferenced(); + + // Create and Attach Template Parameter List to ConceptDecl + llvm::ArrayRef<NamedDecl *> TemplateParams = {T}; + clang::TemplateParameterList *ConceptParams = + clang::TemplateParameterList::Create(context, DeclLoc, DeclLoc, + TemplateParams, DeclLoc, nullptr); + + DeclarationName DeclName = DeclarationName(&IsValidLineVectorII); + Expr *ConstraintExpr = getTypedBufferConstraintExpr(S, DeclLoc, T); + + // Create a ConceptDecl + clang::ConceptDecl *conceptDecl = clang::ConceptDecl::Create( + context, + context.getTranslationUnitDecl(), // DeclContext + DeclLoc, // Source location of start of concept + DeclName, // Source location of end of concept + ConceptParams, // Template type parameter + ConstraintExpr // Expression defining the concept + ); + + // Attach the template parameter list to the ConceptDecl + conceptDecl->setTemplateParameters(ConceptParams); + + // Add the concept declaration to the Translation Unit Decl + context.getTranslationUnitDecl()->addDecl(conceptDecl); + + return conceptDecl; +} + void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; + ConceptDecl *CD = getTypedBufferConceptDecl(*SemaPtr); + Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams(*SemaPtr, {"element_type"}) + .addSimpleTemplateParams(*SemaPtr, {"element_type"}, CD) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { >From f6ec52c31be98dbc4f6121d6f921cf27af5010fa Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 16 Oct 2024 13:42:13 -0700 Subject: [PATCH 10/14] clang format --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index a5f41e23cb7abe..5863c8df955479 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -300,8 +300,8 @@ struct BuiltinTypeDeclBuilder { } TemplateParameterListBuilder addTemplateArgumentList(Sema &S); - BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S, - ArrayRef<StringRef> Names, ConceptDecl *CD); + BuiltinTypeDeclBuilder & + addSimpleTemplateParams(Sema &S, ArrayRef<StringRef> Names, ConceptDecl *CD); BuiltinTypeDeclBuilder &addConceptSpecializationExpr(Sema &S); }; @@ -309,7 +309,6 @@ struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &Builder; Sema &S; llvm::SmallVector<NamedDecl *> Params; - TemplateParameterListBuilder(Sema &S, BuiltinTypeDeclBuilder &RB) : Builder(RB), S(S) {} @@ -335,9 +334,10 @@ struct TemplateParameterListBuilder { Decl->setReferenced(); Params.emplace_back(Decl); return *this; - } + } - ConceptSpecializationExpr *getConceptSpecializationExpr(Sema &S, ConceptDecl *CD) { + ConceptSpecializationExpr *getConceptSpecializationExpr(Sema &S, + ConceptDecl *CD) { ASTContext &context = S.getASTContext(); SourceLocation loc = Builder.Record->getBeginLoc(); DeclarationNameInfo DNI(CD->getDeclName(), loc); @@ -400,7 +400,8 @@ struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &finalizeTemplateArgs(ConceptDecl *CD) { if (Params.empty()) return Builder; - ConceptSpecializationExpr *CSE = CD ? getConceptSpecializationExpr(S, CD) : nullptr; + ConceptSpecializationExpr *CSE = + CD ? getConceptSpecializationExpr(S, CD) : nullptr; auto *ParamList = TemplateParameterList::Create(S.Context, SourceLocation(), SourceLocation(), Params, @@ -436,9 +437,8 @@ BuiltinTypeDeclBuilder::addTemplateArgumentList(Sema &S) { return TemplateParameterListBuilder(S, *this); } -BuiltinTypeDeclBuilder & -BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, - ArrayRef<StringRef> Names, ConceptDecl *CD = nullptr) { +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addSimpleTemplateParams( + Sema &S, ArrayRef<StringRef> Names, ConceptDecl *CD = nullptr) { TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) Builder.addTypeParameter(Name); @@ -611,8 +611,7 @@ ConceptDecl *getTypedBufferConceptDecl(Sema &S) { IdentifierInfo &IsValidLineVectorII = context.Idents.get("is_valid_line_vector"); - IdentifierInfo &ElementTypeII = - context.Idents.get("element_type"); + IdentifierInfo &ElementTypeII = context.Idents.get("element_type"); clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( context, context.getTranslationUnitDecl(), DeclLoc, DeclLoc, /*depth=*/0, >From ed2bd244fee8bfffeaa9f67c716a6df8c0b78adb Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 16 Oct 2024 14:52:44 -0700 Subject: [PATCH 11/14] fix / add test cases --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 28 ++++++++++--------- clang/test/AST/HLSL/RWBuffer-AST.hlsl | 20 +++++++++++-- clang/test/AST/HLSL/StructuredBuffer-AST.hlsl | 4 +-- clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl | 15 ++++++++-- .../SemaHLSL/BuiltIns/StructuredBuffers.hlsl | 4 +-- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 5863c8df955479..b2d5413f7971a9 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -341,10 +341,11 @@ struct TemplateParameterListBuilder { ASTContext &context = S.getASTContext(); SourceLocation loc = Builder.Record->getBeginLoc(); DeclarationNameInfo DNI(CD->getDeclName(), loc); - NestedNameSpecifierLoc NNS; + NestedNameSpecifierLoc NNSLoc; DeclContext *DC = Builder.Record->getDeclContext(); TemplateArgumentListInfo TALI(loc, loc); + // assume that the concept decl has just one template parameter TemplateTypeParmDecl *ConceptTTPD = dyn_cast<TemplateTypeParmDecl>( CD->getTemplateParameters()->getParam(0)); @@ -363,11 +364,11 @@ struct TemplateParameterListBuilder { T->setDeclContext(DC); T->setReferenced(); - clang::QualType TType = context.getTypeDeclType(ConceptTTPD); + clang::QualType ConceptTType = context.getTypeDeclType(ConceptTTPD); - TemplateArgument TA = TemplateArgument(TType); + TemplateArgument ConceptTA = TemplateArgument(ConceptTType); - ArrayRef<TemplateArgument> ConvertedArgs = {TA}; + ArrayRef<TemplateArgument> ConceptConvertedArgs = {ConceptTA}; clang::QualType CSETType = context.getTypeDeclType(T); @@ -375,24 +376,25 @@ struct TemplateParameterListBuilder { ArrayRef<TemplateArgument> CSEConvertedArgs = {CSETA}; - ImplicitConceptSpecializationDecl *IDecl = + ImplicitConceptSpecializationDecl *ImplicitCSEDecl = ImplicitConceptSpecializationDecl::Create( context, Builder.Record->getDeclContext(), loc, CSEConvertedArgs); - const ConstraintSatisfaction CS(CD, ConvertedArgs); - TemplateArgumentLoc tal = - S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()); + const ConstraintSatisfaction CS(CD, ConceptConvertedArgs); + TemplateArgumentLoc TAL = S.getTrivialTemplateArgumentLoc( + ConceptTA, QualType(), SourceLocation()); - TALI.addArgument(tal); + TALI.addArgument(TAL); const ASTTemplateArgumentListInfo *ATALI = ASTTemplateArgumentListInfo::Create(context, TALI); - // In CR, ATALI is what adds the extra TemplateArgument node underneath CSE - ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNS, loc, - DNI, CD, CD, ATALI); + // In the concept reference, ATALI is what adds the extra + // TemplateArgument node underneath CSE + ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNSLoc, + loc, DNI, CD, CD, ATALI); ConceptSpecializationExpr *CSE = - ConceptSpecializationExpr::Create(context, CR, IDecl, &CS); + ConceptSpecializationExpr::Create(context, CR, ImplicitCSEDecl, &CS); return CSE; } diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl index e6ce73dbd962f7..b60519e803bb79 100644 --- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl @@ -11,7 +11,15 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> referenced typename depth 0 index 0 element_type +// EMPTY-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'bool' Concept 0x{{[0-9A-Fa-f]+}} 'is_valid_line_vector' +// EMPTY-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> +// EMPTY-NEXT: TemplateArgument type 'type-parameter-0-0' +// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' +// EMPTY-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' +// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -25,7 +33,15 @@ RWBuffer<float> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> referenced typename depth 0 index 0 element_type +// CHECK-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'bool' Concept 0x{{[0-9A-Fa-f]+}} 'is_valid_line_vector' +// CHECK-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> +// CHECK-NEXT: TemplateArgument type 'type-parameter-0-0' +// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' +// CHECK-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' +// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl index 030fcfc31691dc..14784b5abb60b7 100644 --- a/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl @@ -12,7 +12,7 @@ // instantiated specialization. // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit StructuredBuffer -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> referenced typename depth 0 index 0 element_type // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class StructuredBuffer // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final @@ -26,7 +26,7 @@ StructuredBuffer<float> Buffer; #endif // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit StructuredBuffer -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> referenced typename depth 0 index 0 element_type // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class StructuredBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl index 76b5d01b8036eb..9880b643852a20 100644 --- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl @@ -5,13 +5,24 @@ typedef vector<float, 3> float3; RWBuffer<float3> Buffer; // expected-error@+2 {{class template 'RWBuffer' requires template arguments}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires is_valid_line_vector<element_type> class RWBuffer {}}} RWBuffer BufferErr1; // expected-error@+2 {{too few template arguments for class template 'RWBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires is_valid_line_vector<element_type> class RWBuffer {}}} RWBuffer<> BufferErr2; +struct threeDoubles { + double a; + double b; + double c; +}; + +// expected-error@+3 {{constraints not satisfied for class template 'RWBuffer'}} +// expected-note@*:* {{because 'threeDoubles' does not satisfy 'is_valid_line_vector'}} +// expected-note@*:* {{because 'sizeof(threeDoubles) <= 16UL' (24 <= 16) evaluated to false}} +RWBuffer<threeDoubles> BufferErr3; + [numthreads(1,1,1)] void main() { (void)Buffer.h; // expected-error {{'h' is a private member of 'hlsl::RWBuffer<vector<float, 3>>'}} diff --git a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl index a472d5519dc51f..552624f13ee5f8 100644 --- a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl @@ -5,11 +5,11 @@ typedef vector<float, 3> float3; StructuredBuffer<float3> Buffer; // expected-error@+2 {{class template 'StructuredBuffer' requires template arguments}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class StructuredBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> class StructuredBuffer {}}} StructuredBuffer BufferErr1; // expected-error@+2 {{too few template arguments for class template 'StructuredBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class StructuredBuffer}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> class StructuredBuffer {}}} StructuredBuffer<> BufferErr2; [numthreads(1,1,1)] >From 64e565aa51e3853f719c5de0607d8742bd3283c3 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 17 Oct 2024 11:03:52 -0700 Subject: [PATCH 12/14] add default nullptr, remove comments --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index b2d5413f7971a9..3fa764808bcefc 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -313,7 +313,7 @@ struct TemplateParameterListBuilder { TemplateParameterListBuilder(Sema &S, BuiltinTypeDeclBuilder &RB) : Builder(RB), S(S) {} - ~TemplateParameterListBuilder() { finalizeTemplateArgs(nullptr); } + ~TemplateParameterListBuilder() { finalizeTemplateArgs(); } TemplateParameterListBuilder & addTypeParameter(StringRef Name, QualType DefaultValue = QualType()) { @@ -399,7 +399,7 @@ struct TemplateParameterListBuilder { return CSE; } - BuiltinTypeDeclBuilder &finalizeTemplateArgs(ConceptDecl *CD) { + BuiltinTypeDeclBuilder &finalizeTemplateArgs(ConceptDecl *CD = nullptr) { if (Params.empty()) return Builder; ConceptSpecializationExpr *CSE = @@ -636,13 +636,8 @@ ConceptDecl *getTypedBufferConceptDecl(Sema &S) { // Create a ConceptDecl clang::ConceptDecl *conceptDecl = clang::ConceptDecl::Create( - context, - context.getTranslationUnitDecl(), // DeclContext - DeclLoc, // Source location of start of concept - DeclName, // Source location of end of concept - ConceptParams, // Template type parameter - ConstraintExpr // Expression defining the concept - ); + context, context.getTranslationUnitDecl(), DeclLoc, DeclName, + ConceptParams, ConstraintExpr); // Attach the template parameter list to the ConceptDecl conceptDecl->setTemplateParameters(ConceptParams); >From 83cd7f9277b29ceac90c6be2f3196b6a5896c46f Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 17 Oct 2024 16:18:52 -0700 Subject: [PATCH 13/14] remove unused var, use vector to extend memory lifetime, may need to extend further --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 3fa764808bcefc..895db454c3cf46 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -368,13 +368,15 @@ struct TemplateParameterListBuilder { TemplateArgument ConceptTA = TemplateArgument(ConceptTType); - ArrayRef<TemplateArgument> ConceptConvertedArgs = {ConceptTA}; + std::vector<TemplateArgument> ConceptConvertedArgsVec = {ConceptTA}; + ArrayRef<TemplateArgument> ConceptConvertedArgs = ConceptConvertedArgsVec; clang::QualType CSETType = context.getTypeDeclType(T); TemplateArgument CSETA = TemplateArgument(CSETType); - ArrayRef<TemplateArgument> CSEConvertedArgs = {CSETA}; + std::vector<TemplateArgument> CSEConvertedArgsVec = {CSETA}; + ArrayRef<TemplateArgument> CSEConvertedArgs = CSEConvertedArgsVec; ImplicitConceptSpecializationDecl *ImplicitCSEDecl = ImplicitConceptSpecializationDecl::Create( @@ -426,9 +428,6 @@ struct TemplateParameterListBuilder { QualType T = Builder.Template->getInjectedClassNameSpecialization(); T = S.Context.getInjectedClassNameType(Builder.Record, T); - ArrayRef<TemplateArgument> TempArgs = - Builder.Template->getInjectedTemplateArgs(); - return Builder; } }; @@ -626,7 +625,9 @@ ConceptDecl *getTypedBufferConceptDecl(Sema &S) { T->setReferenced(); // Create and Attach Template Parameter List to ConceptDecl - llvm::ArrayRef<NamedDecl *> TemplateParams = {T}; + std::vector<NamedDecl *> TemplateParamsVec = {T}; + llvm::ArrayRef<NamedDecl *> TemplateParams(TemplateParamsVec); + clang::TemplateParameterList *ConceptParams = clang::TemplateParameterList::Create(context, DeclLoc, DeclLoc, TemplateParams, DeclLoc, nullptr); >From 12e72b462f2fa516ba19870950791092c86a3b1e Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 18 Oct 2024 00:33:43 -0700 Subject: [PATCH 14/14] address everything --- clang/lib/AST/DeclTemplate.cpp | 6 +- clang/lib/Sema/HLSLExternalSemaSource.cpp | 67 ++++++++++++++--------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 515abb3f68b244..d2d8907b884ec8 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1078,10 +1078,10 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, TemplateParameterList *Params, Expr *ConstraintExpr) { bool Invalid = AdoptTemplateParameterList(Params, DC); - auto *CD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); + auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); if (Invalid) - CD->setInvalidDecl(); - return CD; + TD->setInvalidDecl(); + return TD; } ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 895db454c3cf46..5126657ab0c29d 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -336,22 +336,41 @@ struct TemplateParameterListBuilder { return *this; } + /* + The desired result AST after this function constructs the concept + specialization Expression is as follows: + + |-ConceptSpecializationExpr 0xdd5d408 <col:42, col:75> 'bool' Concept + 0xdd5d1c0 'is_valid_line_vector' | |-ImplicitConceptSpecializationDecl + 0xdd5d350 <line:5:9> col:9 | | `-TemplateArgument type 'type-parameter-0-0' | + | `-TemplateTypeParmType 0xdb90ba0 'type-parameter-0-0' dependent depth 0 + index 0 | `-TemplateArgument <line:8:63> type + 'element_type':'type-parameter-0-0' | `-TemplateTypeParmType 0xdd5d2f0 + 'element_type' dependent depth 0 index 0 | `-TemplateTypeParm 0xdd5d298 + 'element_type' + */ ConceptSpecializationExpr *getConceptSpecializationExpr(Sema &S, ConceptDecl *CD) { - ASTContext &context = S.getASTContext(); - SourceLocation loc = Builder.Record->getBeginLoc(); - DeclarationNameInfo DNI(CD->getDeclName(), loc); + ASTContext &Context = S.getASTContext(); + SourceLocation Loc = Builder.Record->getBeginLoc(); + DeclarationNameInfo DNI(CD->getDeclName(), Loc); NestedNameSpecifierLoc NNSLoc; DeclContext *DC = Builder.Record->getDeclContext(); - TemplateArgumentListInfo TALI(loc, loc); + TemplateArgumentListInfo TALI(Loc, Loc); - // assume that the concept decl has just one template parameter + // Assume that the concept decl has just one template parameter + // This parameter should have been added when CD was constructed + // in getTypedBufferConceptDecl + assert(CD->getTemplateParameters()->size() == 1 && + "unexpected concept decl parameter count"); TemplateTypeParmDecl *ConceptTTPD = dyn_cast<TemplateTypeParmDecl>( CD->getTemplateParameters()->getParam(0)); + // this fake TemplateTypeParmDecl is used to construct a template argument + // that will be used to construct the ImplicitConceptSpecializationDecl clang::TemplateTypeParmDecl *T = clang::TemplateTypeParmDecl::Create( - context, // AST context - context.getTranslationUnitDecl(), // DeclContext + Context, // AST context + Context.getTranslationUnitDecl(), // DeclContext SourceLocation(), SourceLocation(), /*depth=*/0, // Depth in the template parameter list /*position=*/0, // Position in the template parameter list @@ -364,39 +383,38 @@ struct TemplateParameterListBuilder { T->setDeclContext(DC); T->setReferenced(); - clang::QualType ConceptTType = context.getTypeDeclType(ConceptTTPD); + clang::QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD); + // this is the 2nd template argument node in the AST above TemplateArgument ConceptTA = TemplateArgument(ConceptTType); - std::vector<TemplateArgument> ConceptConvertedArgsVec = {ConceptTA}; - ArrayRef<TemplateArgument> ConceptConvertedArgs = ConceptConvertedArgsVec; - - clang::QualType CSETType = context.getTypeDeclType(T); + clang::QualType CSETType = Context.getTypeDeclType(T); + // this is the 1st template argument node in the AST above TemplateArgument CSETA = TemplateArgument(CSETType); - std::vector<TemplateArgument> CSEConvertedArgsVec = {CSETA}; - ArrayRef<TemplateArgument> CSEConvertedArgs = CSEConvertedArgsVec; - ImplicitConceptSpecializationDecl *ImplicitCSEDecl = ImplicitConceptSpecializationDecl::Create( - context, Builder.Record->getDeclContext(), loc, CSEConvertedArgs); + Context, Builder.Record->getDeclContext(), Loc, {CSETA}); - const ConstraintSatisfaction CS(CD, ConceptConvertedArgs); + // Constraint satisfaction is used to construct the + // ConceptSpecailizationExpr, and represents the 2nd Template Argument, + // located at the bottom of the sample AST above. + const ConstraintSatisfaction CS(CD, {ConceptTA}); TemplateArgumentLoc TAL = S.getTrivialTemplateArgumentLoc( ConceptTA, QualType(), SourceLocation()); TALI.addArgument(TAL); const ASTTemplateArgumentListInfo *ATALI = - ASTTemplateArgumentListInfo::Create(context, TALI); + ASTTemplateArgumentListInfo::Create(Context, TALI); // In the concept reference, ATALI is what adds the extra // TemplateArgument node underneath CSE - ConceptReference *CR = ConceptReference::Create(S.getASTContext(), NNSLoc, - loc, DNI, CD, CD, ATALI); + ConceptReference *CR = + ConceptReference::Create(Context, NNSLoc, Loc, DNI, CD, CD, ATALI); ConceptSpecializationExpr *CSE = - ConceptSpecializationExpr::Create(context, CR, ImplicitCSEDecl, &CS); + ConceptSpecializationExpr::Create(Context, CR, ImplicitCSEDecl, &CS); return CSE; } @@ -625,12 +643,9 @@ ConceptDecl *getTypedBufferConceptDecl(Sema &S) { T->setReferenced(); // Create and Attach Template Parameter List to ConceptDecl - std::vector<NamedDecl *> TemplateParamsVec = {T}; - llvm::ArrayRef<NamedDecl *> TemplateParams(TemplateParamsVec); - clang::TemplateParameterList *ConceptParams = - clang::TemplateParameterList::Create(context, DeclLoc, DeclLoc, - TemplateParams, DeclLoc, nullptr); + clang::TemplateParameterList::Create(context, DeclLoc, DeclLoc, {T}, + DeclLoc, nullptr); DeclarationName DeclName = DeclarationName(&IsValidLineVectorII); Expr *ConstraintExpr = getTypedBufferConstraintExpr(S, DeclLoc, T); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits