This is an archive of the discontinued LLVM Phabricator instance.

[clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible
ClosedPublic

Authored by dang on Mar 22 2023, 12:17 PM.

Details

Summary

Use CRTP to enable creating statically dispatched subclasses of
ExtractAPIVisitor.
This enables adding extension points and customising the behavior more
easily.

This is used in CXExtractAPI.cpp to create a specialized visitor for
Libclang as well as streamlining the batch implementation in ExtractAPIConsumer.cpp

[clang][ExtractAPI] Improve tests for clang_getSymbolGraphForCursor

Adds a new mode to c-index-test that can fetch a single symbol symbol
graph for a given source location. This way we can be more precise when
writing tests for clang_getSymbolGraphForCursor.
Additionaly this makes it easier to debug the function.

Diff Detail

Event Timeline

dang created this revision.Mar 22 2023, 12:17 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 22 2023, 12:17 PM
dang requested review of this revision.Mar 22 2023, 12:17 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 22 2023, 12:17 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
bnbarham added inline comments.Mar 22 2023, 1:12 PM
clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
170 ↗(On Diff #507469)

Accidental?

clang/test/Index/extract-api-cursor.m
36–120

I personally like to put the run lines next to what's being checked and use [[@LINE+1]]. Up to you though

zixuw added a comment.Mar 22 2023, 1:15 PM

Good to see refactoring to make ExtractAPI easier to extend and use. Thanks Daniel!
Some comments on the ExtractAPIVisitor part. I'll leave the libclang part to the experts.

clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
32 ↗(On Diff #507469)

Would it be better to call this ExtractAPIVisitorImpl because it provides the visitor implementation, and the ExtractAPIVisitor is actually the base for the second level CRTP for actual visitors?

32 ↗(On Diff #507469)

Should this be : public RecursiveASTVisitor<ExtractAPIVisitorBase<Derived>> instead?

34 ↗(On Diff #507469)

Should the constructor be made protected for a CRTP base?

57 ↗(On Diff #507469)

Why does comment-fetching need to be dispatched?

102 ↗(On Diff #507469)

I see that the RecursiveASTVisitor already provides a getDerived() for the top-level CRTP.
My head is still bending trying to get a clear view of the multi-level CRTP here 🙃 , but I'm guessing that this is to avoid the conflict with that method.
In that case could we be more verbose to make clear the purpose of this one? I'm thinking something like getDerivedExtractAPIVisitor(), to communicate that this is for getting the derived/concrete ExtractAPIVisitor subclass.

clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
170 ↗(On Diff #507469)

Missed change?

228–234 ↗(On Diff #507469)

Couldn't find the original logic in this patch. Could you remind me what are these for? Also good to have more comments here to explain things.

zixuw added inline comments.Mar 22 2023, 1:18 PM
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
628 ↗(On Diff #507469)

Same as above, should the constructor be protected? I guess it depends if we want people to just instantiate and use a ExtractAPIVisitor.

dang added inline comments.Mar 22 2023, 3:47 PM
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
32 ↗(On Diff #507469)

I chose to name it "Base" as this seems to be the convention used for ADT, where they use the "Base" suffix for types clients shouldn't be using.

As with the base class, we need to provide RecursiveASTVisitor the most derived class so that when it does the getDerived() dance it can use the most derived methods.

34 ↗(On Diff #507469)

agreed

57 ↗(On Diff #507469)

This is for the libclang use case. If you request symbol graph data for a symbol in an implementation block for example you should get back the doc comment from the header. The main reason for doing this refactoring is so that we can avoid dynamic dispatch when doing source location lookups and now fetching documentation comments.

102 ↗(On Diff #507469)

Not fully sure myself, but I think that using the one from RecursiveASTVisitor would work fine here. I will give it a go and change it if it works.

628 ↗(On Diff #507469)

The aim was for clients to be able to instantiate this one, hence why we go through a fair amount of effort to provide base class the most derived type with the std::conditional_t usage above.

clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
170 ↗(On Diff #507469)

yup definitely accidental will fix.

228–234 ↗(On Diff #507469)

I moved this behavior out of the base type into here, we used to do these checks in the individual VisitXXX methods and bail early, but I needed this behavior to be configurable for the libclang work. I figured it semantically belonged here.

clang/test/Index/extract-api-cursor.m
36–120

Oh I didn't know about this that sounds like it's definitely more readable, will make the swap.

dang updated this revision to Diff 507543.Mar 22 2023, 4:24 PM

Addressing code review feedback

dang updated this revision to Diff 507544.Mar 22 2023, 4:25 PM

Adding back missing diffs.

LGTM for the ExtractAPIVisitor part.
Remaining:

  • update test with @LINE
  • the libclang side
dang added a comment.Mar 24 2023, 10:30 AM

LGTM for the ExtractAPIVisitor part.
Remaining:

  • update test with @LINE
  • the libclang side

I have decided against doing that, because we can't specify @LINE in the c-index-test command line.
@bnbarham are you happy with the libclang bits?

clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
102 ↗(On Diff #507469)

turns out it is needed but not sure why, I will rename to make things clearer.

clang/test/Index/extract-api-cursor.m
36–120

I tried it out and I actually struggled to follow along so I am leaving it as is.

bnbarham accepted this revision.Mar 24 2023, 10:35 AM
This revision is now accepted and ready to land.Mar 24 2023, 10:35 AM
zixuw accepted this revision.Mar 24 2023, 10:49 AM

I have decided against doing that, because we can't specify @LINE in the c-index-test command line.

FWIW you can do:

// RUN: .... -pos=%(line+1):7
let bar = Bar()
// CHECK ... [[@LINE-1]]:7

But I don't think this is particularly common, it's just how I write tests. What you have is perfectly reasonable 👍

This revision was landed with ongoing or failed builds.Mar 27 2023, 9:24 AM
This revision was automatically updated to reflect the committed changes.