Inconsistent mangling of C++ unnamed types compiling source code vs compiling AST files

According to the Itanium C++ ABI, The unnamed structures nested in struct S below should be assigned the names 'N1SUt_' and 'N1SUt0_' respectively. And indeed, Clang versions 3.3 and newer do assign these names when compiling the source directly. However, when the source is first emitted to a .ast file and then compiled, both of the unnamed structures are assigned the same mangled name (presumably because mangling discriminators are not being preserved in the .ast file). For the test case below, this results in both instantiations of the tf() template function receiving the same name and one being discarded.

I tested this behavior with Clang versions 3.3 through trunk (pulled tonight). Clang 3.2 produces consistent behavior, though the names generated in that release don't conform to the Itanium ABI.

Warnings regarding the use of an unnamed type as a template argument are issued when compiling the test case below. This test case was contrived to demonstrate that both unnamed types are being assigned the same name.

$ cat t.cpp
struct S {
   struct {
     int i;
   } s1;
   struct {
     int i;
   } s2;
} s;

template<typename T>
void tf(T t) {}

void f() {
   tf(s.s1);
   tf(s.s2);
}

$ clang -c t.cpp
...

$ nm t.o
0000000000000000 T _Z1fv
0000000000000000 W _Z2tfIN1SUt0_EEvT_
0000000000000000 W _Z2tfIN1SUt_EEvT_
0000000000000000 B s

$ clang -emit-ast t.cpp
...

$ clang -c t.ast

$ nm t.o
0000000000000000 T _Z1fv
0000000000000000 W _Z2tfIN1SUt_EEvT_
0000000000000000 B s

Tom.

Thanks for the report, should be fixed in r204423.

Thank you! Funny, I was just about to submit my own patch when I got your email. Your patch is better :slight_smile:

I verified this resolved the problem (and also back ported the change to Clang 3.4 where it worked fine as well).

Tom.