<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><pre style="white-space: pre-wrap; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Hi cfe-dev,</pre><pre style="white-space: pre-wrap; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">I am using clang to compile C programs to LLVM IR. I have the following program:</pre><pre style="font-variant-ligatures: normal; orphans: 2; widows: 2;" class=""><span style="white-space: pre-wrap;" class="">struct A {
   int (*f)(int, struct A*);
   int (*g)(char, struct A*);
};

int h(int a, struct A* b) {
        return 0;
}

int i(char a, struct A* b) {
        return 1;
}

int main() {
        struct A a;
        a.f = h;
        a.g = 0;
        a.f(0, &a);
        return 0;
}</span></pre><div class="">Now, if I compile this to LLVM IR, the struct A becomes:</div><div class=""><br class=""></div><div class=""><div class="">%struct.A = type { {}*, i32 (i8, %struct.A*)* }</div></div><div class=""><br class=""></div><div class="">So the type of function pointer f in A is {}* and the type of g (in A) is (just as I would expect of type i32 (i8, %struct.A*)*. Now, why is the type for f abbreviated like this? If I change the order of the functions in the C program by swapping the order of the definitions of h(...) and i(…), the type of the struct A becomes:</div><div class=""><br class=""></div><div class=""><div class="">%struct.A = type { i32 (i32, %struct.A*)*, {}* }</div></div><div class=""><br class=""></div><div class="">Now the type of f is spelt out completely as I would expect, but g’s type is given by {}*. If I slightly change the type of the function pointers whose type becomes {}* (e.g. changing “int” to “long” or something like this), I get their full types back again.</div><div class=""><br class=""></div><div class="">From what I can see, the function pointer types within struct A become {}* if they coincide with the type of the first function following the structure definition that involves the struct itself. In other words, if I put a function </div><div class=""><br class=""></div><div class="">int j() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>return 0;</div><div class="">}</div><div class=""><br class=""></div><div class="">between struct A and h, then everything stays as it is (i.e. one of the types is going to be {}*), but if I make it</div><div class=""><br class=""></div><div class="">int j(struct A* a) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>return 0;</div><div class="">}</div><div class=""><br class=""></div><div class="">the IR for %struct.A changes (and I suddenly get the full types for both function pointers).</div><div class=""><br class=""></div><div class="">How is the type {}* supposed to be interpreted here? Why is it, that depending on what follows, the type is “abbreviated” as {}* and sometimes not?</div><div class=""><br class=""></div><div class="">I am using AppleClang on Mac OS 10.12, but I get the same behavior with pre-built clang 3.9 downloaded from the LLVM website.</div><div class=""><br class=""></div><div class="">Best wishes,</div><div class="">Chris</div></body></html>