Modify (and reparse) AST

Is there a way to “modify the source” and reparse the text during the AST TreeTransform process?

I am trying to make a local change that would fix the bug:

The idea would be to replace the nodes that are rendered as:

UnaryExprOrTypeTraitExpr 0x10c4f18 <col:41, col:55> ‘unsigned int’ sizeof
-ParenExpr 0x10c4f00 <col:47, col:55> '<dependent type>' lvalue -DependentScopeDeclRefExpr 0x10c4ed8 <col:48, col:51> ‘’ lvalue

UnaryExprOrTypeTraitExpr 0xf64f28 <col:41, col:64> ‘unsigned int’ sizeof ‘typename T::type’

simply by adding “typename” before the symbol, and then the parser would handle it correctly. and generate the correct UnaryExprOrTypeTraitExpr

Solutions I would accept include:

  1. Change the source and reprocess the file (a la “Fixit”), but this has a high overhead for large files/projects
  2. Ask the parser for the single Expr that would be generated from the new text
  3. A way to look up what the existing typename would be manually and create the expr manually.
  4. Other thing I’m too new to know about.


FYI: I’m trying to do this from the context of TransformUnaryExprOrTypeTraitExpr

Considering that MSVC rejects typename in places where it is required by the standard, I don’t think issuing fixits is appropriate if we assume that users still want to build with MSVC.

It’s way too late to go back and reparse with a new typename token by the time we reach instantiation. We’ve already done the first parse of the template, and now we’re transforming AST nodes.

I think we can probably add a hack for sizeof if we observe during instantiation that the sizeof expr is really operating on a DeclRefExpr that names a type and not a decl. Then we have to turn that DeclRefExpr into TypeSourceInfo, and I think we can rebuild a sizeof() expr that thinks it got a type. I’m not sure how to take apart a DeclRefExpr and go looking for types with that name.

Here’s my poor, not for commit, attempt to do this. It lets Clang accept sizeof without typename, but it crashes 72 existing tests.

t.diff (4.78 KB)

This is so incredibly helpful Reid, thank you.