How to debug/log preprocessor macros in Xcode (iOS)? - ios

The question is stated in title, the main purpose is to be able to efficiently debug some runtime-version-specific or scheme-specific code.
So for example, is it possible to log the value of DEBUG in xcode's console?
EDIT:
I should rephrase the question, I understand we can use NSLog("DEBUG = %d", DEBUG); to log a macro's value (thx #rmaddy), the question should be:
Is there better way? eg. not needing to add a command and recompile just to get the value of a single macro

The question seems a little confusing because of the mention of "runtime-version-specific". Preprocessor macros are compile-time settings rather than runtime settings.
If all you need is to find the iOS predefined macros for Xcode 6, type this into the terminal:
llvm-gcc -arch armv7 -dM -E – < /dev/null | sort
(Yes, there is a single dash by itself.)
Change the -arch option to “armv6″ or “armv7″ or “armv7s” as needed.
This can probably be extended to preprocess your project's code and show all the preprocessor macros. But that will be a compile-time operation rather than run-time.
To print the values of your custom macros at runtime would require specifically writing at least some code for each macro. Macros are tricky things. They may be #defined to one value or another or not #defined at all. They might also be #defined as numbers, or #defined as text, or object literals such as NSString, NSDictionary or NSNumber or any kind of object pointer.
The C standard "stringification operator" ('#') may be of interest if you really need to print things out at run-time.

Related

Clang libtooling: how to print compiler macro definitions

I have a LibTooling based utility and I would like to output a list of macro definitions for debug purposes. One can print compiler macro definitions with clang/gcc -dM -E -, but it does not seem to work if I pass -dM -E or -dD to ClangTool. Is it possible to do so with LibTooling API or CLI options in any way? It does not matter if it will include macros defined in a parsed source code or not.
I've looked at other similar questions, and as far as I can tell they all are about macros expanded in a parsed source code. That's not exactly what I need.
The answer is blindingly obvious—in retrospect. clang::Preprocessor::getPredefines() returns just that—a list of compiler predefines. The preprocessor object can be obtained e.g. from clang::CompilerInstance, as an argument in clang::DiagnosticConsumer::BeginSourceFile(), etc.
Just for the sake of completeness, this functionality is not available via libclang API, but I could do that using the fact that all predefines are present in the beginning of a translation unit. So after parsing I just listed all top-level cursors of CursorKind.MACRO_DEFINITION that are not in any real location (location.file is None using python bindings notation)

Prevent ArmClang to add calls to Standard C library

I am evaluating Keil Microvision IDE on STM32H753.
I am doing compiler comparison between ARMCC5 and AC6 in the different optimisation levels. AC6 is based on Clang.
My code is not using memcpy and I have unchecked "Use MicroLIB" in the project settings , However a basic byte per byte copy loop in my code is replaced by a memcpy with AC6 (only in "high" optimisation levels). It doesn't happen with ARMCC5.
I tried using compilation options to avoid that, as described here: -ffreestanding and -disable-simplify-libcalls, at both compiler and linker levels but it didn't change (for the second option, I get an error message saying that the option is not supported).
In the ARMCLANG reference guide i've found the options -nostdlib -nostdlibinc that prevent (??) the compiler to use any function of a standard lib.
However I still need the math.h function.
Do you know how to prevent clang to use functions from the Standard C Lib that are not explicitely called in the code ?
EDIT: here is a quick and dirty reproduceable example:
https://godbolt.org/z/AX8_WV
Please do not discuss the quality of this example, I know it is dumb !!, I know about memset, etc... It is just to understand the issue
gcc know a lot about the memcpy, memset and similar functions and even they are called "the builtin functions". If you do not want those functions to be used by default just use the command line option -fno-builtin
https://godbolt.org/z/a42m4j

Add #include's to the headers of a program using llvm clang

I need to add headers to an already existing program by transforming it with LLVM and Clang.
I have used clang's rewriter to accomplish a similar thing in the changing function names and arguments, etc.
But the header files aren't present in clang's AST. I already know we need to use PPCallbacks (https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html) but I am in dire need of some examples on how to make it work with the rewriter if at all possible.
Alternatively, adding a #include statement just before the first
using namespace <namespace>;
Also works. I would like to know an example of this as well.
Any help would be appreciated.
There is a bit of confusion in your question. You need to understand in details how the preprocessor works. Be aware that most of C++ compilation happens after the preprocessing phase (so most C++ static analyzers work after that phase).
In other words, the C++ specification (and also the C specification) defines first what is preprocessing, and then what is the syntax and the semantics of the preprocessed form.
In other words, when compiling foo.cc your compiler see the preprocessed form foo.ii that you could obtain with clang++ -C -E foo.cc > foo.ii
In the 1980s the preprocessor /lib/cpp was a separate program forked by the compiler (and some temporary foo.ii was sitting on the disk and removed at end of compilation). Today, it is -for performance reasons- some initial processing done inside the compiler. But you could reason as if it was still separate.
Either you want to alter the Clang compiler, and it deals (like every other C++ compiler or C++ static analyzer) mostly with the preprocessed form. Then you don't want to add new #include-s, but you want to alter the flow of AST given to the compiler (after preprocessing), and that is a different question: you then want to add some AST between existing AST elements (independently of any preprocessor directives).
Or you want to automatically change the C++ source code. The hard part is determining what you want to change and at what place. I suppose that you have used complex stuff to determine that a #include <vector> has to be inserted after line 34 of file foo.cc. Once you've got that information (and getting it is the hard thing), doing the insertion is pretty trivial. For example, you could read every C++ source line, and insert your line when you have read enough lines.

Does the preprocessor pass environment variables?

Does the preprocessor have a mechanism to access environment variables directly as defines, without the need to define them on the command line?
For instance,
SOME_VAR=foo gcc code.c
and
#if ENV_SOME_VAR == "foo"
#define SOME_VAR_IS_FOO
#endif
No, the standard C preprocessor has no such mechanism, and I'm not aware of any compiler extensions that provide such a feature either.
However, you can do this using a build system, such as Cmake or GNU Autoconf, the latter being a part of the GNU Autotools build system. A simple shell script would do this as well, though all of these options mean you'd need to test the environment variable to determine whether to define ENV_SOME_VAR, in which case, you might just define it using something like the following:
-DENV_SOME_VAR="${SOME_VAR:-unfoo}"
That would define ENV_SOME_VAR in your C file as the value of $SOME_VAR if it's set or to the string "unfoo" if $SOME_VAR is empty (null) or unset.

Is is possible to disable this warning in clang? warning: #pragma once in main file

warning: #pragma once in main file
We're running our headers through clang to get a partial AST.
Is it possible to disable that warning?
Use the -Wno-pragma-once-outside-header command line argument. Consult the Clang documentation here.
I had this thing when I accidentally included a header file in compile sources (this header has #pragma once line). To fix this remove header from compile sources (and probably you need to replace it with .cpp file)
There's no -W option for "#pragma once in main file", so you can't turn it off via the usual means. (However, the Clang developers are very aware that warnings without -W options suck, and there's a general rule that new warnings always get -W options. Cleaning up the old code, unfortunately, is left as an exercise for frustrated users.)
If you don't mind shell hackery, you could always do something like this:
# This gives the warning...
clang -c myheader.h
# ...This doesn't.
echo '#include "myheader.h"' | clang -c -x c++-header -o myheader.h.gch -
The trailing -, as usual, means "read from stdin". The -x c++ tells Clang what language you're using (since it can't tell from the file extension when there is no file), and changing c++ to c++-header means that we want to produce a .gch file instead of an .o file.
The two .gch files thus produced are NOT bit-for-bit identical. I don't know enough about gch files to tell you what might be observably different about their behavior. However, since all you care about is Clang's AST, I bet you'll be fine with it. :)
Use the -w (lowercase w not uppercase W) option while compiling the source to suppress such warnings.
There are no option to control it, so just ban this warning in your code.

Resources