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 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits