Author Topic: Code completion doesnt follow #include in struct  (Read 37832 times)

Offline zacaj

  • Single posting newcomer
  • *
  • Posts: 5
Code completion doesnt follow #include in struct
« on: March 02, 2011, 11:14:34 pm »
I posted this in the bug tracker, and was told to post here

object.h:
Code
typedef struct
{
#include "object_struct.h"
} Object;
object_struct.h:
Code
    vec3f pos; ///< The 3D position of the object
    vec3f lpos; ///< The 3D position of the object last update
    float r; ///< The radius of the Object
    uchar type; ///< Used to identify if the Object has been inherited
Quaternion q; ///< The rotation of the Object, as a Quaternion
void *data; ///< Pointer to the data used by this object for rendering
main.c:
Code
#include "object.h"

int main()
{
  Object *object=malloc(sizeof(Object));
  object->ty//HERE
}
after typing ty at //HERE type will not be suggested, nor will any other member of Object

This is even more annoying if you have another object 'inherit' Object:
enemy.h:
Code
typedef struct
{
  #include "object_struct.h"
  float hp;
} Enemy
main.c:
Code
#include "enemy.h"

int main()
{
  Enemy *enemy=malloc(sizeof(Enemy));
  object->//HERE
}
Code completion will automatically complete with hp (I know this can be turned off, but its useful in lots of other cases)
« Last Edit: March 02, 2011, 11:46:41 pm by zacaj »

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Code completion doesnt follow #include in struct
« Reply #1 on: March 02, 2011, 11:56:50 pm »
C::B version, OS version?
If C::B is <=10.05 then try some of the latest nightlies...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6076
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion doesnt follow #include in struct
« Reply #2 on: March 03, 2011, 01:44:31 am »
@zacaj
Ok, I know why cc does not show it's member.
Because Currently, CC's parser dose not do a full preprocessor. I mean, both files were parsed separately, so, the members in "object_struct.h" will be added to "global namespace" instead of the struct.  :D

It is too hard to implement a full parser. so the bug can't finished soon. The most reasonal way in the feature was: gcc/clang, those two were all compilers, so they do a full parse on your code.
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 zacaj

  • Single posting newcomer
  • *
  • Posts: 5
Re: Code completion doesnt follow #include in struct
« Reply #3 on: March 03, 2011, 09:53:32 pm »
C::B rev 6992, Windows 7 32 bit

Is the CC parser custom?  A full preprocessor does seem like it would be complex, but it doesnt seem (at least in my mind, I havent looked at the code) like it should be that hard to jump into another file if its included and just keep reading from there

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Code completion doesnt follow #include in struct
« Reply #4 on: March 03, 2011, 10:37:24 pm »
zacaj: Why don't you use proper inheritance? Yes, C has it, too.

It is something like:

Code
typedef struct A
{
     members of A;
};

typedef struct B {
    A base;
    members of B;
};
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline zacaj

  • Single posting newcomer
  • *
  • Posts: 5
Re: Code completion doesnt follow #include in struct
« Reply #5 on: March 04, 2011, 09:55:39 pm »
Because that looks really weird.  I use it in less used classes, but for something as common as Object, I dont want to have to type an extra ->base-> every time I change the position

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6076
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion doesnt follow #include in struct
« Reply #6 on: March 22, 2011, 02:50:18 pm »
Because that looks really weird.  I use it in less used classes, but for something as common as Object, I dont want to have to type an extra ->base-> every time I change the position
I think we can not solve your problem unless we use a full preprocessor/parser framework.  :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 JGM

  • Lives here!
  • ****
  • Posts: 518
  • Got to practice :)
Re: Code completion doesnt follow #include in struct
« Reply #7 on: March 23, 2011, 07:57:00 am »
some weeks ago I started working on a simple to use cpp parser mainly a prepreocessor just for fun. I worked on it about 2 days and was fixing some special cases where the parser wouldn't parse some things as it should do, so some code is commented out since I was debugging it, I was developing it on ubuntu and only using c/c++ standard libraries. I was programming it on a way that the preprocessor would return the final code as it should look for normal parsing and each elements on the code tokenized and identified by enums. Also I did some function place holders for expressions parsing and other things left to do. So if someone is interested on checking it out I uploaded the code to mediafire on a zip file:

http://www.mediafire.com/?yqvsstq23jot650

Comments and suggestions are welcome, I stopped after reading about clang with all it's advanced features, but if someone thinks this could be useful a spark of motivation may come to light xD (i gave up but then thought that the code may be of some use, and I think I was implementing it on a way not so hard to maintain for the future, but after all I'm a noob xD)

Edit: whoa I reached post 500  :D
« Last Edit: March 23, 2011, 07:58:44 am by JGM »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6076
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion doesnt follow #include in struct
« Reply #8 on: March 23, 2011, 08:16:40 am »
nice work, I am downloading your code and do some checking.

I know clang was a full preprocessor/parser framework. but it was too complex, and it was released under BSD style license. And finally I switch my mind to gcc. I have read the gcc's cpp internal manual (development manual), and found that developing a preprocessor was really complex.

the advantage of a full preprocessor/parser framework is that it has one AST tree for every translation unit, so, it is precise, but slow.
and currently cc's implementation is: parse every file only once, and collect every token to a single tree, just like ctags did, even there are some files missing, cc's parser still do some guess and continue parsing.

for a preprocessor framework, I remembered that One c::b developer  has implemented a preprocessor(but it was hard to read for me)



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: 6076
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion doesnt follow #include in struct
« Reply #9 on: March 23, 2011, 08:32:25 am »
Comments and suggestions are welcome, I stopped after reading about clang with all it's advanced features, but if someone thinks this could be useful a spark of motivation may come to light xD (i gave up but then thought that the code may be of some use, and I think I was implementing it on a way not so hard to maintain for the future, but after all I'm a noob xD)
here are my two point
1, I think using a generated lexer will make things much easier. a generated lexer can handle somethings like: line counting, column counting, and it use a state machine which will catch the "keyword" much faster than "clang or gcc". (both clang and gcc does not distinguish between a keyword or an identifier, they just do a hashtable search when an identifier returned), from this point, I'd suggest my work on Quex based lexer. ( I do benchmarks showing that it was 200% as the speed of flex generated lexer under windows). I put the test code here( also it include a clang test project to test codecompletion feature of clang )
http://code.google.com/p/quexparser/
would you like to have a look?

2, I found you use std::vector in the code, does std::list is much better? when doing a macro replacement, a vector will always re-size itself.

Currently, I feel a little confused about my quexparser, I do not have a clean direction, I found that even doing a macro replacement need many tricky.
you can look at
http://gcc.gnu.org/onlinedocs/cppinternals/
« Last Edit: March 23, 2011, 09:06:07 am by 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.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Code completion doesnt follow #include in struct
« Reply #10 on: March 23, 2011, 09:03:47 am »
2, I found you use std::vector in the code, does std::list is much better? when doing a macro replacement, a vector will always re-size itself.
Or probably a std::deque :) -> http://www.gotw.ca/publications/mill10.htm
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9720
Re: Code completion doesnt follow #include in struct
« Reply #11 on: March 23, 2011, 02:54:52 pm »
some weeks ago I started working on a simple to use cpp parser mainly a prepreocessor just for fun.
[...]
http://www.mediafire.com/?yqvsstq23jot650
I cannot test it atm, but do you mean "a preprocessor", or "for preprocessors?

My recent idea concerning preprocessor was using tools like:
http://dotat.at/prog/unifdef/
(...and there are other going in the same direction like "sunifdef") to "clean up" source files in a pre-process and parse what's left. If we do this in memory it should also be pretty fast.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline JGM

  • Lives here!
  • ****
  • Posts: 518
  • Got to practice :)
Re: Code completion doesnt follow #include in struct
« Reply #12 on: March 23, 2011, 06:54:54 pm »
...
1, I think using a generated lexer will make things much easier. a generated lexer can handle somethings like: line counting, column counting, and it use a state machine which will catch the "keyword" much faster than "clang or gcc". (both clang and gcc does not distinguish between a keyword or an identifier, they just do a hashtable search when an identifier returned), from this point, I'd suggest my work on Quex based lexer. ( I do benchmarks showing that it was 200% as the speed of flex generated lexer under windows). I put the test code here( also it include a clang test project to test codecompletion feature of clang )
http://code.google.com/p/quexparser/
would you like to have a look?
...

I started writing a custom tokenizer for the preprocessor since I thought the output would be much simple to analyze on the future and also I wanted it to be smart and produce a tree more easy to analyze. Also I wanted to produce the cleaned code after preproccessing with correct column and line numbers for the code parser as optimizable if possible. Still I need to correctly manage multiple line preprocessors (#define blah blah(123) \).

Whoa! that quexparser looks a little kind of complex for my brain to digest I will try to analyze it deeply.

...
2, I found you use std::vector in the code, does std::list is much better? when doing a macro replacement, a vector will always re-size itself.
...

2. I have read several c++ books and read about the performance on available containers as inner structure but I always forget the differences on each of them :( (lack of practice) but it may be easy to substitute since containers almost always share same interface (I think)

Currently, I feel a little confused about my quexparser, I do not have a clean direction, I found that even doing a macro replacement need many tricky.
you can look at
http://gcc.gnu.org/onlinedocs/cppinternals/

Yep, this whole c++ parsing thing is hard since the language itself has so many features to look up, but it is fun, I just wanted to create a simple to use preprocessor after several months of c++ inactivity on my blood.

Offline JGM

  • Lives here!
  • ****
  • Posts: 518
  • Got to practice :)
Re: Code completion doesnt follow #include in struct
« Reply #13 on: March 23, 2011, 07:35:27 pm »
some weeks ago I started working on a simple to use cpp parser mainly a prepreocessor just for fun.
[...]
http://www.mediafire.com/?yqvsstq23jot650
I cannot test it atm, but do you mean "a preprocessor", or "for preprocessors?

My recent idea concerning preprocessor was using tools like:
http://dotat.at/prog/unifdef/
(...and there are other going in the same direction like "sunifdef") to "clean up" source files in a pre-process and parse what's left. If we do this in memory it should also be pretty fast.


yep a preprocessor, with the future goal of complete parser. (my english vocabulary and game of words suck  :P)

Current logic is to identify preprocessor type when tokenizing (function ex: #define test(x) (x*2) or just a declaration ex #define test_delcared) add it to a vector to then make correct replacements on code to parse it correctly. Actually nested preprocessors as I tested worked correctly, I was fixing some issues with multiple line preprocessors (handle incorrectly to produce correct line and column positions) and then write an expression parser to evaluate macro expressions. Also include files are parsed only once as normally, it handles global and local includes and you can indicate to the class the paths to search. Also the use of string class should be replaced by the wstring one, but since I was playing around at first there are things to be improved.

I wanted to have a much complete and documented code before posting it but well, after reading some threads here I decided to let it go as it is and see if it is understandable by other developers, wishing for the best. The main.cpp file should serve as an example of how I intended to make use of it. If people think the code is not that hard to understand then it may merit it's completeness.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6076
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion doesnt follow #include in struct
« Reply #14 on: March 24, 2011, 06:14:36 am »
some weeks ago I started working on a simple to use cpp parser mainly a prepreocessor just for fun.
[...]
http://www.mediafire.com/?yqvsstq23jot650
I cannot test it atm, but do you mean "a preprocessor", or "for preprocessors?

My recent idea concerning preprocessor was using tools like:
http://dotat.at/prog/unifdef/
(...and there are other going in the same direction like "sunifdef") to "clean up" source files in a pre-process and parse what's left. If we do this in memory it should also be pretty fast.

I briefly read the site: unifdef - selectively remove C preprocessor conditionals
it said:
Quote
It is useful for avoiding distractions when studying code that uses #ifdef heavily for portability (the original motivation was xterm's pty handling code), or as a lightweight preprocessor to strip out internal routines from a public header (the Linux kernel uses unifdef to strip out #ifdef __KERNEL__ sections from the headers it exports to userland)
Great, I think we need a lightweight preprocessor, as my point of view, gcc's preprocessor code base was too big and too complex.
The main two job is:
1, handle conditional preprocessor directive, like #if  and do a expression evaluation.
2, do macro expansion

In fact this two method was done in the current implementation of cc, but I think they need to be refactored. Morten, can you give a direction?

@JGM
quex's lexer generator is quite easy to lean, and it's grammar is very easy to learn. once you use this, you can give(retern) a token once a time. the token contains several information include at least four field.
1, token id (identifier, keyword, open-bracket......)
2, string value if it is an identifier, otherwise, it is empty
3, column count value
4, line count value

then you don't care about anything else, you just use the token, and do everything you like. So, quex's lexer stands on a low level, and you can implement the high level preprocessor on that.

I have implement a const value expression solver by "shunting yard algorithm" on the code. There is a quite similar one in the CC's source code. We can have further discussion to collaborate.
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.