I am facing a problem with LLVM 3.5 Compiler and suspect it is a bug in the clang. I earlier posted this query to llvm-dev list.
Here is my observation.
I am trying to support a target specific function attribute for a particular target machine.
Having followed the steps specified in the compiler documentation, I see the attribute is passed to the backend if we include the attribute in the function definition. But this attribute is not propagate to the backend if I include it only in the function’s prototype/declaration (in the C program).
This virtual function (given below) invocation in clang/lib/CodeGen/CodeGenModule.cpp in clang is responsible for attaching the target specific attributes to the backend CodeGen objects (functions, variables etc.)
getTargetCodeGenInfo().SetTargetAttributes(D, GO, *this)
I found that this virtual function is getting invoked only for function definitions and not for function declarations.
Along with regular C functions we have special functions supported in the target and its definition and invocation will always come in different compilation units. There must be a way to recognize these special functions at the call-sites during codegen in the backend. By attaching some info in the function prototype, we can recognize these special functions at the call-site during backend codegen. That’s why I thought of a new target specific attribute to achieve this purpose.
Is it really a bug?
When I compile a program having function declarations/prototypes with generic attributes like attribute((const)), clang will add it to that function’s attributelist in the IR and it will be available in the backend.
Similarly I expected the target specific attribute should also be added to the attributelist available in the backend and I should be able to identify it using F.hasFnAttribute(“XYZ”), where XYZ is the new attribute name.
I understand that a look-up in the prototype for function-attrs is very rare at codegen. But I was keen to ask this when I found that the standard attributes (‘const’, for example) are actually propagated to the backend through function prototype.
In the sample program below I have declared function foo with attribute 'const’ and you can see 'readnone’ is added to the attribute list.
extern void attribute((const)) foo (int);
int main ()
int my_var = 45;