hokein added inline comments.

================
Comment at: clang/include/clang/AST/RecursiveASTVisitor.h:1843
+  if (const auto *TC = D->getTypeConstraint()) {
+    TRY_TO(TraverseStmt(TC->getImmediatelyDeclaredConstraint()));
     TRY_TO(TraverseConceptReference(*TC));
----------------
nridge wrote:
> hokein wrote:
> > nridge wrote:
> > > hokein wrote:
> > > > Looks like we may visit some nodes in `ConceptReference` twice:
> > > > -  getImmediatelyDeclaredConstraint returns a 
> > > > `ConceptSpecializationExpr` (most cases?) which is a subclass of 
> > > > `ConceptReference`;
> > > > - `TraverseStmt(ConceptSpecializationExpr*)` will dispatch to 
> > > > `TraverseConceptSpecializationExpr` which invokes 
> > > > `TraverseConceptReference` (see Line 2719);
> > > > 
> > > > 
> > > > It is sad that we don't have enough test coverage, could you write some 
> > > > tests in `clang/unittests/Tooling/RecursiveASTVisitorTests/`?
> > > It is true that there will be two calls to `TraverseConceptReference()`. 
> > > However, they are called on two different `ConceptReference` objects:
> > > 
> > >   * the call in `TraverseConceptSpecializationExpr` will visit the base 
> > > subobject of the `ConceptSpecializationExpr` (which inherits from 
> > > `ConceptReference`)
> > >   * the call in `TraverseTemplateTypeParmDecl` will visit the base 
> > > subobject of the `TypeConstraint` (which also inherits from 
> > > `ConceptReference`).
> > > 
> > > So, I think this is fine -- there are two distinct `ConceptReference` 
> > > objects in the AST, and with this patch we visit both of them.
> > I understand that they are two different `ConceptReference` objects, but 
> > they have members (`FoundDecl`, `ArgsAsWritten`) that may refer to the same 
> > AST nodes.
> > 
> > ```
> > template <typename T, typename U>
> > concept binary_concept = true;
> > struct Foo {};
> > 
> > template<binary_concept<Foo> T> // the template argument Foo will be 
> > visited twice.
> > void k2();
> > ```
> > 
> > I'm not sure what's is the right approach here, I can see two options:
> > 
> > - traverse TC + immediately-declared-constraint expr, this seem to cause 
> > some ast nodes visited twice (maybe not a big deal?)
> > - just traverse immediately-declared-constraint expr, this seems not 
> > breaking any tests, but the immediately-declared-constraint expr could be 
> > nullptr (e.g. broken code, missing required template arguments); or the 
> > immediately-declared-constraint expr could be a `CXXFoldExpr`, which will 
> > make some members in `ConceptReference` not be visited;
> > 
> > @rsmith, do you have any idea about this?
> > 
> From clangd's point of view, it would be sufficient to visit the 
> immediately-declared-constraint-expr without visiting any of its descendants. 
> However, I'm not sure how to accomplish this using `RecursiveASTVisitor`. (I 
> think I'd want to call 
> `WalkUpFromXXX(TC->getImmediatelyDeclaredConstraint())`, where `XXX` is the 
> dynamic type of the immediately-delcared-constraint, but I don't know how to 
> dispatch to that dynamic type; `RecursiveASTVisitor` seems to be designed to 
> do the dispatch on `Traverse` calls, not `WalkUpFrom` calls).
Thinking more about this.

I'm aligned on the idea of only traversing the immediately declared constraint 
since the TypeContraint is a wrapper of it. The regression is that we'd not 
perform traversal if the immediately declared constraint is nullptr (this just 
happens for broken code). 

Fix ideas:
- build a recovery expression if we can't not build a immediately declared 
constraint due to the missing required template arguments etc;
- still traverse the TC if immediately declared constraint is nullptr;




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84136/new/

https://reviews.llvm.org/D84136

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to