Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When an error is encountered, provide the include trace/stack/whatever #50

Open
eternaleye opened this issue Jul 26, 2016 · 11 comments
Open

Comments

@eternaleye
Copy link

The error in #49 may be harder to eliminate than necessary, as I can't tell how the project arrived at the (very, very internal to the C library) header in question.

@jameysharp
Copy link
Owner

It would be great to be able to report the include stack! (For what it's worth, byteswap.h is included somehow from stdlib.h, so that was a pretty common problem.)

The language-c parser requires running GCC first to preprocess the source code, and it isn't easy to work out the include stack after preprocessing.

I suspect the most practical option is to provide documentation on using gcc -M to figure out which headers a source file uses, or something along those lines. Do you have any suggestions?

@eternaleye
Copy link
Author

eternaleye commented Jul 29, 2016

It seems like this may be doable simply from the source file itself, presuming Language.C doesn't throw the relevant info away:

https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html

gcc -E puts these directives into the output:

# linenum filename flags

The (space-separated) flags are:

  1. Begin a new file
  2. Return to a file after an included file ends
  3. Came from a system header file
  4. Should be considered to be wrapped in extern "C" (irrelevant for Corrode, as it lacks C++)

As a result, you can simply treat "1" as "push" (with "3" setting a flag on it), "2" as "pop", and any directive with neither replaces the top-of-stack - that gives you the full include stack.

Then, at each newline that does not end such a directive, increment the line number of the current top of the stack.

EDIT: Oh, hm. Looks like Language.C mishandles this - fixing it would require altering Language.C.Data.Position to have a posParent or posCause member which is itself a Maybe Position so as to form the include stack, and then track it that way.

@eternaleye
Copy link
Author

eternaleye commented Jul 29, 2016

Another alternative would be to use the libClang bindings, but that would be... big. However, the unified preprocessor would make some things easier (e.g. the use of #define for constants).

@jameysharp
Copy link
Owner

I had no idea what those extra numbers meant. That's fascinating!

In addition to changing the representation of Position, you'd need to change language-c's lexer to capture the extra fields, which you'd do in the implementation of adjustLineDirective.

I'd encourage you to open an issue on visq/language-c and see what that project's current maintainer thinks.

Regarding libClang bindings: I tried that first, from Rust rather than Haskell, even. They are worthless for this project because they can't report the structure of expressions. It seems to me that the authors of libClang pushed it far enough to support Xcode's code completion needs and then stopped, or something along those lines.

@eternaleye
Copy link
Author

Already opened the ticket :P

@eternaleye
Copy link
Author

Also, huh, really? Entity::get_children() when EntityKind is one of the *Expr kinds doesn't work? That's pretty surprising.

@jameysharp
Copy link
Owner

Getting the children worked fine. As I recall, what I couldn't get was "which operator is this binop?", and also "I know you're looking at a variable reference. Why are you telling me the expression type is 'unknown'?" At that point I gave up...

Ah, I see you've filed visq/language-c#12. Excellent! I look forward to hearing how that goes.

@eternaleye
Copy link
Author

eternaleye commented Jul 29, 2016

Hm, the C++ libClang seems to support that via getOpcode() on the BinaryOperator subclass of Expr - seems like that's just not been wired up in Rust (no idea about Haskell). I'll file a ticket on the crate.

@jameysharp
Copy link
Owner

I'm pretty sure it's libclang's C API that's missing that functionality, so there's nothing the Rust or Haskell bindings could do about it. At least, I couldn't find anything in the libclang documentation about it. But I didn't try, you know, asking anybody who might actually know what to do about it before I gave up and used the C parser I already understood—so you may have better luck. 😄

@eternaleye
Copy link
Author

Seems upstream's implemented support; just waiting on memory impact before merge :D

@eternaleye
Copy link
Author

eternaleye commented Sep 13, 2017

And upstream seems to have merged the change! 😄

0.7.0 is out with support for the include stack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants