I am building a GCC plugin and am trying to create a call to a constructor for
a global variable. The class is declared in a .cpp file and I have global
instance of the class declared in the file as well. The class declaration for
the global instance I am trying to create follows:
--------------------------------------
namespace LocalTestNamespace
{
class CTestClass
{
public :
CTestClass()
{
std::cout << "Test Class Initialized." << std::endl;
}
};
}
LocalTestNamespace::CTestClasssourceCodeGlobalTestClass;
// g++ parser generates the initialization statement for this global
------------------------------------
In my plugin, I create a global variable for 'CTestClass' and then attempt to
invoke the constructor for it in the
'__static_initialization_and_destruction_0' function. Below is a snippet of
the code to create the gimple statement and insert it into the initialization
function. The plugin runs just before the call flow graph generator pass.
-------------------------------------
treeaddr_var_decl = build_fold_addr_expr( globalDeclaration );
// globalDeclaration points to the VAR_DECL I created
treeconstructor = CLASSTYPE_CONSTRUCTORS( declType );
// declType is the tree for CTestClass
gimpleinitializationStatement = gimple_build_call( OVL_CURRENT( constructor ),
1, addr_var_decl );
debug_gimple_stmt( initializationStatement );
// the debug outout of the statement looks fine
gsi_insert_before( &insertionPoint, initializationStatement, GSI_SAME_STMT );
// insertionPoint is just before the goto following the calls to
global initializers
--------------------------------------
When I run this code, the statement gets inserted but the assembler fails.
Looking at the assembly output reveals the following at the end of the
initializer:
--------------------------------------
movl$sourceCodeGlobalTestClass, %edi // the
global in the source code
call_ZN18LocalTestNamespace10CTestClassC1Ev //
call to the class constructor created by the g++ parser
movl$testCTestClassVar, %edi // the
global I created in the plugin
call_ZN18LocalTestNamespace10CTestClassC1EOS0_ *INTERNAL* //
call to the class constructor generated by the code snippet above and the gcc
error
--------------------------------------
Using c++filt the names demangle as:
_ZN18LocalTestNamespace10CTestClassC1Ev =>>
LocalTestNamespace::CTestClass::CTestClass()
_ZN18LocalTestNamespace10CTestClassC1EOS0_ =>>
LocalTestNamespace::CTestClass::CTestClass(LocalTestNamespace::CTestClass&&)
Clearly the call I am building is incorrect and I have tried numerous
variations with the same results. If I manually edit the assembly output file
and change the 'C1EOS0_' suffix to 'C1Ev' and strip out the '*INTERNAL*', I can
run the assembler on the modified file and generate an executable that works
perfectly. I have searched for examples of using gimple_build_call() to
generate calls to c++ class constructors but haven't tripped over any examples.
I would greatly appreciate any suggestions on how to generate the appropriate
constructor call.
Thanks,
Stephan