I have two LLVM passes, one which requires the outputs of the other. So in PassB I have:
void DiscoPoP::getAnalysisUsage(AnalysisUsage &Info) const{
Info.addRequired<PassA>();
}
I tried adding the snippet below to PassB, but when running clang -Xclang -load -Xclang LLVMPassB.so I get an error: undefined symbol: _ZN18PassA2IDE
static RegisterStandardPasses PassLoader(
PassManagerBuilder::EP_EarlyAsPossible,
[](const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM) { PM.add(new PassA()); });
If I load PassA in clang as well, it works: clang -Xclang -load -Xclang LLVMPassA.so -Xclang -load -Xclang LLVMPassB.so
But it seems redundant to have to load it manually if it required from the PassB. Is there a way to load PassA programmatically from PassB?
I get an error: undefined symbol: _ZN18PassA2IDE
Because the PassA isn't visible to clang.
If I load PassA in clang as well, it works: clang -Xclang -load -Xclang LLVMPassA.so -Xclang -load -Xclang LLVMPassB.so
As expected.
But it seems redundant to have to load it manually if it required from the PassB.
Only if there was a way for clang know know about PassA when passB is supplied as flag. clang has no way of knowing where LLVMPassA.so resides unless we pass as flag.
Is there a way to load PassA programmatically from PassB?
This can be done if you modify the LLVM source code and put both your passes there. Registering a pass within LLVM pass manager is straightforward. See https://reviews.llvm.org/D50658 (Hot cold splitting pass) as an example, specifically changes in lib/Transforms/IPO/PassManagerBuilder.cpp, and function createHotColdSplittingPass.
Related
I would like to make a LibTooling tool that takes precisely the same compilation string as clang. For example
clang a.c -O3 b.c -I/myinclude -DMY_DEFINE c.c. Should be replaced by my-tool a.c -O3 b.c -I/myinclude -DMY_DEFINE c.c
Officially suggested by clang documentation way to parse arguments in LibTooling-based tools is CommonOptionsParser. It expects a different format of command-line string and by default relies on the compile_commands.json file. I can simulate desired behavior if I put all source files before -- and everything else after it, like this: my-tool a.c b.c c.c -- -O3 -I/myinclude -DMY_DEFINE. Is it possible to implement this without such hacking of parameter string using llvm/clang API?
I want to create a shared library, using Go, to be used by a third-party software (STAR-CCM+). That software provides some utility c functions for my code to call, and expects my code to, at a minimum, define a specific function, which the third-party software will call after loading the library.
My problem is Go complains about undefined references for the utility functions:
/tmp/go-build672782048/b001/_x002.o: In function `_cgo_c4b84da031f3_Cfunc_utility':
/tmp/go-build/cgo-gcc-prolog:50: undefined reference to `utility'
How can I compile a shared library that calls a c function that is declared but not defined by my code?
The third-party software provides a header file similar to this:
uclib.h
#ifndef UCLIB_H
#define UCLIB_H
// utility function defined by third party software, declared here
extern void utility(int);
// function expected to exist in .so and defined by user
// this function is expected to call `utility` one or more times
void user_function();
#endif
Working example, c only
To test the interaction with the third party software, I build an example using only c:
usingc.c
#include "uclib.h"
void
user_function()
{
utility(1);
}
Build:
$ gcc -fPIC -c usingc.c -o usingc.o
$ gcc -shared -o libmine.so usingc.o
This results in a libmine.so that the third party software successfully loads and registers its utility function being called with 1. Note that utility was only declared, never defined, by my code.
Problematic example, Go
I create a simple go module with the header above and two files:
go.mod
module example.com/cgo_mwe
go 1.15
usinggo.go
package main
// #include "uclib.h"
import "C"
//export user_function
func user_function() {
C.utility(C.int(2))
}
func main() {}
I attempt to build the shared library and observe the error:
$ go build -o libmineg.so -buildmode=c-shared
# example.com/cgo_mwe
/tmp/go-build672782048/b001/_x002.o: In function `_cgo_c4b84da031f3_Cfunc_utility':
/tmp/go-build/cgo-gcc-prolog:50: undefined reference to `utility'
collect2: error: ld returned 1 exit status
The are three possible solutions to allow the linking with the undefined reference. The second two are found in the golang-nuts Google Group:
ignore all undefined references via LDFLAGS with -shared
// #include "uclib.h"
// #cgo LDFLAGS: -shared
import "C"
ignore all undefined references via LDFLAGS with -Wl,-unresolved-symbols=ignore-all:
// #include "uclib.h"
// #cgo LDFLAGS: -Wl,-unresolved-symbols=ignore-all
import "C"
mark the declared but undefined functions as weak in the header file:
#pragma weak utility
// utility function defined by third party software, declared here
extern void utility(int);
The advantage of #3 is that references not marked weak are still called out as undefined.
#define NUM 1
#if(NUM)
if(globalglobalInteger){
result = 1;
}
#else
result=2
#endif
Given the above code , the requirement is that the conditional macro #if should not be evaluated and all code under #if and #else should be passed for further processing.
Basically I want both the active and inactive part(code under #if and code under #else) to be present in the clang AST.
Is this possible in clang ?
Is there any pre-processor flag available
for doing this in clang?
Saw that there is flag called -fdirectives-only in gcc which disables macro expansion but could not find similar flag in clang
Preprocessing takes places before parsing and AST generation, so you can't have
non-expanded defines and macros in the AST.
However, there are means for handling non-preprocessed code - such as registering to clang preprocessor callbacks (the PPCallbacks interface) or through the pp-trace tool
(disclamer: I don't have experience with this myself).
References:
Clang AST dump doesn't show #defines
http://clang-developers.42468.n3.nabble.com/Preprocessor-Parser-interaction-td3754583.html
http://www.llvm.org/devmtg/2016-11/Slides/Trull-ExtendingClangASTMatchers.pdf
With regards to flags, clang has no equivalent to gcc's -fdirectives-only. For keeping both parts of the macro in output,
you could disable preprocessing altogether, similar to gcc's -fpreprocessed - which will effectively disable macro expansion (but still macros will be absent from the AST).
You could insepct the AST generated for non-preprocessed source files with these commands:
clang -xcpp-output -Xclang -ast-dump -c foo.c
clang -xc++-cpp-output -Xclang -ast-dump -c foo.cpp
HTH - good luck!
I tried to use erl_errno as described in the erlang document: http://erlang.org/doc/man/erl_error.html#.
However, I'm getting a symbol not found problem during linking. I'm running on Mac and here's the how the program is linked:
g++ -L/usr/local/lib/erlang/lib/erl_interface-3.9.3/lib -o "roserl" ./src/driver.o ./src/erl_bridge.o -lei -lm -lerl_interface
I have already linked with libei and liberl_interface. What else is needed?
It is weird but you will have to do this in your header:
#ifndef _REENTRANT
#define _REENTRANT /* For some reason __erl_errno is undefined unless _REENTRANT is defined */
#endif
#include "erl_interface.h"
#include "ei.h"
This fixed the problem for me. Now I can use erl_errno.
Using clang to link a program fails like this:
/usr/bin/x86_64-pc-linux-gnu-ld: stackoverflow.o: undefined reference to symbol '__cxa_free_exception##CXXABI_1.3'
Like with gcc, you have to use clang++ to link C++ programs