================ @@ -323,30 +324,127 @@ struct TemplateParameterListBuilder { S.Context, Builder.Record->getDeclContext(), SourceLocation(), SourceLocation(), /* TemplateDepth */ 0, Position, &S.Context.Idents.get(Name, tok::TokenKind::identifier), - /* Typename */ false, - /* ParameterPack */ false); + /* Typename */ true, + /* ParameterPack */ false, + /* HasTypeConstraint*/ false); if (!DefaultValue.isNull()) Decl->setDefaultArgument( S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), SourceLocation())); - Params.emplace_back(Decl); return *this; } - BuiltinTypeDeclBuilder &finalizeTemplateArgs() { + /* + The concept specialization expression (CSE) constructed below is constructed + so that it matches the CSE that is constructed when parsing + the below C++ code: + + template<typename T> + concept is_typed_resource_element_compatible =sizeof(T) <= 16; + + template<typename element_type> requires + is_typed_resource_element_compatible<element_type> + + struct RWBuffer { + element_type Val; + }; + + int fn() { + RWBuffer<int> Buf; + } + + When dumping the AST and filtering for "RWBuffer", the resulting AST + structure is what we're trying to construct below, specifically the + CSE portion. + */ + ConceptSpecializationExpr * + constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD) { + 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); + + // 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 ---------------- bob80905 wrote:
It isn't being placed into the AST, the sole reason for its existence is to allow a path to construct a TemplateArgument, and that TemplateArgument will actually be placed into the AST. The fake TemplateTypeParmDecl is otherwise unused and discarded. https://github.com/llvm/llvm-project/pull/112600 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits