steveire marked an inline comment as done.
steveire added inline comments.
================
Comment at: include/clang/AST/TextNodeDumper.h:28
const comments::FullComment *> {
+ TextTreeStructure &TreeStructure;
raw_ostream &OS;
----------------
aaron.ballman wrote:
> steveire wrote:
> > aaron.ballman wrote:
> > > This makes me a bit wary because you create a node dumper in the same
> > > situations you make a tree structure object, but now there's a strict
> > > ordering between the two object creations. If you're doing this
> > > construction local to a function, you wind up with a dangling reference
> > > unless you're careful (which is unfortunate, but not the end of the
> > > world). If you're doing this construction as part of a constructor's
> > > initializer list, you now have to properly order the member declarations
> > > within the class and that is also unfortunate. Given that those are the
> > > two common scenarios for how I envision constructing an ast dump of some
> > > kind, I worry about the fragility. e.g.,
> > > ```
> > > unique_ptr<ASTConsumer> createASTDumper(...) {
> > > TextTreeStructure TreeStructure;
> > > TextNodeDumper NodeDumper(TreeStructure); // Oops, dangling reference
> > > return make_unique<MySuperAwesomeASTDumper>(TreeStructure, NodeDumper,
> > > ...);
> > > }
> > >
> > > // vs
> > >
> > > struct MySuperAwesomeASTDumper : ... {
> > > MySuperAwesomeASTDumper() : TreeStructure(...),
> > > NodeDumper(TreeStructure, ...) {}
> > > private:
> > > TextTreeStructure TreeStructure; // This order is now SUPER important
> > > TextNodeDumper NodeDumper;
> > > };
> > > ```
> > > There's a part of me that wonders if a better approach is to have this
> > > object passed to the `dumpFoo()` calls as a reference parameter. This
> > > way, the caller is still responsible for creating an object, but the
> > > creation order between the tree and the node dumper isn't as fragile.
> > In your first snippet there is a dangling reference because the author of
> > `MySuperAwesomeASTDumper` decided to make the members references. If the
> > members are references, code like your first snippet will cause dangling
> > references and nothing can prevent that. Adding `TreeStructure&` to Visit
> > methods as you suggested does not prevent it.
> >
> > The only solution is make the `MySuperAwesomeASTDumper` not use member
> > references (ie your second snippet). The order is then in fact not
> > problematic because "taking a reference to an uninitialized object is
> > legal".
> > The order is then in fact not problematic because "taking a reference to
> > an uninitialized object is legal".
>
> This presumes that the constructors aren't using those references to the
> uninitialized object, which would be illegal. That's what I mean about this
> being very fragile -- if the stars line up correctly, everything works fine,
> but if the stars aren't aligned just right, you get really hard problems to
> track down.
Actually 'the stars would have to line up in a particular way' in order to
reach the scenario you are concerned about. What would have to happen is:
* This patch gets in as-is
* Someone in the future reorders the members
* But they don't reorder the init-list
* They build on a platform without -Wreorder (only MSVC?) enabled in the build.
* That passes review
* Other users update their checkout and everyone else also ignores the
-Wreorder warning.
That is a vanishingly likely scenario. It's just unreasonable to consider that
as a reason to create a broken interface.
And it would be a broken interface.
After the refactoring is complete, we have something like
```
class ASTDumper
: public ASTDumpTraverser<ASTDumper, TextTreeStructure, TextNodeDumper> {
TextTreeStructure TreeStructure;
TextNodeDumper NodeDumper;
public:
TextTreeStructure &getTreeStructure() { return TreeStructure; }
TextNodeDumper &getNodeDumper() { return NodeDumper; }
ASTDumper(raw_ostream &OS, const SourceManager *SM)
: TreeStructure(OS),
NodeDumper(TreeStructure, OS, SM) {}
};
```
In the case, of the `ASTDumper`, the `TextNodeDumper` uses the
`TextTreeStructure`.
However, in the case of any other subclass of `ASTDumpTraverser`, the
`NodeDumper` type does not depend on the `TreeStructure` type. The
`ASTDumpTraverser` should not pass the `TreeStructure` to the
`NodeDumper`because the `ASTDumpTraverser` should not assume the `NodeDumper`
needs the `ASTDumpTraverser`.
That is true in one concrete case (the `TextNodeDumper`), but not in general.
You would be encoding an assumption about a concrete `NodeDumper`
implementation in the generic `ASTDumpTraverser`.
That is an interface violation which is definitely not justified by your
far-fetched scenario of someone re-ordering the members in the future and
ignoring `-Wreorder`.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55337/new/
https://reviews.llvm.org/D55337
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits