Rendering of variable declarations specifying register allocation

[Re-posting to cfe-dev after receiving no response from cfe-users. Apologies if this is the wrong place to post this or if this is intended behaviour.]

Hi all,

GCC allows you to specify a register to use during a variable declaration (https://gcc.gnu.org/onlinedocs/gcc/Local-Reg-Vars.html#Local-Reg-Vars). Clang seems to understand these declarations, but does not correctly render these when pretty printing the AST:

  $ cat foo.c
  void foo(void) {
      register int x asm("eax");
  }
  $ clang-3.2.7 -c foo.c # compiles without error
  $ clang-3.2.7 -cc1 -ast-print foo.c
  void foo() {
      register int x;
  }
  $ clang-r207601 -cc1 -ast-print foo.c
  void foo() {
     register int x asm("eax");
}

  $ cat bar.c
  void bar(void) {
      register int x asm("eax") = 1;
  }
  $ clang-3.2.7 -c bar.c # compiles without error
  $ clang-3.2.7 -cc1 -ast-print bar.c
  void bar() {
      register int x = 1;
  }
  $ clang-r207601 -cc1 -ast-print bar.c
  void bar() {
      register int x = 1 asm("eax");
  }

As you can see from the above, the two Clang versions I've tested have different behaviour, though neither seem correct. The versions generated by the second version of Clang do not seem to be syntactically valid. I have not yet tried with the current tip, but the two above are:
  - Debian clang version 3.2-7ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2)
  - clang version 3.5.0 (trunk 207601)

This seems to be independent of the target platform; at least I get similar results for ARM and x86. What is the intended behaviour here?

Thanks,
Matt

Current tip does:

void foo() {
    register int x asm("eax");
}

AND

void foo() {
    register int x = 1 asm("eax");
}

The first looks correct, but the second looks weird. I don't know
what's the expected behaviour, or if this output can be regarded as
valid code (I'm guessing not), so in theory, it doesn't matter much.
But it does seem an easy fix for this particular case, I think.

cheers,
--renato

Thanks, Renato. So this is definitely a bug? If so, I'll open a new one at http://llvm.org/bugs/. Just wanted to make sure it wasn't intended behaviour.

Possibly. Opening a bug is definitely worth, though, at least to investigate.

Cheers,
Renato

OK, will do. While we're on the topic, Clang also seems to remove bracketing around parameters to inline asm:

  $ cat foo.c
  void foo() {
    int i = 0;
    asm ("mov %%eax, %%ebx"::"a"(i));
  }
  $ clang -c foo.c
  $ clang -cc1 -ast-print foo.c | tee bar.c
  void foo() {
      int i = 0;
      asm ("mov %%eax, %%ebx" : : "a" i);
  }
  $ clang -c bar.c
  bar.c:3:38: error: expected '(' after 'asm operand'
      asm ("mov %%eax, %%ebx" : : "a" i);
                                       ^
  1 error generated.

To me, this is indicative of a second bug. Should I file this one separately as well? My hesitancy is because I'm not sure how robust this functionality is intended to be. Should the output of -ast-print always be parseable as input to Clang? I would think yes.

Matthew,

I don’t think this functionality is intended to be stable or reparseable, but most certainly it’s not a production tool.

Whatever is reported, will probably be treated as improvement, not a bug. You shouldn’t be using this as a feature, that’s all I’m saying.

Cheers,
Renato