News:

When registered with our forums, feel free to send a "here I am" post here to differ human beings from SPAM bots.

Main Menu

Symbol Browser trouble with class ctor/dtor definition when namespace is used

Started by Greatwolf, December 15, 2010, 02:23:15 PM

Previous topic - Next topic

Greatwolf

Hi all,

I've identified a bug in the symbol browser(codecomplete?) plugin. Please let me know if this is the correct section to post or not.

The problem I'm running into is that the C::B plugin is unable to locate the class constructor and destructor definitions when it's used inside a namespace. The following minimal code snippet illustrates the bug:

namespace foo
{
  class bar
  {
   bar();
   ~bar();
  };
  bar::bar() {}
  bar::~bar() {}
}


The declaration for bar() and ~bar() is correctly located but when I try to find the implementation, it will tell me it's not found. The scope bar above the editor also does not display correct for these two cases. If you click the caret to be on the line bar::~bar() {} then that scope display will show foo:: and bar(): ~. The expected result for it is foo::bar:: and ~bar().

One more piece of info, if the above test code is change to the following then everything works as expected:

namespace foo
{
  class bar
  {
   bar();
   ~bar();
  };
}

foo::bar::bar() {}
foo::bar::~bar() {}



The nightly build used here is 6863. I've submitted a bug report for this already over here. Did anyone else run into this problem also?

Thanks

Greatwolf

I've attached a picture here to better show the issue. Notice the ctor and dtor declarations are properly found. However, the dtor definition is showing in the wrong scope and the ctor definition is missing altogether! The codecomplete bar at the top is also not showing correctly when the caret is on the ctor definition line.

[attachment deleted by admin]

ollydbg

If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

ollydbg

Windows XP, codeblocks trunk 6897, with the test code:
namespace foo
{
 class bar
 {
  bar();
  ~bar();
 };
 bar::bar() {}
 bar::~bar() {}
}


Here is the result:

both the declaration and the implementation of constructor are lost.

I will do more check. :D
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Greatwolf

Quote from: ollydbg on December 16, 2010, 06:12:35 AM
both the declaration and the implementation of constructor are lost.

I will do more check. :D

kewl. thanks for looking into this :)

If it helps to narrow this down, this bug doesn't show up if an anonymous namespace is used. That is to say if the above example is changed to this, everything will work:

namespace // foo
{
  class bar
  {
   bar();
   ~bar();
  };
  bar::bar() {}
  bar::~bar() {}
}

ollydbg

here is the full log when I use the parsertest project.
Quote--------------M-a-i-n--L-o-g--------------

000001. InitTokenizer() : m_Filename='test.h', m_FileSize=103.
000002. Init() : m_Filename='test.h'
000003. Parse() : Parsing 'test.h'
000004. DoParse() : Loop:m_Str='', token='namespace'
000005. DoAddToken() : Created token='foo', file_idx=1, line=1, ticket=
000006. GetActualTokenType() : Searching within m_Str=''
000007. GetActualTokenType() : Compensated m_Str=''
000008. GetActualTokenType() : Returning ''
000009. DoAddToken() : Prepending ''
000010. DoAddToken() : Added/updated token 'foo' (0), kind 'namespace', type '', actual ''. Parent is  (-1)
000011. DoParse() : Loop:m_Str='', token='class'
000012. HandleClass() : Found class 'bar'
000013. DoAddToken() : Created token='bar', file_idx=1, line=3, ticket=
000014. GetActualTokenType() : Searching within m_Str=''
000015. GetActualTokenType() : Compensated m_Str=''
000016. GetActualTokenType() : Returning ''
000017. DoAddToken() : Prepending ''
000018. DoAddToken() : Added/updated token 'bar' (1), kind 'class', type '', actual ''. Parent is foo (0)
000019. DoParse() : Loop:m_Str='', token='bar'
000020. ReadParentheses(): (), line=5
000021. HandleFunction() : Adding function 'bar': m_Str=''
000022. HandleFunction() : name='bar', args='()', peek=';'
000023. HandleFunction() : !(Ctor/Dtor) 'bar', m_Str='', localParent='<none>'
000024. HandleFunction() : Adding function 'bar', ': m_Str='', enc_ns='nil'.
000025. HandleFunction() : Add token name='bar', args='()', return type=''
000026. GetBaseArgs() : args='()'.
000027. GetBaseArgs() : baseArgs='()'.
000028. DoAddToken() : Created token='bar', file_idx=1, line=5, ticket=
000029. DoAddToken() : Added/updated token 'bar' (2), kind 'constructor', type '', actual ''. Parent is bar (1)
000030. DoParse() : Loop:m_Str='', token=';'
000031. DoParse() : Loop:m_Str='', token='~'
000032. DoParse() : Loop:m_Str='~ ', token='bar'
000033. ReadParentheses(): (), line=6
000034. HandleFunction() : Adding function 'bar': m_Str='~ '
000035. HandleFunction() : name='bar', args='()', peek=';'
000036. HandleFunction() : !(Ctor/Dtor) 'bar', m_Str='~ ', localParent='<none>'
000037. HandleFunction() : Adding function 'bar', ': m_Str='~ ', enc_ns='nil'.
000038. HandleFunction() : Add token name='bar', args='()', return type='~ '
000039. GetBaseArgs() : args='()'.
000040. GetBaseArgs() : baseArgs='()'.
000041. DoAddToken() : Created token='~bar', file_idx=1, line=6, ticket=
000042. DoAddToken() : Added/updated token 'bar' (3), kind 'destructor', type '', actual ''. Parent is bar (1)
000043. DoParse() : Loop:m_Str='', token=';'
000044. DoParse() : Loop:m_Str='', token='}'
000045. DoParse() : Loop:m_Str='', token='bar'
000046. DoParse() : Loop:m_Str='', token='bar'
000047. ReadParentheses(): (), line=8
000048. HandleFunction() : Adding function 'bar': m_Str=''
000049. HandleFunction() : name='bar', args='()', peek='{'
000050. HandleFunction() : Ctor/Dtor 'bar', m_Str='', localParent='<none>'
000051. HandleFunction() : Adding function 'bar', ': m_Str='', enc_ns='nil'.
000052. HandleFunction() : Add token name='bar', args='()', return type=''
000053. GetBaseArgs() : args='()'.
000054. GetBaseArgs() : baseArgs='()'.
000055. DoAddToken() : Created token='bar', file_idx=1, line=8, ticket=
000056. GetActualTokenType() : Searching within m_Str=''
000057. GetActualTokenType() : Compensated m_Str=''
000058. GetActualTokenType() : Returning ''
000059. DoAddToken() : Prepending 'bar::'
000060. DoAddToken() : Added/updated token 'bar' (4), kind 'function', type '', actual 'bar::'. Parent is foo (0)
000061. DoParse() : Loop:m_Str='', token='bar'
000062. DoParse() : Loop:m_Str='', token='~'
000063. DoParse() : Loop:m_Str='~ ', token='bar'
000064. ReadParentheses(): (), line=9
000065. HandleFunction() : Adding function 'bar': m_Str='~ '
000066. HandleFunction() : name='bar', args='()', peek='{'
000067. HandleFunction() : Ctor/Dtor 'bar', m_Str='~ ', localParent='<none>'
000068. HandleFunction() : Adding function 'bar', ': m_Str='~ ', enc_ns='nil'.
000069. HandleFunction() : Add token name='bar', args='()', return type='~ '
000070. GetBaseArgs() : args='()'.
000071. GetBaseArgs() : baseArgs='()'.
000072. DoAddToken() : Found token (parent).
000073. GetActualTokenType() : Searching within m_Str='~'
000074. GetActualTokenType() : Compensated m_Str='~'
000075. GetActualTokenType() : Found ''
000076. DoAddToken() : Prepending 'bar::'
000077. DoAddToken() : Added/updated token 'bar' (4), kind 'function', type '~', actual 'bar::'. Parent is foo (0)
000078. DoParse() : Loop:m_Str='', token='}'


--------------T-r-e-e--L-o-g--------------

000079. +namespace foo {...}   [1,1]
000080. +class bar {...}   [3,3]
000081. foo::bar::bar()   [5,0]
000082. foo::bar::~bar()   [6,0]
000083. bar()   [8,9]


--------------L-i-s-t--L-o-g--------------

000084. namespace namespace foo {...}   [1,1]
000085. class class bar {...}   [3,3]
000086. constructor foo::bar::bar()   [5,0]
000087. destructor foo::bar::~bar()   [6,0]
000088. function ~ foo::bar()   [8,9]

the red lines are wrong.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

ollydbg

here is the patch to solve this, but I have no time to check if it will break other piece of code. :D
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Greatwolf

I've applied the patch with the latest svn and it does indeed fix the issue. Very nice good job!

Now we just need to apply this patch to the trunk :D