In my project there's a file enclosed in an ifdef preprocessor directive
#ifdef SOME_SYMBOL
... entire file ...
#endif
SOME_SYMBOL is defined by another file that's compiled before this one, and the code works as expected, but the static analyzer isn't aware of this symbol and so it treats SOME_SYMBOL is undefined. The entire file has no syntax highlighting and some of the analysis is just skipped (e.g. syntax error highlighting).
Is there a way to tell the analyzer to treat this symbol as defined without defining it in CMakeLists.txt?
I don't have the option of defining SOME_SYMBOL in CMakeLists.txt since the project depends on it being undefined in some compilation paths (changing this would be near impossible).
Update:
Seems like this is currently an open issue with JetBrains. See Issue CPP-2286
Clion now has a macro which you can use to detect the IDE:
https://youtrack.jetbrains.com/issue/CPP-1296#comment=27-1846360
#ifdef __JETBRAINS_IDE__
// Stuff that only clion will see goes here
#endif
This allows you to put in defines to make clion render your code properly in cases where it can't be clever enough to figure it out.
The __JETBRAINS_IDE__ macro's value is a version string for the IDE. Specific versions of the macro exist for different Jetbrains IDEs: __CLION_IDE__, __STUDIO_IDE__ (for Android Studio), and __APPCODE_IDE__ (for AppCode).
Yay!
To get syntax highlighting:
Go to Settings ⇒ Editor ⇒ Colors&Fonts ⇒ C/C++ and remove all ticks for 'Conditionally non-compiled code'. This way all code will show up with the usual highlighting.
The task has no solution for common case.
But! You can find the target and related resolve context, where SOME_SYMBOL is defined.
...in the status bar you can find the Resolve Context chooser for switching between the Debug, Release, RelWithDebInfo and MinSizeRel contexts to resolve your code in the IDE with the desired definitions.
Related
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.
I spoted a bug in my own code because of copy/paste. The same value name is shadowned by the copy/pasted in the same scope.
let func() =
let a = 1
let a = something_else
....
In C# I wont pass compile. is there a way to disable shadowing? at least within the same level of scope?
Thanks
You can't disable shadowing in F# -- it's an important language feature.
However, you can instruct the compiler to issue a warning or error which will help you catch cases of accidental shadowing.
In the project properties, add --warnon:1182 to the "Other flags" textbox (on the Build tab, under the platform target dropdown). This triggers a compiler warning when you accidentally shadow a variable and cause it not to be used anywhere. If you'd rather these cases cause compilation to fail, you can also add 1182 to the "Specific warnings" textbox under the "Treat warnings as errors" section of the Build tab.
Finally -- do install the Visual F# Power Tools extension. It provides additional syntax highlighting functionality and will indicate unused variables so they're easy to spot in your code.
I was trying to:
#define CommonAppData {commonappdata}
but it yields:
Compiler Error
[ISPP] Expression expected but opening brace ("{") found.
How to achieve this with Inno Setup PreProcessor?
{commonappdata} cannot be expanded at compile time, i.e. when the pre-processor runs because it is only known at runtime: It identifies the common application data directory on the machine where the compiled installer is run.
Maybe if you could clarify how you intend to use that define we might be able to help. If for example what you're really interested in is not the common app data directory on the target machine but the one on the developer machine, then you can probably use this:
#define CommonAppData GetEnv("COMMONAPPDATA")
If however you intend to use that define for populating Inno properties that are themselves capable of expanding the constant at runtime then you should use this:
#define CommonAppData "{commonappdata}"
Hope this helps.
#define is a inno setup pre-processor directive, in a pre-compile phase. It works much like a C pre-processor.
By defining a pre-processor variable, we force the compiler to see a script after the ispp defines are resolved:
Inno Setup Preprocessor (ISPP) is an add-on for Jordan Russell's Inno Setup compiler. More technically speaking, it is an additional layer between GUI (your Inno Setup script) and the compiler, which before passing the text intercepts and modifies it in a way it is told by using special directives in the script text.
That said, I can't find a source in documentation nor have time to digg into the source code, but I'm pretty sure inno setup variables are not available during this pre-compile time.
If you just want the defined variable to contain the string {commonappdata}, use it directly in your source... if you want the defined variable to have the run-time value of commonappdata, it doesn't seem possible to me, because that value is determined at runtime as its current value depends on the target machine (windows version, language, etc.).
If you think it twice, it doesn't make sense to try to use that value at pre-compile or compile time... this is just the whole fact that brings inno setup constants like {commonappdata}, {destdir} and the like to existence... that you can express in a standard way at compile time a unknown but meaningful value, which will be known and evaluated at runtime.
You'll probably need to escape the brace. Something like:
#define CommonAppData {{commonappdata}
Sometimes I get annoying pattern matching and indent warnings when compiling F#. Is there a way to disable warnings? I'm pretty OCD over warnings.
In case you forget, you can type
let rec x = lazy(x.Value)
and get the warning
This and other recursive references to
the object(s) being defined will be
checked for initialization-soundness
at runtime through the use of a
delayed reference. This is because you
are defining one or more recursive
objects, rather than recursive
functions. This warning may be
suppressed by using '#nowarn "40"' or
'--nowarn:40'.
which shows that you can use either the compiler flag --nowarn on the command-line, or use the hash-directive #nowarn in your code. The warning number for each warning will be part of the build output (the Visual Studio error list does not display the numbers, so if in VS, build and then inspect the build output). Also, if inside VS, you can go to the project properties page, "Build" tab, and use the "warning level" selector and "suppress warnings" field (a semicolon-delimited list of numbers) to control which warnings are diplayed via the VS UI.
(BTW, I believe #nowarn only turns off the warning in the current file, whereas --nowarn turns it off for the entire project being compiled.)
See: Compiler Options (F#)
--nowarn:<int-list>:
Disable specific warnings listed by
number. Separate each warning number
by a comma. You can discover the
warning number for any warning from
the compilation output.
This compiler option is equivalent to
the C# compiler option of the same
name. For more information, see
/nowarn (C# Compiler Options).
This isn't really clearly documented, but a shallow search reveals that RIM's RAPC compiler does support preprocessor statements (with some project file modification).
We've been using the simple #ifdef, #else, and #endif directives for quite some time now, as supporting platforms 4.1 through 4.7 with one code base is nearly impossible without them, but I began wondering recently if there are other supported directives which aren't quite as well documented; something akin to C's #elif for example, or even rudimentary equivalency directives?
Here's a complete listing of commands for the RAPC preprocessor. The preprocessor's not very robust, but that's on purpose.
//#preprocess - Used to specify that the file should be preprocessed. It must be the first line of the file.
//#implicit tag - This needs to be on the second line of the file. If tag is part of the command line, then the whole file should be compiled. If not, then it should be excluded.
Then there's the //#ifdef tag ... #else ... #endif and the //#ifndef tag ... #else ... #endif directives that you mentioned.
Also note, there is no nesting of preprocessed blocks and no macros.
RIM Help Center Doc:
http://docs.blackberry.com/en/developers/deliverables/21065/Specifying_preprocessor_directives_657636_11.jsp