This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: More __comp_ctor () woes


In order to help, I am posting the code I use to try and get a "user constructor" FUNCTION_DECL node from a "__comp_ctor ()" FUNCTION_DECL node as mentioned in previous emails. The code can be found at the end of this email.

Also...

class MyClass
{
   MyClass()
   {}
};

int main()
{
   MyClass c;
   return 0;
}

This will produce at least 3 FUNCTION_DECL nodes:
1) main()
2) MyClass::MyClass(MyClass* this)
3) MyClass::__comp_ctor (MyClass* this)

I call (2) a "User Constructor" for want of a better name. But note that BOTH (2) and (3) are considered "constructors" as returned by DECL_CONSTRUCTOR_P(fndecl)




This comes from the fact ABI has two constructors, an in charge and an
out of charge and the orginal constructor is still there though 3 is a
clone of (2). (2) is never compiled or called.



As i understand it (2) is compiled, as that is the function that contains the users code. I could be wrong here though as i have very little experience hacking GCC.



The code I am using to obtain a "user constructor" FUNCTION_DECL from a "__comp_ctor ()" FUNCTION_DECL looks as shown below. I really dont like this code as it currently uses a strcmp in order to findwhat it is after and it also does not work completely. I have also placed some code at the very end of this email which is a small test case of code that this fails for.


Thanks, Brendon





I call the function: GetCtorEquivilent(tree fndecl) with the fndecl node for the "__comp_ctor()" i am looking for the associated "User constructor" for.



static tree GetCtorEqvProcMethod(tree fndecl, tree method,
  const char* context_string, int context_len);

/*==================================================================*/
tree GetCtorEquivilent(tree fndecl)
{
tree context = NULL_TREE;
tree method = NULL_TREE;
int context_len = 0;
const char* context_string = NULL;
tree ret = NULL_TREE;
context = DECL_CONTEXT(fndecl);
BJC_ASSERT(TYPE_P(context), "Should be a TYPE object");
BJC_ASSERT(CLASS_TYPE_P(context), "Should be a CLASS TYPE object");


/* Get list of classes methods that we will search for a
constructor in. */
method = TYPE_METHODS(context);
context_string = IDENTIFIER_POINTER(
DECL_NAME(TYPE_NAME(context)));
context_len = strlen(context_string);
while(method)
{
ret = GetCtorEqvProcMethod(fndecl, method,
context_string, context_len);
if (ret)
{
return ret;
}


     method = TREE_CHAIN(method);
  }

  return NULL_TREE;
}


/*==================================================================*/ static tree GetCtorEqvProcMethod(tree fndecl, tree method, const char* context_string, int context_len) { tree ret = NULL_TREE; tree list = NULL_TREE; int decl_len = 0; const char* decl_string = NULL;

  /* We are only interested in constructors */
  if (!DECL_CONSTRUCTOR_P(method))
  {
     return NULL_TREE;
  }

  /* Ensure we do not look at ourself */
  if (method == fndecl)
  {
     return NULL_TREE;
  }

/* If is a template decl then process all instanciations */
if (TREE_CODE(method) == TEMPLATE_DECL)
{
list = DECL_TEMPLATE_SPECIALIZATIONS(method);
while (list)
{
/* The TREE_VALUE should be eithre a FUNCTION_DECL
or a TEMPLATE_DECL process it recursivly. */
ret = GetCtorEqvProcMethod(fndecl, constructor,
TREE_VALUE(list), context_string, context_len);
if (ret)
{
return ret;
}
list = TREE_CHAIN(list);
}
return NULL_TREE;
}


  /* Template decls are handled above, at this point we
  should only ever see function decls. */
  BJC_ASSERT(TREE_CODE(method) == FUNCTION_DECL, "");

/* This is dodgy there has to be a way to do this
without using string compare of the first part. I.e.
we are comparing without looking at the template data.*/
/* I.e. ::Container<::int>::Container() is the correct
constructor NOT
::Container<::int>::Container<::int>() which will never occur
*/
decl_string = IDENTIFIER_POINTER(DECL_NAME(method));
decl_len = strlen(decl_string);
if (strncmp(context_string, decl_string, decl_len))
{
/*decl has a different name than the context. */
return NULL_TREE;
}


  if (context_len != decl_len)
  {
     if (context_string[decl_len] != '<')
     {
        /*decl has a different name than the context. */
        return NULL_TREE;
     }
  }

/* Got a method with the same name as the class that
encapsulates it. Now checking parameter types to see if
they are the same */
/* This function is defined elsewhere and will compare
parameters of functions/methods ignoring the
in_charge_identifier, vtt_parm_identifier nodes
if the 3rd arg is true*/
if (!FunctionsHaveSameArgs(fndecl, method, true))
{
return NULL_TREE;
}


  return method;
}



---------------
This is a simple test case which causes the above to fail to find a "user constructor" for the associated "__comp_ctor() constructor". It can probably get even simpler, but it should demonstrate the problem.


template<typename CharT>
class Traits
{
};
template<typename CharT>
class Alloc
{
};


template<typename _CharT, typename _Traits, typename _Alloc>
class MyClassT
{
public:
template<class _InputIterator>
MyClassT(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc());
};
typedef MyClassT<char, Traits<char>, Alloc<char> > MyClass;
int main()
{
const char* str1 = "Hello1";
const char* str2 = "Hello2";
Alloc<char> a;
MyClass mc(str1, str2, a);
return 0;
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]