From: Stephan Friedl <stephanf01@yahoo.com>
To: "gcc@gcc.gnu.org" <gcc@gcc.gnu.org>
Subject: Re: gimple_build_call for a class constructor
Date: Thu, 30 Jan 2014 09:23:00 -0000 [thread overview]
Message-ID: <1391060508.92372.YahooMailNeo@web125804.mail.ne1.yahoo.com> (raw)
In-Reply-To: <1390976775.69577.YahooMailNeo@web125803.mail.ne1.yahoo.com>
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
prev parent reply other threads:[~2014-01-30 5:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-29 9:32 Stephan Friedl
2014-01-30 9:23 ` Stephan Friedl [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1391060508.92372.YahooMailNeo@web125804.mail.ne1.yahoo.com \
--to=stephanf01@yahoo.com \
--cc=gcc@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).