This is an archive of the discontinued LLVM Phabricator instance.

[SyntaxTree] Expand support for `NestedNameSpecifier`
ClosedPublic

Authored by eduucaldas on Aug 6 2020, 8:57 AM.

Details

Reviewers
gribozavr2
Summary

We want NestedNameSpecifier syntax nodes to be generally supported, not
only for DeclRefExpr and DependentScopedDeclRefExpr.

To achieve this we:

  • Use the RecursiveASTVisitor's API to traverse NestedNameSpecifierLocs and automatically create its syntax nodes
  • Add links from the NestedNameSpecifierLocs to their syntax nodes.

In this way, from any semantic construct that has a NestedNameSpecifier,
we implicitly generate its syntax node via RAV and we can easily access
this syntax node via the links we added.

This diff revision is based on This diff revision is based on https://reviews.llvm.org/D84781

Closed by https://reviews.llvm.org/rGf9500cc487573c55ea37b4ee6e9162d115753a48

Diff Detail

Event Timeline

eduucaldas created this revision.Aug 6 2020, 8:57 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 6 2020, 8:57 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
eduucaldas requested review of this revision.Aug 6 2020, 8:57 AM
eduucaldas edited the summary of this revision. (Show Details)Aug 6 2020, 9:03 AM
eduucaldas edited the summary of this revision. (Show Details)
eduucaldas added inline comments.
clang/lib/Tooling/Syntax/BuildTree.cpp
227–254

Inpired on the definition of:

  • template<typename T> struct DenseMapInfo<T*>
  • template<typename T, typename U> struct DenseMapInfo<std::pair<T,U>>

Please tell me if this is all silly.

clang/unittests/Tooling/Syntax/TreeTest.cpp
1224–1225

standard TraverseNestedNameSpecifierLoc fired TraverseTypeLoc, once we override it we lost this. This will be fixed when refining the Node for DecltypeSpecifier

gribozavr2 accepted this revision.Aug 7 2020, 6:03 AM
gribozavr2 added inline comments.
clang/lib/Tooling/Syntax/BuildTree.cpp
227–254

This is the right way to use DenseMapInfo, just move the specialization into the file that defines NNSLoc.

794–868

Please add a comment that explains why we override Traverse for NNSLoc instead of WalkUpFrom.

Something like:

To build syntax tree nodes for NestedNameSpecifierLoc we override Traverse instead of WalkUpFrom because we want to traverse the children ourselves and build a list instead of a nested tree of name specifier prefixes.

This revision is now accepted and ready to land.Aug 7 2020, 6:03 AM

Move to using inheritance

eduucaldas marked 2 inline comments as done.Aug 10 2020, 2:41 AM

Now NNS are based on inheritance!

clang/lib/Tooling/Syntax/BuildTree.cpp
849–850

Since we are overriding the TraverseNestedNameSpecifierLoc that previously fired TraverseTypeLoc we fire it when building a NameSpecifier.

clang/unittests/Tooling/Syntax/TreeTest.cpp
1224–1225

This is no longer an issue, because we now fire TraverseTypeLoc in the case of DecltypeNameSpecifier

gribozavr2 accepted this revision.Aug 10 2020, 4:12 AM
gribozavr2 added inline comments.
clang/include/clang/AST/NestedNameSpecifier.h
20
534

I'd suggest to remove the comment because it repeats the API (this is the only reason to define a DenseMapInfo specialization).

539

Inline is implied here.

544

Inline is implied here.

550

Please use hash_combine instead of this internal API (see an example in include/clang/Sema/Sema.h).

clang/lib/Tooling/Syntax/BuildTree.cpp
770

There are some refinements to do, to generate a complete syntax tree. Namely tag decltype-name-specifier and simple-template-specifier children with roles, to allow for accessors.

clang/lib/Tooling/Syntax/BuildTree.cpp
838–842

Let's generate the syntax tree for the nested-name-specifier:

T::template U<int>::X::

T and X are just identifier-name-specifiers. They are easy.

template U<int> however is a simple-template-name-specifier.

simple-template-name-specifier :
  template_opt simple-template-id

We could generate it by traversing the corresponding semantic node. But this node is a DependentTemplateSpecializationTypeLoc and it covers T::template U<int>. The traversal would then cover T:: and thus generate a crash.

As such, we should treat simple-template-name-specifier in a less generic way.

849–850

As opposed to simple-template-name-specifier, we can here use a normal traversal to build the decltype-name-specifier because this specifier doesn't cross boundaries of name specifiers

eduucaldas marked 6 inline comments as done and 2 inline comments as done.

Answer comments

eduucaldas closed this revision.Sep 17 2020, 1:14 AM
eduucaldas edited the summary of this revision. (Show Details)