Skip to content

vcg-ast#6556

Merged
MartinNowak merged 6 commits intodlang:masterfrom
UplinkCoder:cg_ast_ouput
Mar 11, 2017
Merged

vcg-ast#6556
MartinNowak merged 6 commits intodlang:masterfrom
UplinkCoder:cg_ast_ouput

Conversation

@UplinkCoder
Copy link
Member

@UplinkCoder UplinkCoder commented Feb 22, 2017

In order to debug the inliner I found a need to print the write-out AST after all semantic steps have been done (akin to gcc -E).

This is a developer tool and is therefore not covered by the test-suite.

@UplinkCoder UplinkCoder changed the title [WIP] first steps to vcg-ast vcg-ast Feb 22, 2017
@UplinkCoder UplinkCoder force-pushed the cg_ast_ouput branch 5 times, most recently from 0e5cd6f to 21154e2 Compare February 23, 2017 15:32
src/mars.d Outdated
-transition=? list all language changes
-unittest compile in unit tests
-v verbose
-vcg-ast generates .d.cg file with the ast right before obj-file generation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove from the help menu, it's an internal tool and I wouldn't want to commit to it too much.

src/mars.d Outdated
if(global.params.vcg_ast)
{
import ddmd.hdrgen;
foreach(mod;modules)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style, space after if and for

auto modFilenameLength = strlen(modFilename);
auto cgFilename = cast(char*)allocmemory(modFilenameLength + 4);
strcpy(cgFilename, modFilename);
cgFilename[modFilenameLength .. modFilenameLength + 4] = ".cg\0";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are path tools in root, look at other path manipulating code in mars.d.

Copy link
Member Author

@UplinkCoder UplinkCoder Feb 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a few lines above:

                assert(*ext == '.');
                newname = cast(char*)mem.xmalloc((ext - p) + 1);
                memcpy(newname, p, ext - p);
                newname[ext - p] = 0; // strip extension
                name = newname;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comment indicating what you're trying to do to the file name would be most helpful.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what that code is doing to the filename, but in root.filename there are forceExt, defaultExt, etc.

Copy link
Member Author

@UplinkCoder UplinkCoder Mar 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cgFilename = filename ~ ".cg";

bool hdrgen; /// true if generating header file
bool ddoc; /// true if generating Ddoc file
bool fullDump; /// true if generarting a full ast_dump

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo, alignment, space...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are so many specializations needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because fullDump has to behave differently then hdrgen and so does ddoc,

buf.level++;
s.elsebody.accept(this);
if (!s.elsebody.isScopeStatement())
if (!s.elsebody.isScopeStatement() && !s.elsebody.isIfStatement)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this change actually do?

Copy link
Member Author

@UplinkCoder UplinkCoder Feb 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise

if (a) {} 
else if (b) {}
else if (c) {}

will be printed as

if (a) {} 
else
    if (b) {}
    else
         if (c) {}

if (ti.aliasdecl)
{
ti.aliasdecl.accept(this);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this? Commit message is not helpful here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it writes out the instanced body of the template.

@jacob-carlborg
Copy link
Contributor

Could we get a sample of the output?

@UplinkCoder
Copy link
Member Author

@jacob-carlborg you don't want to see this :)

@MartinNowak
Copy link
Member

alias vec = __vector(int[4]);

vec binop(vec a)
{
    vec b = a;
    return b;
}
import object;
alias vec = __vector(int[4]);
__vector(int[4]) op(__vector(int[4]) a)
{
	return a;
}
__vector(int[4]) binop(__vector(int[4]) a)
{
	return (__vector(int[4]) a = a;) , a;
}

It's really only useful to debug dmd internal issues.

@UplinkCoder
Copy link
Member Author

It does have the utility of showing templates and mix-ins expanded.
That is why I made it a user-visible switch.

@jacob-carlborg
Copy link
Contributor

Cool. Perhaps a nitpick, but this isn't really the AST itself that is printed, rather the result after lowering/semantic pass. I think having ast in the name of the flag is a bit misleading (although I don't know that vcg stands for).

I've been working on a visitor that prints the data in the AST itself, which I initially thought this was.

@UplinkCoder
Copy link
Member Author

-vcg-ast stands for View CodeGen-AST
@jacob-carlborg why would you implement another visitor to do it ?
The PrettyPrintVisitor isn hdrgen does it for you. You just have to evoke it before the semantic-passes.

@jacob-carlborg
Copy link
Contributor

jacob-carlborg commented Feb 25, 2017

jacob-carlborg why would you implement another visitor to do it ?
The PrettyPrintVisitor isn hdrgen does it for you. You just have to evoke it before the semantic-passes.

As far as I can see PrettyPrintVisitor will print the source code that resulted in a given AST. My visitor prints the actual structure of the AST:

NewExp
{
  Expression
  {
    type: TypeClass
    {
      Type
      {
        ty: 7,
        deco: C4core3ast10expression18FunctionExpression
      },
      sym: ClassDeclaration
      {
        AggregateDeclaration
        {
          ScopeDsymbol
          {
            Dsymbol
            {
              ident: Identifier(FunctionExpression)
            },

          },

        }
      }
    },
    op: TOKnew
  },
  thisexp: Expression(null),
  newargs: null,
  newtype: TypeClass
}

It's a good tool to learn the AST and understand the compiler.

@UplinkCoder
Copy link
Member Author

@jacob-carlborg where is that work ?

@jacob-carlborg
Copy link
Contributor

jacob-carlborg commented Feb 25, 2017

jacob-carlborg where is that work ?

In my local branch 😃. I can extract and make it publicly available if it's of any interest. It's not complete, I've added types and fields when needed.

@UplinkCoder
Copy link
Member Author

@jacob-carlborg please push it. I'd like to have a look.

@jacob-carlborg
Copy link
Contributor

I just extracted it from my other branch without compiling it. The file is not added to the makefiles or anything.

https://github.com/jacob-carlborg/dmd/blob/ast-printer/src/ast_printer.d

@veelo
Copy link
Contributor

veelo commented Mar 5, 2017

Not a comment on the code, but maybe a useful tip: for inspecting large ASTs, it can be practical if nodes in the tree can be collapsed and expanded while you are looking at it. This can be done by writing the tree out as HTML5 using the <detail> tag (not supported by IE though). Here is an example. The code that generated this is in https://github.com/PhilippeSigaud/Pegged/blob/master/pegged/tohtml.d.

@jacob-carlborg
Copy link
Contributor

jacob-carlborg commented Mar 5, 2017

The output is actually some kind of JavaScript format. I paste that in my editor, enable JavaScript as the language and then code folding works. Both human readable and collapsing works.

@WalterBright
Copy link
Member

General comment: there are zero comments in the code. For example, it seems like "print template instances" ought to be a comment somewhere in the commit entitled "print template instances". Little nudges like these can be very helpful.

src/mars.d Outdated
auto modFilename = mod.srcfile.toChars();
auto modFilenameLength = strlen(modFilename);
auto cgFilename = cast(char*)allocmemory(modFilenameLength + 4);
strcpy(cgFilename, modFilename);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One reason I dislike ad-hoc C string manipulation is the use of strcpy here. It should be memcpy(cgFilename, modFilename, modFilenameLength) because the length is already computed, and strcpy will compute it again, and strcpy will also add a 0 which will get promptly overwritten.

@MartinNowak
Copy link
Member

Doesn't seem like any blocker for a debug tool.

@MartinNowak
Copy link
Member

Auto-merge toggled on

@schveiguy
Copy link
Member

What version of the compiler did this make it into? Can it be put into the changelog? Every time I want to use this feature, I have to search for Stefan's posts to the forums to figure out the name of the switch. It's not listed in dmd --help, and not on the changelog.

It's a super-handy feature, especially when trying to figure out which templates are instantiated, and how are they implemented.

@UplinkCoder
Copy link
Member Author

UplinkCoder commented Aug 9, 2017

@schveiguy it should be in 2.073 ?
The reason this is not documented is that it is not an official feature.
It's a tool for compiler-devs and not intended to be user-facing.
see: #6556 (comment)

@schveiguy
Copy link
Member

Just today, I used it to determine the exact implementation of formattedRead when called with certain parameters, to see if it allocates using the GC. Tagging a formattedRead call as @nogc didn't help because it uses enforce.

Having a tool to understand exactly how the compiler is going to interpret your templates and other code is sometimes indispensable, especially for a language like D where so much meta-code is happening.

Note, if you didn't want it to be public facing, you shouldn't have posted about it on the newsgroup :)

@UplinkCoder
Copy link
Member Author

@schveiguy I want users to know about it.
Though if it were a publicly documented switch people might relay on the quality and format of the output. Which I cannot guarantee.

@schveiguy
Copy link
Member

people might relay on the quality and format of the output

There has to be a way that it can be documented somewhere, but not "official". Again, I just want to be able to remember the name of the switch (it's not intuitive to me).

@UplinkCoder
Copy link
Member Author

UplinkCoder commented Aug 9, 2017

@schveiguy "view code gen - a s t"

@schveiguy
Copy link
Member

I get that the name stands for something, but I just can't remember it :)

Haven't you ever misremembered an option of a tool, looked for it using --help, and if not there, tried man, or online docs? The issue is that there isn't any existing doc that shows it.

@UplinkCoder
Copy link
Member Author

UplinkCoder commented Aug 9, 2017

mattgodbolt pushed a commit to compiler-explorer/compiler-explorer that referenced this pull request Nov 14, 2023
Apparently AST for ldc is an abuse of terminology, as it doesn't
produces anything resembling a syntax tree:
dlang/dmd#6556 (comment) . It is
potentially meaningful only to ldc developers. Anyway the `generateAST`
result type is fixed, along with some other small stuff around.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants