dang marked an inline comment as done.
dang added inline comments.

================
Comment at: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp:510
   Symbols.emplace_back(std::move(*Obj));
+  PathComponentContext.pop_back();
 }
----------------
QuietMisdreavus wrote:
> dang wrote:
> > dang wrote:
> > > zixuw wrote:
> > > > zixuw wrote:
> > > > > QuietMisdreavus wrote:
> > > > > > zixuw wrote:
> > > > > > > What's the cost/would it worth it to wrap the `emplace_back`s and 
> > > > > > > `pop_back`s of `PathComponentContext` in meaningful APIs like 
> > > > > > > `enterPathComponentContext` and `exitPathComponentContext`?
> > > > > > > That way the code is more self-explanatory and easier to read. It 
> > > > > > > took me some time and mental resources to figure out why the 
> > > > > > > `pop_back` is placed here.
> > > > > > What's the use of having the `emplace_back` call inside 
> > > > > > `serializeAPIRecord` but to pop it outside? It seems like it's 
> > > > > > easier to mess up for new kinds of records.
> > > > > The reason to `emplace_back` the path component inside 
> > > > > `serializeAPIRecord` is that the `pathComponent` field of the 
> > > > > `Record` is serialized in there so you want to include the name of 
> > > > > the symbol itself in the path component list.
> > > > > The `pop_back` is delayed til all other additional serialization for 
> > > > > a specific kind of record, for example `serializeEnumRecord` handles 
> > > > > all the enum cases after processing the enum record itself using 
> > > > > `serializeAPIRecord`. So in order to correctly include the enum name 
> > > > > in the path components of all the enum cases, the enum name has to 
> > > > > stay in `PathComponentContext` until all members are serialized.
> > > > > 
> > > > > This is exactly the reason why I wanted a clearer API to make it 
> > > > > easier to see.
> > > > Hmm now that I thought about this, it seems that it would be easier to 
> > > > understand and avoid bugs if we lift 
> > > > `PathComponentContext.emplace_back`/`enterPathComponentContext` out of 
> > > > `serializeAPIRecord`, because we have access to the record name before 
> > > > that anyway.
> > > > 
> > > > So we establish a pre-condition of `serializeAPIRecord` that the 
> > > > correct path components would be set up in `PathComponentContext` 
> > > > before the call so we could still serialize the field inside that 
> > > > method. And in specific `serialize*Record` methods we push the record 
> > > > name, and pop out at the end.
> > > > 
> > > > This way the push and pop operations would appear in pairs in a single 
> > > > block, saving the confusion and mental work of jumping across functions 
> > > > to see how `PathComponentContext` is evolving.
> > > If you think we should have a specialized API I am happy to do this. I 
> > > figured it was self-explanatory by the name of `PathComponentContext` but 
> > > it clearly isn't so needs addressing. I put the `emplace_back` call in 
> > > `serializeAPIRecord` since all the specific serialization methods call 
> > > it. I thought it would make it impossible to forget to add them. @zixuw 
> > > is correct in the reason why the pop is outside we don't want to pop 
> > > before we have serialized the sub records by agree it is ugly and 
> > > potentially error prone. I can see three ways forward for improving the 
> > > ergonomics of this since this seems to be problematic:
> > > - Provide `serializeAPIRecord` a continuation to serialize the sub 
> > > records or additional fields, that way we can move the pop inside 
> > > `serializeAPIRecord` I am not a fan personally because we get into JS 
> > > style closure hell if we start doing this...
> > > - Use a visitor pattern where the visitor would be responsible for 
> > > managing `PathComponentContext` and do the appropriate push/pops in the 
> > > `visit` methods. We would need to add a APIRecordVisitor type, and 
> > > appropriate visit methods for each APIRecord. This would make sense 
> > > because the records should really know how to visit themselves.
> > > - Just add a specialized API although it seems it would really easy to 
> > > forget to remove path components.
> > > 
> > > Let me know what you think is the way forward.
> > Unless we go with the last option, I think this should be a follow up patch 
> > since it would a structural change.
> I'm most a fan of the `APIRecordVisitor` option, but you're right in that 
> that would be a rather involved change. Now that you've said that the 
> arrangement is for encoding sub-records, it makes sense to me. As an 
> alternative, i think moving the `emplace_back` outside of 
> `serializeAPIRecord` is actually my other preferred arrangement; without some 
> other way of calculating the path components on-the-fly (e.g. walking up 
> DeclContexts) simply having `serializeAPIRecord` look at what's there and 
> have the wrapper calls deal with setting up its state sounds the most 
> reasonable to me. That way, as @zixuw said, the `emplace_back` and `pop_back` 
> calls are at least lexically close to each other.
Let's move to a visitor based implementation later as a follow up patch since 
it is quite a big structural change. For now, I have implemented managing path 
components using RAII to avoid issues around forgetting to pop when returning 
early for skipped records.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123045

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

Reply via email to