[cfe-dev] clang_parseTranslationUnit2(), "true", and libclang's header search path
W. Michael Petullo via cfe-dev
cfe-dev at lists.llvm.org
Sat Jun 3 04:48:18 PDT 2017
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?
Here is the program:
#include <clang-c/Index.h>
#include <stdio.h>
#include <stdlib.h>
const char *program;
const char *filename;
void
usage(const char *program)
{
fprintf(stderr, "usage: %s FILE.C\n", program);
exit(EXIT_FAILURE);
}
enum CXChildVisitResult
visit_children_cb(CXCursor cursor,
CXCursor parent,
CXClientData client_data)
{
CXFile file;
unsigned int line, column, offset;
unsigned int level = *(unsigned int *) client_data;
unsigned int next = level + 1;
clang_getSpellingLocation(clang_getCursorLocation(cursor),
&file,
&line,
&column,
&offset);
printf("LINE %d\n", line);
clang_visitChildren(cursor, visit_children_cb, &next);
return CXChildVisit_Continue;
}
int
main(int argc, const char * const* argv)
{
unsigned int level = 0;
CXIndex index;
enum CXErrorCode error;
CXTranslationUnit tu;
CXCursor cursor;
if (argc != 2) {
usage(program);
}
program = argv[0];
filename = argv[1];
index = clang_createIndex(1, 1);
error = clang_parseTranslationUnit2(index,
NULL,
argv,
argc,
NULL,
0,
0,
&tu);
if (CXError_Success != error) {
fprintf(stderr, "Failure parsing %s\n", filename);
exit(EXIT_FAILURE);
}
cursor = clang_getTranslationUnitCursor(tu);
clang_visitChildren(cursor, visit_children_cb, &level);
clang_disposeTranslationUnit(tu);
clang_disposeIndex(index);
printf("DONE\n");
exit(EXIT_SUCCESS);
}
--
Mike
:wq
More information about the cfe-dev
mailing list