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

On further investigation, yes I believe it is being placed into the AST. I 
didn't realize that setting the DeclContext correlated with AST placement. 
However, comparing the generated AST with similar C++ code, I do think the 
declaration context for this template type parm decl is correct. (That is, the 
context is the ClassTemplateDecl, and it shows up directly indented under the 
ClassTemplateDecl in the AST.

I've added tests for the concept declaration AST.

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

Reply via email to