public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* gimple_build_call for a class constructor
@ 2014-01-29  9:32 Stephan Friedl
  2014-01-30  9:23 ` Stephan Friedl
  0 siblings, 1 reply; 2+ messages in thread
From: Stephan Friedl @ 2014-01-29  9:32 UTC (permalink / raw)
  To: gcc

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: gimple_build_call for a class constructor
  2014-01-29  9:32 gimple_build_call for a class constructor Stephan Friedl
@ 2014-01-30  9:23 ` Stephan Friedl
  0 siblings, 0 replies; 2+ messages in thread
From: Stephan Friedl @ 2014-01-30  9:23 UTC (permalink / raw)
  To: gcc

I found my problem - I had forgotten about the cloned and generated constructors.

For this case, there were 9 constructors generated - 3 sets of three with names of 'CTestClass', '__base_ctor' and '__comp_ctor'.  The first two sets of constructors took references as arguments, I'm assuming copy and move constructors, and the third set took no arguments and was the one I wanted.  When I used the '__comp_ctor' constructor with no arguments all worked correctly.  The following code snippet is the first pass of what I did to identify the right no-arg constructor to insert into the global initialization routine:

--------------------------------------

MethodListmethods( TYPE_METHODS( declType ) );              // MethodList is a template class I created to iterate over TREE_LISTs 

for( MethodList::iterator itrMethod = methods.begin(); itrMethod != methods.end(); ++itrMethod )
{
    ctorMethod = (const tree&)*itrMethod;

    if(( strcmp( IDENTIFIER_POINTER( DECL_NAME( ctorMethod )), "__comp_ctor " ) == 0 ) &&
       ( TREE_CHAIN( DECL_ARGUMENTS( ctorMethod ) ) == NULL_TREE ))
    {
        break;
    }
}

------------------------------------------ 

For clarity, the FUNCTION_DECL does take an argument, the pointer to the variable to be initialized.  Any arguments to the FUNCTION_DECL beyond a pointer to the variable to be initialized would be arguments to the class constructor itself.

Thanks,

Stephan





On Tuesday, January 28, 2014 11:26 PM, Stephan Friedl <stephanf01@yahoo.com> wrote:
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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-01-30  5:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-29  9:32 gimple_build_call for a class constructor Stephan Friedl
2014-01-30  9:23 ` Stephan Friedl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).