Thread: [CEDET-devel] Problem with visibility pragmas before class declaration
Brought to you by:
zappo
From: David E. <de...@ra...> - 2009-04-16 20:07:58
|
I'm trying to use CEDET with the Xapian library, and semantic fails to parse most of the classes, since Xapian makes use of the new visibility attributes in gcc 4.x. For example: class __attribute__((visibility("default"))) foo { private: int bar; }; (This is not actual Xapian code, of course; I just reduced it to the basic problem.) Regards, David |
From: Eric M. L. <er...@si...> - 2009-04-16 20:19:04
|
>>> David Engster <de...@ra...> seems to think that: >I'm trying to use CEDET with the Xapian library, and semantic fails to >parse most of the classes, since Xapian makes use of the new visibility >attributes in gcc 4.x. > >For example: > >class __attribute__((visibility("default"))) foo { > private: > int bar; >}; > >(This is not actual Xapian code, of course; I just reduced it to the >basic problem.) [ ... ] Hi David, I think you can work around this using macros in Semantic to hide the new syntax. This simplest would be to create a magic header for semantic, perhaps like this: ------ hack.h ----- // Hacks for Emacs/Semantic #define __attribute__(thing) #define __other_attribute_gcc_might_have__(thing) ------- then you can configure semantic to use it by adding that to the semantic-lex-c-preprocessor-symbol-file variable. If the list of such exciting things is small, it would be most advantageous to others to add this to semantic-gcc.el, by detecting the new version of gcc, adding in macros for these items directly by writing in the parsed versions of these empty macros. I'd be happy to accept patches to semantic-gcc that adds in these new features. Eric -- Eric Ludlam: er...@si... Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net |
From: David E. <de...@ra...> - 2009-04-17 17:59:14
|
"Eric M. Ludlam" <er...@si...> writes: >>>> David Engster <de...@ra...> seems to think that: >>I'm trying to use CEDET with the Xapian library, and semantic fails to >>parse most of the classes, since Xapian makes use of the new visibility >>attributes in gcc 4.x. >> >>For example: >> >>class __attribute__((visibility("default"))) foo { >> private: >> int bar; >>}; >> >>(This is not actual Xapian code, of course; I just reduced it to the >>basic problem.) > This simplest would be to create a magic header for semantic, > perhaps like this: > > ------ hack.h ----- > // Hacks for Emacs/Semantic > > #define __attribute__(thing) > #define __other_attribute_gcc_might_have__(thing) > > ------- > > then you can configure semantic to use it by adding that to the > semantic-lex-c-preprocessor-symbol-file variable. Unfortunately, this doesn't seem to work. Even the following won't parse: #define __attribute__(thing) #define VISIBILITY __attribute__((visibility("default"))) class VISIBILITY foo { int bar; }; And the funny thing is: it only fails with "__attribute__"; take anything else ("__foo__"), and it will parse the class just fine. In any case, it seems to me the lexer knows very well what __attribute__ is. For example, if I run semantic-lex-spp-describe on the above, I see the line Macro Value FOO ((__ATTRIBUTE__ "__attribute__" 42 . 55) (semantic-list "((visibility(\"default\")))" 55 . 80)) -David |
From: David E. <de...@ra...> - 2009-04-17 18:07:31
|
David Engster <de...@ra...> writes: > Macro Value > FOO ((__ATTRIBUTE__ "__attribute__" 42 . 55) (semantic-list "((visibility(\"default\")))" 55 . 80)) Sorry, that should of course read VISIBILITY ((__ATTRIBUTE__ "__attribute__" 49 . 62) ... -David |
From: Eric M. L. <er...@si...> - 2009-04-17 19:10:02
|
>>> David Engster <de...@ra...> seems to think that: >"Eric M. Ludlam" <er...@si...> writes: >>>>> David Engster <de...@ra...> seems to think that: >>>I'm trying to use CEDET with the Xapian library, and semantic fails to >>>parse most of the classes, since Xapian makes use of the new visibility >>>attributes in gcc 4.x. >>> >>>For example: >>> >>>class __attribute__((visibility("default"))) foo { >>> private: >>> int bar; >>>}; >>> >>>(This is not actual Xapian code, of course; I just reduced it to the >>>basic problem.) > >> This simplest would be to create a magic header for semantic, >> perhaps like this: >> >> ------ hack.h ----- >> // Hacks for Emacs/Semantic >> >> #define __attribute__(thing) >> #define __other_attribute_gcc_might_have__(thing) >> >> ------- >> >> then you can configure semantic to use it by adding that to the >> semantic-lex-c-preprocessor-symbol-file variable. > >Unfortunately, this doesn't seem to work. Even the following won't >parse: > >#define __attribute__(thing) >#define VISIBILITY __attribute__((visibility("default"))) > >class VISIBILITY foo { > int bar; >}; > >And the funny thing is: it only fails with "__attribute__"; take >anything else ("__foo__"), and it will parse the class just fine. > >In any case, it seems to me the lexer knows very well what __attribute__ >is. For example, if I run semantic-lex-spp-describe on the above, I see >the line > >Macro Value >FOO ((__ATTRIBUTE__ "__attribute__" 42 . 55) (semantic-list "((visibility(\"default\")))" 55 . 80)) Oh, you are right. I had completely forgotten about that. I guess that was added before the pre-processor support was any good. If the number of locations for __attribute__ is small, they could be added to the grammar. If the number is large, then we should probably pull it out of the parser and added it to the preprocessor table. Do you know how often this can be used? Right now it is only on functions in c.by. (See opt-attribute rule in c.by for more). Eric -- Eric Ludlam: er...@si... Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net |
From: David E. <de...@ra...> - 2009-04-18 09:07:49
|
"Eric M. Ludlam" <er...@si...> writes: >>>> David Engster <de...@ra...> seems to think that: >>In any case, it seems to me the lexer knows very well what __attribute__ >>is. For example, if I run semantic-lex-spp-describe on the above, I see >>the line >> >>Macro Value >>FOO ((__ATTRIBUTE__ "__attribute__" 42 . 55) (semantic-list "((visibility(\"default\")))" 55 . 80)) > > Oh, you are right. I had completely forgotten about that. I guess > that was added before the pre-processor support was any good. > > If the number of locations for __attribute__ is small, they could be > added to the grammar. If the number is large, then we should probably > pull it out of the parser and added it to the preprocessor table. > > Do you know how often this can be used? Right now it is only on > functions in c.by. (See opt-attribute rule in c.by for more). In general, you can have attributes for * Functions: void fatal () __attribute__ ((noreturn)); * Variables: int x __attribute__ ((aligned (16))) = 0; * Types: typedef int more_aligned_int __attribute__ ((aligned (8))); struct S { short f[3]; } __attribute__ ((aligned (8))); class __atribute__ ((visibility("default"))) foo; But the syntax can get pretty sophisticated, e.g. char *__attribute__((aligned(8))) *f; specifies the type "pointer to 8-byte-aligned pointer to char" Not sure if this can easily be incorporated into the grammar. Since CEDET should effectively just ignore them, I guess it's easier to put them into the preprocessor table? -David |
From: Eric M. L. <er...@si...> - 2009-04-18 12:17:32
|
I have checked in a change to remove it from the grammar, and add it to the default preprocessor table as a no-op. Let me know how it goes. Thanks Eric >>> David Engster <de...@ra...> seems to think that: >"Eric M. Ludlam" <er...@si...> writes: >>>>> David Engster <de...@ra...> seems to think that: >>>In any case, it seems to me the lexer knows very well what __attribute__ >>>is. For example, if I run semantic-lex-spp-describe on the above, I see >>>the line >>> >>>Macro Value >>>FOO ((__ATTRIBUTE__ "__attribute__" 42 . 55) (semantic-list "((visibility(\"default\")))" 55 . 80)) >> >> Oh, you are right. I had completely forgotten about that. I guess >> that was added before the pre-processor support was any good. >> >> If the number of locations for __attribute__ is small, they could be >> added to the grammar. If the number is large, then we should probably >> pull it out of the parser and added it to the preprocessor table. >> >> Do you know how often this can be used? Right now it is only on >> functions in c.by. (See opt-attribute rule in c.by for more). > >In general, you can have attributes for > >* Functions: > > void fatal () __attribute__ ((noreturn)); > >* Variables: > > int x __attribute__ ((aligned (16))) = 0; > >* Types: > > typedef int more_aligned_int __attribute__ ((aligned (8))); > struct S { short f[3]; } __attribute__ ((aligned (8))); > class __atribute__ ((visibility("default"))) foo; > >But the syntax can get pretty sophisticated, e.g. > > char *__attribute__((aligned(8))) *f; > >specifies the type "pointer to 8-byte-aligned pointer to char" > >Not sure if this can easily be incorporated into the grammar. Since >CEDET should effectively just ignore them, I guess it's easier to put >them into the preprocessor table? [ ... ] -- Eric Ludlam: er...@si... Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net |
From: David E. <de...@ra...> - 2009-04-18 13:05:06
|
"Eric M. Ludlam" <er...@si...> writes: > I have checked in a change to remove it from the grammar, and add it > to the default preprocessor table as a no-op. > > Let me know how it goes. Thank you. That seems to work fine, but now I stumbled upon another problem. Consider the following header and source file: ---- foo.h --- #define FOO -------------- ---- foo.cpp ---- #include <foo.h> class FOO bar { int i; }; ----------------- Semantic is unable to parse the class in foo.cpp. If I just put the "#define FOO" directly in foo.cpp, everything works fine. Regards, David |
From: Eric M. L. <er...@si...> - 2009-04-18 15:12:29
|
>>> David Engster <de...@ra...> seems to think that: >"Eric M. Ludlam" <er...@si...> writes: >> I have checked in a change to remove it from the grammar, and add it >> to the default preprocessor table as a no-op. >> >> Let me know how it goes. > >Thank you. That seems to work fine, but now I stumbled upon another >problem. Consider the following header and source file: > >---- foo.h --- >#define FOO >-------------- > >---- foo.cpp ---- >#include <foo.h> > >class FOO bar { > int i; >}; >----------------- > >Semantic is unable to parse the class in foo.cpp. If I just put the >"#define FOO" directly in foo.cpp, everything works fine. [ ... ] Hi, Semantic doesn't use #defines from every header referenced. That would be too slow in the general case. Instead, you need to specify which headers have #defines you care about. I think most projects have a limited number of core headers with #defines in them, so the list can be small. As such, in this example, you would add foo.h to the variable semantic-lex-c-preprocessor-symbol-file, or to the EDE equivalent, and that would allow this case to work. Eric -- Eric Ludlam: er...@si... Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net |
From: David E. <de...@ra...> - 2009-04-18 17:08:36
|
"Eric M. Ludlam" <er...@si...> writes: >>>> David Engster <de...@ra...> seems to think that: >>Consider the following header and source file: >> >>---- foo.h --- >>#define FOO >>-------------- >> >>---- foo.cpp ---- >>#include <foo.h> >> >>class FOO bar { >> int i; >>}; >>----------------- >> >>Semantic is unable to parse the class in foo.cpp. If I just put the >>"#define FOO" directly in foo.cpp, everything works fine. > Semantic doesn't use #defines from every header referenced. That > would be too slow in the general case. Instead, you need to specify > which headers have #defines you care about. I think most projects > have a limited number of core headers with #defines in them, so the > list can be small. Yes, but for external libraries it can be difficult to tell which header files are important. For example, for the Xapian library, it is xapian/visibility.h which contains the macro definition which enables CEDET to parse the classes correctly. This is of course a special case because of this __atribute__ stuff in the class declaration. > As such, in this example, you would add foo.h to the variable > semantic-lex-c-preprocessor-symbol-file, or to the EDE equivalent, and > that would allow this case to work. Thank you for this explanation. This does work in principal, but still has problems in practice. In the above example, when I load foo.cpp, the class "bar" is not parsed because foo.h was not parsed yet, so the lexer doesn't know that FOO is actually nil. I then fire up some completion to initiate parsing of foo.h, and I would assume that it should work afterwards, but it doesn't. Even reloading foo.cpp and running 'bovinate' doesn't do the trick. When I restart Emacs, load foo.cpp, it still doesn't parse the class, (I guess because it is using the cache?), but at least semantic-lex-spp-describe shows a definition of FOO now. When I then change something in foo.cpp, the class "bar" gets parsed correctly. Regards, David |