After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 660025 - Symbol db plugin doesn't parse nested class correctly
Symbol db plugin doesn't parse nested class correctly
Status: RESOLVED OBSOLETE
Product: anjuta
Classification: Applications
Component: plugins: symbol-db
git master
Other Linux
: Normal normal
: ---
Assigned To: Massimo Cora'
Anjuta maintainers
Depends on:
Blocks:
 
 
Reported: 2011-09-24 17:59 UTC by Sébastien Granjoux
Modified: 2020-11-06 20:22 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
A small improvement in anjuta-tags to support scope in verilog (4.66 KB, patch)
2012-01-24 21:48 UTC, Sébastien Granjoux
none Details | Review
A small verilog sample to check the code (930 bytes, text/plain)
2012-01-24 21:49 UTC, Sébastien Granjoux
  Details

Description Sébastien Granjoux 2011-09-24 17:59:50 UTC
I have written the following class in a C++ file:

class Parent
{
public:
	int i;
	int j;

	class Child
	{	
	public:
		int i;
		int j;

		void print(void);
	};
	
	void print(void);
};


void Parent::print(void)
{
	std::cout << "Print Parent" << i << " " << j << std::endl;
}

void Parent::Child::print(void)
{
	std::cout << "Print Child" << i << " " << j << std::endl;
}

In the symbol-db browser pane, I get two times, the variables i and j and the method print as children of the Parent class. Moreover the Child class get the same things with an additional wrong Child class up to 20 or 30 levels. Is it something not supported or is it a bug?
Comment 1 Johannes Schmid 2011-09-25 00:59:22 UTC
This looks like a bug. Maybe we should write some unit test with symbol-db...
Comment 2 Massimo Cora' 2012-01-02 23:50:41 UTC
Indeed, a unit test is definely needed to avoid regressions in the parser.
And the C++ one is especially not mature.
I wonder if exists something more powerful than ctags to handle these cases in a one shot. Of course it would mean to rewrite the symbol-db engine.
Comment 3 Johannes Schmid 2012-01-03 07:58:50 UTC
Well, it's called clang and is a full featured C/C++ parser (and therefore a lot more powerful than ctags).

The gedit devs played a bit with it:
https://github.com/jessevdk/gedit-code-assistance
Comment 4 Sébastien Granjoux 2012-01-03 20:15:18 UTC
I would like to use the symbol-db plugin for another language than C++ so using clang is not really an option. But instead of re-targeting the symbol-db plugin to use clang perhaps we can add an interface to allow using various backend (like in the project manager or in the debugger). If I'm not alone, I will be interested to spend some time on this.

Else for regression test, I'm using autotest in the autotools backend, I think it could be used here too.
Comment 5 Massimo Cora' 2012-01-03 20:24:26 UTC
From what I read on http://clang.llvm.org/features.html I don't see a feature to retrieve the symbols in a file, so having a behaviour like ctags' one seems impossibile.
Different is instead the thing of errors annotations etc. while coding. That would be interesting.

@Seb: using a common backend would be possibile if the different parsers output more or less the same informations (function declarations, definitions, global symbols etc.).
By having those informations we can setup a strategy pattern to use ctags or clang(?) or x-parser at runtime. Everyone can then use the same database or implement their own.

Btw: we could have reached the same thing that clang does many years ago with something like "gcc -E". IIRC it was used by Kdevelop but it was extremely slow.
Comment 6 Sébastien Granjoux 2012-01-03 20:52:52 UTC
(In reply to comment #5)
> @Seb: using a common backend would be possibile if the different parsers output
> more or less the same informations (function declarations, definitions, global
> symbols etc.).

My idea was to display a hierarchical view for verilog. It's looking a bit like C hierarchical declaration. By example

module child (i, j);
  input i;
  output j;

  assign j = i;
endmodule

module parent (i, j, k);
  input i;
  output j;
  output k;
  child u1 (j, i);
  child u2 (k, i);
endmodule
 
And I would like to display in the symbol db view

+ parent
  i
  j
  k
  + u1
    i 
    j
  + u2
    i
    j

The module child could contains other module adding new level in the hierarchy, there is no limit. Is it possible to have such thing with the current symbol-db plugin?

I don't think the verilog backend for ctag provide enough information for such thing, so I plan to improve it or use another parser. But if it needs some additional changes in the symbol-db plugin it's more difficult.
Comment 7 Massimo Cora' 2012-01-04 21:20:30 UTC
The scope information should be provided by ctags, and currently it doesn't support it for verilog.
I tried with:

$ ctags --fields=afmiKlnsStz --language-force=verilog test.verilog

The tags output was:


child   test.verilog    /^module child (i, j);$/;"      kind:module     line:1  language:Verilog
i       test.verilog    /^  input i;$/;"        kind:port       line:2  language:Verilog
i       test.verilog    /^  input i;$/;"        kind:port       line:9  language:Verilog
j       test.verilog    /^  output j;$/;"       kind:port       line:10 language:Verilog
j       test.verilog    /^  output j;$/;"       kind:port       line:3  language:Verilog
k       test.verilog    /^  output k;$/;"       kind:port       line:11 language:Verilog
parent  test.verilog    /^module parent (i, j, k);$/;"  kind:module     line:8  language:Verilog


in particular there's no sign of u1 and u2, which could help in finding the correct scope.
I suppose the that it can be implemented in anjuta-tags.
Comment 8 Sébastien Granjoux 2012-01-04 22:01:16 UTC
(In reply to comment #7)
> The scope information should be provided by ctags, and currently it doesn't
> support it for verilog.
> I suppose the that it can be implemented in anjuta-tags.

And what should be the output of ctags in this case to support scope?
Comment 9 Massimo Cora' 2012-01-06 15:08:54 UTC
in case of a C file like this one:

struct {

	int a;
	char *b;

} FooStruct;



void main ()
{
}


you have: ctags --fields=afmiKlnsStz  main.c

FooStruct       main.c  /^} FooStruct;$/;"      kind:variable   line:9  language:C      typeref:struct:__anon1
a       main.c  /^      int a;$/;"      kind:member     line:6  language:C      struct:__anon1  file:   access:public
b       main.c  /^      char *b;$/;"    kind:member     line:7  language:C      struct:__anon1  file:   access:public
main    main.c  /^void main ()$/;"      kind:function   line:13 language:C


In a Cpp file instead:

class FooA {
        FooA ();

        private:
        void fooa_func () { }        
};




class FooB {
        FooB ();

        private:
        FooA *m_fooA;
};


int main()
{
        return 0;
}

anjuta-tags --fields=afmiKlnsStzT  main.cpp
(note the added "T" parameter)

FooA    main.cpp        /^class FooA {$/;"      kind:class      line:1  language:C++    file:
FooB    main.cpp        /^class FooB {$/;"      kind:class      line:13 language:C++    file:
fooa_func       main.cpp        /^      void fooa_func () { }$/;"       kind:function   line:6  language:C++    class:FooA      file:   access:private  signature:()    returntype:void
m_fooA  main.cpp        /^      FooA *m_fooA;$/;"       kind:member     line:17 language:C++    class:FooB      file:   access:private
main    main.cpp        /^int main()$/;"        kind:function   line:21 language:C++    signature:()    returntype:int
Comment 10 Sébastien Granjoux 2012-01-06 19:00:46 UTC
Thanks so in my example it should output something like

child   test.verilog    /^module child (i, j);$/;"      kind:module     line:1 language:Verilog
i       test.verilog    /^  input i;$/;"        kind:port       line:2 
language:Verilog     parent:child
i       test.verilog    /^  input i;$/;"        kind:port       line:9 
language:Verilog     parent:parent
j       test.verilog    /^  output j;$/;"       kind:port       line:10
language:Verilog     parent:parent
j       test.verilog    /^  output j;$/;"       kind:port       line:3 
language:Verilog     parent:child
k       test.verilog    /^  output k;$/;"       kind:port       line:11
language:Verilog     parent:parent
parent  test.verilog    /^module parent (i, j, k);$/;"  kind:module     line:8 
language:Verilog
u1       test.verilog    /^  child u1 (j, i);$/;"       kind:instance   line:12 
language:Verilog     parent:parent     module:child      
u2       test.verilog    /^  child u2 (k, i);$/;"       kind:instance   line:13
language:Verilog     parent:parent     module:child

I have the parent and module fields and a instance kind. How much is it for you to use such output? Could it be easier by doing it in another way?

In the sample above, it seems that even for C++, if you create a new variable of type FooA, ctags doesn't mark this variable with the type FooA. I think it will be useful, it's what I have tried to do with the module field.

The parent field is similar to the class field.
Comment 11 Massimo Cora' 2012-01-08 22:45:19 UTC
(In reply to comment #10)
> Thanks so in my example it should output something like
> 
> child   test.verilog    /^module child (i, j);$/;"      kind:module     line:1
> language:Verilog
> i       test.verilog    /^  input i;$/;"        kind:port       line:2 
> language:Verilog     parent:child
> i       test.verilog    /^  input i;$/;"        kind:port       line:9 
> language:Verilog     parent:parent
> j       test.verilog    /^  output j;$/;"       kind:port       line:10
> language:Verilog     parent:parent
> j       test.verilog    /^  output j;$/;"       kind:port       line:3 
> language:Verilog     parent:child
> k       test.verilog    /^  output k;$/;"       kind:port       line:11
> language:Verilog     parent:parent
> parent  test.verilog    /^module parent (i, j, k);$/;"  kind:module     line:8 
> language:Verilog
> u1       test.verilog    /^  child u1 (j, i);$/;"       kind:instance   line:12 
> language:Verilog     parent:parent     module:child      
> u2       test.verilog    /^  child u2 (k, i);$/;"       kind:instance   line:13
> language:Verilog     parent:parent     module:child
> 
> I have the parent and module fields and a instance kind. How much is it for you
> to use such output? Could it be easier by doing it in another way?
> 

well, the output should be read by readtags.[c|h] library. It's provided with ctags, and as such it must comply with its output format.

> In the sample above, it seems that even for C++, if you create a new variable
> of type FooA, ctags doesn't mark this variable with the type FooA. I think it
> will be useful, it's what I have tried to do with the module field.
> 

Unfortunately, ctags doesn't recognize that.
I've written sdb_engine_extract_type_qualifier () in symbol-db-engine-core.c to supply that missing feature.
Comment 12 Sébastien Granjoux 2012-01-09 19:51:04 UTC
(In reply to comment #11)
> well, the output should be read by readtags.[c|h] library. It's provided with
> ctags, and as such it must comply with its output format.

Well, the sample output above should be parsable by the readtags library. It seem that the key name are not hardcoded.


> Unfortunately, ctags doesn't recognize that.
> I've written sdb_engine_extract_type_qualifier () in symbol-db-engine-core.c to
> supply that missing feature.

I think it would be better to add this in ctags. Anyway, ctags is currently changing very slowly, I think I can add this in anjuta-tags. Do you see any issue for using this in the symbol-db plugin?
Comment 13 Massimo Cora' 2012-01-11 16:33:34 UTC
(In reply to comment #12)
> (In reply to comment #11)
> > well, the output should be read by readtags.[c|h] library. It's provided with
> > ctags, and as such it must comply with its output format.
> 
> Well, the sample output above should be parsable by the readtags library. It
> seem that the key name are not hardcoded.
> 

here
http://ctags.sourceforge.net/EXTENDING.html
they explain how to add support for a new language. I think you would need a two step parsing to identify the type of "u1" and u2. But still I think I'd be better if the regex on the type is applied by symbol-db engine, coz it's some logic that doesn't belong to ctags itself.

> 
> > Unfortunately, ctags doesn't recognize that.
> > I've written sdb_engine_extract_type_qualifier () in symbol-db-engine-core.c to
> > supply that missing feature.
> 
> I think it would be better to add this in ctags. Anyway, ctags is currently
> changing very slowly, I think I can add this in anjuta-tags. Do you see any
> issue for using this in the symbol-db plugin?

definetely don't add to ctags - it's a dead project, even if there are some spurious signals of life.
Add it to anjuta-tags please.

As for the displaying:
You would obtain something like 

+ u1
  i 
  j

+ u2
  i
  j

+ parent
  i
  j
  k
  u1
  u2


With some work it would be to set the children u1 and u2 expandable.
Comment 14 Sébastien Granjoux 2012-01-11 20:43:07 UTC
(In reply to comment #13)
> http://ctags.sourceforge.net/EXTENDING.html
> they explain how to add support for a new language. I think you would need a
> two step parsing to identify the type of "u1" and u2. But still I think I'd be
> better if the regex on the type is applied by symbol-db engine, coz it's some
> logic that doesn't belong to ctags itself.

Thanks, I will look at this. verilog looks like C but it has a more primitive syntax. It's perhaps possible to avoid this two steps parsing. My first idea was to keep everything specific to the language in ctags but I will look at this.


> definetely don't add to ctags - it's a dead project, even if there are some
> spurious signals of life. Add it to anjuta-tags please.

Sure.


> As for the displaying:
> You would obtain something like 
> + u1
>   i 
>   j
> 
> + u2
>   i
>   j
> + parent
>   i
>   j
>   k
>   u1
>   u2
> With some work it would be to set the children u1 and u2 expandable.

For such case a typical organization is to display the children u1 and u2 only inside parent. So keep at the top level only modules which are not instantiated anywhere. In a common case there is only one top module, any other modules are probably something unused which can be removed.


Anyway, I will try to take a look at this. But I'm currently still working on the project manager so I think it will be rather in one or two months.
Comment 15 Sébastien Granjoux 2012-01-24 21:48:38 UTC
Created attachment 206030 [details] [review]
A small improvement in anjuta-tags to support scope in verilog

I have looks the code parsing the verilog in ctags and it's very simple. It probably doesn't handle all possible cases, but it's already a start and it is easy to improve. 

So, I have added a module keyword defining in which module a tag is defined. I haven't checked instances defined inside a module, so I don't need a module tree view for the moment. I would like to have only the tags defined in a module represented as children of the corresponding module. Could you do it? or I can try to do it myself with your support.

This will need additional change, so we can create a new branch for this work but I'm not sure it's necessary because it's a new feature, we don't break anything, and it could be done by small steps.

The patch contains a few obvious changes in other plugin to support verilog. The mime data base needs to define a text/x-verilog type for file with .v extension at least.
Comment 16 Sébastien Granjoux 2012-01-24 21:49:58 UTC
Created attachment 206031 [details]
A small verilog sample to check the code
Comment 17 Massimo Cora' 2012-01-26 23:15:28 UTC
I'll be able to check it out as soon as next week
Comment 18 Massimo Cora' 2012-02-02 23:08:30 UTC
considering that I don't know verilog, I need some info: do the declared modules need to be unique?

Is module a 'container'? e.g. does it define a scope?

what about register and port? are they simple variables as int and char?

Based on the info you are outputting in tags file there could already be some points to retrieve the scope of a, say, declared variable register.
The simple trick is to order by row the tuples of the db for that file. The scope of a variable is the nearest module that's declared above.

If the verilog instead is more complex, e.g. have headers or structures are deployed on more than a file, then more detailed info about the symbols are needed. 
You can for instance associate to which module a variable belongs to.
I suppose that while scanning with anjuta-tags once you encounter a module you set some flag as - I'm on module X. The next variables you encounter can be associated with that module, until a new module is found.
Comment 19 Sébastien Granjoux 2012-02-03 20:07:16 UTC
(In reply to comment #18)
> considering that I don't know verilog

Sure.


>I need some info: do the declared modules need to be unique?

Yes, all module names must be unique in a global scope. Then in a project you often have several modules with the same name. A project typically include several simulation and a simulation is similar to a test project like libanjuta/tests/anjuta-tabber-test and libanjuta/tests/anjuta-token-test which both have a different main function.


> Is module a 'container'? e.g. does it define a scope?

Yes. It's similar to a C function.


> what about register and port? are they simple variables as int and char?

port and register is not a type like int or char. It defined rather the usage of the thing.
A port is a connection with the outside. If you consider module as function, it corresponds to the arguments of the function. You can have an input, and output or an inout port.
A register is a internal connection which can keep its own state, it can work as a 1 bit memory.
There is none is my example but you can have "wire" which are internal connection which cannot keep their state. This is the default type.


> Based on the info you are outputting in tags file there could already be some
> points to retrieve the scope of a, say, declared variable register.
> The simple trick is to order by row the tuples of the db for that file. The
> scope of a variable is the nearest module that's declared above.

Yes, but it's useful to have a hierarchy for this, contrary to C function arguments you can have a hundred of ports. It could be perhaps better to create a parent for all ports so you can hide all of them.

It we continue this analogy with a C function, a module can include instantiation of another modules, like a C function can call other functions. Having this "call graph" is very useful.


> If the verilog instead is more complex, e.g. have headers or structures are
> deployed on more than a file, then more detailed info about the symbols are
> needed. 

No, I don't think so. There are some extension to verilog, adding oriented object construct and so on, but the basis are really simple, simpler than C.


> You can for instance associate to which module a variable belongs to.
> I suppose that while scanning with anjuta-tags once you encounter a module you
> set some flag as - I'm on module X. The next variables you encounter can be
> associated with that module, until a new module is found.

Yes, I have done it like this in the attached anjuta-tag patch. There is even an end module marker so it's quite easy.
Comment 20 André Klapper 2020-11-06 20:22:58 UTC
bugzilla.gnome.org is being replaced by gitlab.gnome.org. We are closing all old bug reports in Bugzilla which have not seen updates for many years.

If you can still reproduce this issue in a currently supported version of GNOME (currently that would be 3.38), then please feel free to report it at https://gitlab.gnome.org/GNOME/anjuta/-/issues/

Thank you for reporting this issue and we are sorry it could not be fixed.