I'm dumping the AST of some headers like this:
clang -cc1 -ast-dump -fblocks header.h
However, any #defines on the header are not showing on the dump. Is there a way of adding them?
It's true, #defines are handled by the preprocessor, not the compiler. So you need a preprocessor parser stage. I know of two:
Boost Wave can preprocess the input for you, and/or give you hooks to trigger on macro definitions or uses.
The Clang tool pp-trace uses a Clang library that can do callbacks on many preprocessor events, including macro definitions.
Related
I want to make target independent IR with LLVM.
clang -emit-llvm -S source.c -o source.ll
in source.ll
target datalayout = "e-m:e-i64:..."
target triple = "x86_64-pc-linux-gnu"
...
LLVM IR is said to be Target-independent, but the properties of the target are specified in the actual IR file.
How can I create an LLVM IR without this Target property?
Short answer: you cannot
Long answer: target-neutrality is the property of input language, not the LLVM IR. While in theory it is possible to make more or less target-neutral LLVM IR for some inputs it is not possible for C/C++ inputs. I will only mention few things that prevents us from having such LLVM IR:
Preprocessor. Target-specific #ifdef clauses obviously make resulting IR target-specific
Pointer sizes. Think about expressions like sizeof(void*). These are target-dependent compile-time constants (yes, there are ways to defer calculation of these constants later on, but this is not something frontends are prepared to deal with, this also hinders many optimizations)
Struct layout. Partly it depends on 2. (think about struct { int foo; void* bar; }
Various ABI-related things like necessary support steps for argument / result passing, etc.
I will not mention target-specific things like vectors, builtins for target-specific instructions sets, etc.
I am trying to do some analysis on Linux kernel source code using clang AST representation. But I found some statements in source are missing in clang AST.
The first picture is a snippet of the kernel source code. As we can see, there are 7 functions in the IfStmt.
Linux Source snippet
The second picture shows the result of clang -Xclang -ast-dump ~/mm/mmap.c, but there are only four functions. Three functions and four statements in yellow boxes are missing in AST representation. result of clang AST
I am running on Ubuntu 18.04, with clang9.0.0. Does anyone know what's going on?
Is there any frontend that will generate MLIR (not LLVM) code currently? I am interested in parsing C/C++ or Java code in particular. Does clang support this now? This page doesn't list any at the moment.
As of Oct 2020, compiling C++ into CIL (C intermediate language) mlir dialect is not public yet. But they will be making it available "soon".
This was hinted on this year on LLVM developers meeting (http://llvm.org/devmtg/2020-09/program/) on the following talk:
CIL : Common MLIR Dialect for C/C++ and Fortran - P. NR; V. M; Ranjith; Srihari
In case people are not aware, as an alternative if you just want your C/C++ code in the mlir environment is to compile your program into LLVM with clang -S -fno-discard-value-names -emit-llvm and then later use mlir-translate --import-llvm to transform your .ll file into a .mlir file. But you do lose some higher level information and the opportunity for higher level optimizations.
I have using function ParserAST() to get a AST ,but I don't know how to display the ast on my console(i am using vs 2017). And how can i using llvm to run the ast and get the information about the var value.
Try clang -Xclang -ast-dump -fsyntax-only test.c, if want to print AST.
And,
You cannot run your own AST on llvm. Instead, see LLVM-JIT.
I am parallelizing an existing FORTRAN application. I don't want to directly change parts of its code so I am using preprocessor directives to accomplish my goal. This way I am able to maintain the readability of the code and I won't induce errors in parts of the code that have already been tested. However, when I try to preprocess my source with the GNU C preprocessor I get the following error message (gcc version 4.7.2 (Debian 4.7.2-5)):
test.f:9:0: error: detected recursion whilst expanding macro "ARR""
This simple test program demonstrates my problem:
PROGRAM TEST
IMPLICIT NONE
INTEGER I,OFFSET,ARR(10)
#define ARR(I) ARR(OFFSET+I)
DO I=1,10
ARR(I)=I
END DO
#undef ARR(I)
END PROGRAM TEST
This is the commandline output:
testing$ gfortran -cpp -E test.f
# 1 "test.f"
# 1 "<command-line>"
# 1 "test.f"
PROGRAM TEST
[...]
test.f:9:0: error: detected recursion whilst expanding macro "ARR"
DO I=1,10
ARR(OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+I)=I
END DO
[...]
END PROGRAM TEST
This site provides some information on the preprocessor I am using:
http://tigcc.ticalc.org/doc/cpp.html#SEC10
As it seems I am using a function-like macro with macro arguments.
Why is the preprocessor detecting a recursion? [EDIT] - Maybe because I use the same name for Makro and Identifier?
Why isn't the preprocessor capable of interpreting upper case directives (#DEFINE instead of #define)? - I am asking, because I haven't had this problem with the ifort preprocessor.
BTW: I am able to preprocess the original code either using the ifort preprocessor -fpp, or by changing the source in the following way:
PROGRAM TEST
IMPLICIT NONE
INTEGER I,OFFSET,ARR(10)
#define ARR_T(I) ARR(OFFSET+I)
DO I=1,10
ARR_T(I)=I
END DO
#undef ARR_T(I)
END PROGRAM TEST
Why is the preprocessor detecting a recursion? [EDIT] - Maybe because I use the same name for Makro and Identifier?
The preprocessor is detecting recursion because your macro name and array name are the same.
Why isn't the preprocessor capable of interpreting upper case directives (#DEFINE instead of #define)? - I am asking, because I haven't had this problem with the ifort preprocessor.
When using gfortran, you are using a C preprocessor. #DEFINE is not a recognized preprocessor directive in C. No idea about ifort. I thought in ifort you had to prefix macros with !$MS or !$DEC.
Your change to the program to get it to work for ifort will also work for gfortran.