Author Topic: Symbol Browser trouble with class ctor/dtor definition when namespace is used  (Read 6393 times)

Offline Greatwolf

  • Multiple posting newcomer
  • *
  • Posts: 48
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:

Code
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:

Code
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

Offline Greatwolf

  • Multiple posting newcomer
  • *
  • Posts: 48
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]
« Last Edit: December 16, 2010, 04:14:26 am by Greatwolf »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
sounds like a bug in codecompletion plugin. I will check it :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.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Windows XP, codeblocks trunk 6897, with the test code:
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.

Offline Greatwolf

  • Multiple posting newcomer
  • *
  • Posts: 48
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:

Code
namespace // foo
{
  class bar
  {
   bar();
   ~bar();
  };
  bar::bar() {}
  bar::~bar() {}
}
« Last Edit: December 16, 2010, 06:45:55 am by Greatwolf »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
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.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
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.

Offline Greatwolf

  • Multiple posting newcomer
  • *
  • Posts: 48
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