[cfe-dev] clang_parseTranslationUnit2(), "true", and libclang's header search path

Emilio Cobos Álvarez via cfe-dev cfe-dev at lists.llvm.org
Sat Jun 3 10:44:34 PDT 2017



On 06/03/2017 01:48 PM, W. Michael Petullo via cfe-dev wrote:
> I am writing a program which parses other programs written in C. When
> I run my program, I find that it fails to find some key system headers
> such as stdbool.h. When "true" is present in the parsed program, the
> AST appears to be incomplete. When I replace "true" with "1" in the
> parsed program, the AST is complete.
> 
> I have written a minimal example which follows at the end of this email. 
> 
> The "good" input program is:
> 
> 1  #include <stdbool.h>
> 2  #include <stdio.h>
> 3
> 4  int
> 5  main(int argc, char *argv[])
> 6  {
> 7          while (1) {
> 8                  printf("Hello, world!\n");
> 9          }
> 10 }
> 
> For this, the attached program produces:
> 
> [...]
> LINE 5
> LINE 5
> LINE 5
> LINE 6
> LINE 7
> LINE 7
> LINE 7
> LINE 8
> LINE 8
> LINE 8
> LINE 8
> LINE 8
> LINE 8
> DONE
> 
> The "bad" input program is:
> 
> 1  #include <stdbool.h>
> 2  #include <stdio.h>
> 3
> 4  int
> 5  main(int argc, char *argv[])
> 6  {
> 7          while (true) {
> 8                  printf("Hello, world!\n");
> 9          }
> 10  }
> 
> For this, the attached program produces:
> 
> [...]
> LINE 5
> LINE 5
> LINE 5
> LINE 6
> DONE
> 
> All of this appears to follow from my program failing to find stdbool.h. I
> used strace to discover that libclang seems to search
> 
> 	/usr/local/include/,
> 	/usr/include/, and
> 	/include/
> 
> but not
> 
> 	/usr/lib64/clang/3.9.1/include/.
> 
> The last directory is where clang installed its headers, so I am
> surprised that libclang does not look there.
> 
> Is the expectation that I discover /usr/lib64/clang/3.9.1/include/
> and pass -I/usr/lib64/clang/3.9.1/include/ to my program?
> 
> Why does libclang not search clang's header directory by default?

FWIW I've seen this problem before too. The rust libclang bindings
"solve" this just trying to run |clang -E -x <lang> -v|, and parsing the
output[1], which is not only somewhat overkill, but also a fairly hacky
solution. It works well in practice though, AFAICT (I don't maintain
that library, but I use it).

I think it doesn't seem unreasonable, and if including them by default
would be breaking (which I guess it would), it may make sense to
retrieve the default include paths as a CXStringSet or something of the
sort.

That being said, I'm not sure how difficult to implement it would be, or
even if it's feasible without a clang binary around?

 -- Emilio

[1]: https://github.com/KyleMayes/clang-sys/blob/master/src/support.rs#L182



More information about the cfe-dev mailing list