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

Reply via email to