Decide if is the user is using gfortran or ifort - gfortran

I'm coding a code in modern Fortran, and I want to do some like:
IF (you are compiling the code with gfortran) Do something...
IF (you are compiling the code with ifort) Do other thing...
but I haven't found a way to verify those logic conditions in the IF statements inside the code.

The easiest way is to look at compiler-specific macros.
For gfortran, you can look at __GNUC__ as described here.
For ifort, you can look at __INTEL_COMPILER as described here.
If you have the file test.F90 (note the .F90 rather than .f90, it's important that this file is preprocessed), then you can have something like
program test
implicit none
#ifdef __GNUC__
logical, parameter :: gfortran = .true.
#else
logical, parameter :: gfortran = .false.
#endif
#ifdef __INTEL_COMPILER
logical, parameter :: ifort = .true.
#else
logical, parameter :: ifort = .false.
#endif
if (gfortran) then
write(*,*) 'gfortran'
elseif (ifort) then
write(*,*) 'ifort'
else
write(*,*) 'Unknown compiler'
endif
end program

Related

Disabling conditional macro evaluation in clang

#define NUM 1
#if(NUM)
if(globalglobalInteger){
result = 1;
}
#else
result=2
#endif
Given the above code , the requirement is that the conditional macro #if should not be evaluated and all code under #if and #else should be passed for further processing.
Basically I want both the active and inactive part(code under #if and code under #else) to be present in the clang AST.
Is this possible in clang ?
Is there any pre-processor flag available
for doing this in clang?
Saw that there is flag called -fdirectives-only in gcc which disables macro expansion but could not find similar flag in clang
Preprocessing takes places before parsing and AST generation, so you can't have
non-expanded defines and macros in the AST.
However, there are means for handling non-preprocessed code - such as registering to clang preprocessor callbacks (the PPCallbacks interface) or through the pp-trace tool
(disclamer: I don't have experience with this myself).
References:
Clang AST dump doesn't show #defines
http://clang-developers.42468.n3.nabble.com/Preprocessor-Parser-interaction-td3754583.html
http://www.llvm.org/devmtg/2016-11/Slides/Trull-ExtendingClangASTMatchers.pdf
With regards to flags, clang has no equivalent to gcc's -fdirectives-only. For keeping both parts of the macro in output,
you could disable preprocessing altogether, similar to gcc's -fpreprocessed - which will effectively disable macro expansion (but still macros will be absent from the AST).
You could insepct the AST generated for non-preprocessed source files with these commands:
clang -xcpp-output -Xclang -ast-dump -c foo.c
clang -xc++-cpp-output -Xclang -ast-dump -c foo.cpp
HTH - good luck!

Where can I find the definition of the macro __insn_dword_align that occurs in memcmp.c of the glibc source code project?

The implementation of function memcmp in glibc uses the macro DBLALIGN(eg, DBLALIG(a3, a0, srcli)) to compare two unsinged int integer. DBLALIGN is delcared as follows. However, the definition of __insn_dword_align is not found in glibc source codes. Where can I find it. Thank you!
#ifdef __tilegx__
#define DBLALIGN __insn_dblalign
#define REVBYTES __insn_revbytes
#else
#define DBLALIGN __insn_dword_align
#define REVBYTES __insn_bytex
#endif
It's a gcc builtin. See e.g. here.
I cannot find the definition
You wouldn't find a definition for any builtin. That's what "builtin" means: the compiler recognizes builtin by name and emits required instructions directly to assembly.

Getting bison parser to divulge debug information

I am having trouble writing a bison parser, and unexpectedly ran into difficulties getting the parser to print debug information. I found two solutions on the web, but neither seems to work.
This advocates to put this code in the main routine:
extern int yydebug;
yydebug = 1;
Unfortunately the C++ compiler detects an undefined reference to `yydebug'.
This suggests putting
#if YYDEBUG == 1
extern yydebug;
yydebug = 1;
#endif
into the grammar file. It compiles but does not produce output.
What does work is to edit the parser file itself, replacing
int yydebug;
by
int yydebug = 1;
The big disadvantage is that I have to redo this every time I change the grammar file, which during debugging would happen constantly. Is there any other way I can provoke the parser into coughing up its secret machinations?
I am using bison v2.4.1 to generate the parser, with the following command-line options:
bison -ldv -p osil -o $(srcdir)/OSParseosil.tab.cpp OSParseosil.y
Although the output is a C++ file, I am using the standard C skeleton.
With bison and the standard C skeleton, to enable debug support you need to do one of the following:
Use the -t (Posix) or --debug (Bison extension) command-line option when you create your grammar. (bison -t ...)
Use the -DYYDEBUG=1 command-line option (gcc or clang, at least) when you compile the generated grammar (gcc -DYYDEBUG=1 parser.tab.c ...`).
Add the %debug directive to your bison source
Put #define YYDEBUG 1 in the prologue in your bison source (the part of the file between %{ and %}.
I'd use -t in the bison command line. It's simple, and since it is Posix standard it probably will also work on other derived parser generators. However, adding %debug to the bison source is also simple; while it is not as portable, it works in bison 2.4.
Once you've done that, simply setting yydebug to a non-zero value is sufficient to produce debug output.
If you want to set yydebug in some translation unit other than the generated parser itself, you need to be aware of the parser prefix you declared in the bison command line. (In the parser itself, yydebug is #defined to the prefixed name.) And you need to declare the debug variable (with the correct prefix) as extern. So in your main, you probably want to use:
extern int osildebug;
// ...
int main(int argc, char** argv) {
osildebug = 1;
// ...
}
If you're using bison, your best place to find information is the bison manual; most of the above answer will be found in that page.

XC8 warning: (107) illegal # directive "foo"

I have a fair bit of code written to compile under various build systems (e.g. CCS, Visual C, Embarcadero CBuilder, Microchip XCn). Since the various compilers differ in how they define things like inline or interrupt routines, I use #if/#elif/#else constructs to satisfy their requirements. The GCC preprocessor documentation even suggests this as a good use for #if etc.
In the case of my microprocessor build tools, the CCS family of compilers, and XC16 (gcc-based) deal with this just fine, but XC8 insists on looking inside a non-active #if blocks and generating warnings.
For example, the code
#ifdef _COMPILER_CCS
#INT_RDA
void RDA_ISR(void)
#elif defined (_COMPILER_MCHIP_XC16)
void __attribute__((__interrupt__(_ISR_SPECIAL_SAVE), __auto_psv__)) _U1RXInterrupt(void)
#elif defined (_COMPILER_MCHIP_XC8)
void vU1RXInterruptHandler(void)
#else
#error Problem with defines
#endif
{
...
}
generates the warning
warning: (107) illegal # directive "INT_RDA"
There are hundreds of these warnings generated, making it hard to see legitimate warnings and/or errors.
Does anyone have suggestions on how to make XC8 shut up about things it's not even supposed to be parsing? I cannot find a flag to turn off this warning.
I use macros with xc8, but use #if
not just #ifdef as it seems to sometimes think undefined 'C'
macros are simply 0. Also I never give a compiler option the value 0.
Bit scary, but I tend to do stuff like:
//#define COMP_OPT 1
//#define COMP_OPT 2
#define COMP_OPT 3
then in the code
#if ( COMP_OPT == 0 )
#error COMP_OPT NOT DEFINED
#endif
#if ( COMP_OPT == 2 )
{
// code for compile option 2
// blah blah
}
#endif
That way I don't unintentionally produce code compiled for the wrong option (or none)

Gfortran pre-processor directives for Different Operating systems

Could you tell me please how can I do the following:
#if __unix__
#define path_sep='/'
#elif __windows__
#define path_sep='\'
#else
#error "path_sep not defined."
#endif
using gfortran compiler.
This can be done in combination with conditional compilation and using the "D" option on the command line. Here is some example code:
program test_Dopt
character (len=1) :: pathsep
pathsep = "?"
#ifdef WOS
pathsep = "\"
#endif
#ifdef UOS
pathsep = "/"
#endif
write (*, '( "pathsep is >", A1, "<")' ) pathsep
end program test_Dopt
Name the program with filetype F90 to cause gfortran to run the preprocessor or use -cpp on the compile line. Then pass options to the prepreprocessor by including them after D on the compile line, e.g., gfortran -DWOS. (This is more general then gfortran -- most Fortran compilers will process C-style pre-processor directives.) Then you can identify the OS outside of Fortran and pass the information to the Fortran program.
You can compile your code via using the filetype F90 or -cpp.

Resources