I am trying to use Doxygen to document some C++ code that uses Microsoft's Source-Code Annotation Language (SAL). However, Doxygen does not parse certain annotation macros, like _Success_, correctly. In the case of the example function annotation, _Success_, Doxygen misinterprets this macro as the function header/prototype.
Take the following example that contains the function annotation marker:
/**
* #file
* Example with function annotation.
*/
#include <windows.h>
#include <sal.h>
/**
* #brief This is a function.
* #param i a random variable
* #return TRUE on every call.
*/
_Success_(return) // The SAL function annotation.
BOOL function(_In_ int i) {
return TRUE;
}
With the example above, Doxygen will interpret _Success_() as the function header/prototype and thereby, creates documentation that is absolutely wrong. Here is what the HTML Doxygen output appears like with and without the function annotation:
With the function annotation, Doxygen also says I have documented a parameter variable i that is not part of the list of arguments:
C:/.../Source.cpp:9: warning: argument 'i' of command #param is not found in the argument list of Success(return)
Am I missing a configuration setting in the main Doxygen configuration file?
Or is SAL and Doxygen simply just incompatible?
Ah ha! After some further research, I found a question on Stack Overflow that asked this same question, except it wasn't tagged correctly and did not explicitly say s/he was using "Microsoft's SAL." This is why it took me awhile to find it. (I have updated the corresponding question to correct these missteps.)
The question's answer references the Doxygen manual section entitled: Preprocessing.
A typically example where some help from the preprocessor is needed is when dealing with the language extension from Microsoft: __declspec. The same goes for GNU's __attribute__ extension. [...] When nothing is done, doxygen will be confused and see __declspec as some sort of function. [...]
Therefore, as pertaining to my example above, the settings that need to be configured in the Doxygen configuration file are as follows:
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = _Success_(x)= \
_In_=
Basically, this set of configurations means that the macros defined in the PREDEFINED section will be fully expanded and evaluated "before the preprocessor [has] started." But, these macros will expand to nothing as we provide "nothing" for the definition side of the equation (i.e. format: name=definition). Therefore, they are essentially ignored/removed while Doxygen builds the documentation documents.
Unfortunately, this does mean that one will need to continue to expand this PREDEFINED list to encapsulate, at least, all the SAL macros used in the source code. A better solution would to encapsulate all the SAL macros in this list, but future proofing is impossible as one will always be late at appending any new macros that are added later on. But, at least, there is a solution!
Related
I am trying to understand a typedef but I am stuck with this Code:
typedef _Return_type_success_(return == DUPL_RETURN_SUCCESS) enum
{
DUPL_RETURN_SUCCESS = 0,
DUPL_RETURN_ERROR_EXPECTED = 1,
DUPL_RETURN_ERROR_UNEXPECTED = 2
}DUPL_RETURN;
My question is:
1) What is the Return argument doing in parameter of a function
2) we usually define typedef like this
typedef int foo;
I am unable to understand this above format.
I am a noobee to serious c++ programming, Thankyou for your time.
EDIT: I am trying to build this streaming app, so I need to retrieve frames as fast as possible, I came across a few articles that recommended DXGI way which is a fast solution. I am trying to understand how to use the windows desktop Duplication API. I found this code on official msdn website : here
_Return_type_success_ it is not part of the official c++ standard, but part of the Microsoft source code annotation language (which is proprietary addition to the c++ syntax):
Using SAL Annotations to Reduce C/C++ Code Defects
SAL is the Microsoft source code annotation language. By using source code annotations, you can make the intent behind your code explicit. These annotations also enable automated static analysis tools to analyze your code more accurately, with significantly fewer false positives and false negatives.
And _Return_type_success_ itself is described in Success/Failure Annotations
_Return_type_success_(expr): May be applied to a typedef. Indicates that all functions that return that type and do not explicitly have _Success_ are annotated as if they had _Success_(expr). _Return_type_success_ cannot be used on a function or a function pointer typedef.
_Return_type_success_ is most certainly just a macro defined as #define _Return_type_success_(arg) so that it is completely removed while compiling. This is at least the case for the sal.h (no_sal2.h ) header used in some azure code.
I have a templated class SafeInt<T> (By Microsoft).
This class in theory can be used in place of a POD integer type and can detect any integer overflows during arithmetic operations.
For this class I wrote some custom templatized overloaded arithmetic operator (+, -, *, /) functions whose both arguments are objects of SafeInt<T>.
I typedef'd all my integer types to SafeInt class type.
I want to search my codebase for instances of the said binary operators where both operands are of type SafeInt.
Some of the ways I could think of
String search using regex and weed through the code to detect operator usage instances where both operands are SafeInt objects.
Write a clang tool and process the AST to do this searching (I am yet to learn how to write such a tool.)
Somehow add a counter to count the number of times the custom overloaded operator is instantiated. I spent a lot of time trying this but doesn't seem to work.
Can anyone suggest a better way?
Please let me know if I need to clarify anything.
Thanks.
Short answer
You can do this using the clang-query command:
$ clang-query \
-c='m cxxOperatorCallExpr(callee(functionDecl(hasName("operator+"))), hasArgument(0, expr(hasType(cxxRecordDecl(hasName("SafeInt"))))), hasArgument(1, expr(hasType(cxxRecordDecl(hasName("SafeInt"))))))' \
use-si.cc --
Match #1:
/home/scott/wrk/learn/clang/clang-query1/use-si.cc:10:3: note: "root" binds here
x + y; // reported
^~~~~
1 match.
What is clang-query?
clang-query is a utility intended to facilitate writing clang-tidy checks. In particular it understands the language of AST Matchers and can be used to interactively explore what is matched by a given match expression. However, as shown here, it can also be used non-interactively to look for arbitrary AST tree patterns.
The blog post Exploring Clang Tooling Part 2: Examining the Clang AST with clang-query by Stephen Kelly provides a nice introduction to using clang-query.
The clang-query program is included in the pre-built LLVM binaries, or it can be built from source as described in the AST Matchers Tutorial.
How does the above command work?
The -c argument provides a command to run non-interactively. With whitespace added, the command is:
m // Match (and report) every
cxxOperatorCallExpr( // operator function call
callee(functionDecl( // where the callee
hasName("operator+"))), // is "operator+", and
hasArgument(0, // where the first argument
expr(hasType(cxxRecordDecl( // is a class type
hasName("SafeInt"))))), // called "SafeInt",
hasArgument(1, // and the second argument
expr(hasType(cxxRecordDecl( // is also a class type
hasName("SafeInt")))))) // called "SafeInt".
The command line ends with use-si.cc --, meaning to analyze use-si.cc and there are no extra compiler flags needed by clang to interpret it.
The clang-query command line has the same basic structure as that of clang-tidy, including the ability to pass -p compile_commands.json to scan many files at once, possibly with different compiler options per file.
Example input
For completeness, the input I used to test my matcher is use-si.cc:
// use-si.cc
#include "SafeInt.hpp" // SafeInt
void f1()
{
SafeInt<int> x(2);
SafeInt<int> y(3);
x + y; // reported
x + 2; // not reported
2 + x; // not reported
}
where SafeInt.hpp comes from https://github.com/dcleblanc/SafeInt , the repo named on the Microsoft SafeInt page.
To do this right, you clearly have to be able to identify individual uses of the operator which overload to a specific operator definition. Fundamentally, you need what the front end of a C++ compiler does: parsing and name resolution (including the overloads).
Obviously GCC and Clang have this basic capability. But you want to track/display all uses of the specific operator. You can probably bend Clang (or GCC, harder) to give you this information on a file-by-file basis.
Our DMS Software Reengineering Toolkit with its C++ Front End can be used for this, too.
DMS provides the generic parsing and symbol table support machinery; the C++ front end specializes DMS to handle C++ with full, accurate name resolution including overloads, for both GCC5 and MSVS2015. Its symbol table actually collects, for each declaration in a scope, the point of the declaration, and the list of uses of that declaration in terms of accurate source positions. The symbol scopes include an entry for each (overloaded) operator valid in the scope. You could just
go to the desired symbol table entry and enumerate/count the list of references to get a raw count. There are standard APIs for this available via DMS.
The same kind of symbol scope/definition/uses information is used by our Java Source Browser to build an HTML-based JavaDoc-like display with full HTML linkages between symbol declarations and uses. So for any symbol declaration, you can easily see the uses.
The C++ front end has a similar HTMLizer that operates on C++ source code. It isn't as mature/pretty, but it is robust. It presently doesn't show all the uses of a declared symbol, but that would be a pretty straightforward change to make to it. (I don't have a publicly visible instance of it. Contact me through my bio and I can send you a sample).
I am working on a proprietary tool which uses a C++-like language to define various methods. The tool provides its own compiler to compile these methods into a .so file. It does not follow the "declaration-definition" syntax of C++, but is otherwise quite similar. An example code looks like the following:
method _foo::bar(var message) {
// do something with 'message' here
}
I tried documenting this method using doxygen as follows:
/**
* #brief this method does something with #a message.
*/
method _foo::bar(var message) {
// do something with 'message' here
}
but this gave me a warning:
warning: documented function `method _foo::bar' was not declared or defined.
I tried with adding #fn method _foo::bar(), #fn _foo::bar, and #fn bar to the comment block (one by one), but neither of them resulted in the #brief message being added to the document.
I have searched here on Stack Overflow, and this post Doxygen comments with undeclared functions in C++ headers is the closest to my question, but it doesn't quite address my problem.
Is there any way to configure doxygen to generate documentation for a function regardless of the fact that it is undeclared?
I'm reading through and trying to understand some verilog, and sprinkled through is the compiler directive:
// synopsys template
But I do not know what this is or what it does. My Google Fu in researching variations of 'verilog templates' has lead to more example verilog code than answers.
I did find this synopsis user guide: http://acms.ucsd.edu/info/documents/dc/syn3.pdf, which on p282 provides some information, the directive seems to affect this variable:
hdlin_auto_save_templates
Controls whether HDL designs containing parameters are read in as templates.
...
It goes on to imply this directive affects "elaboration" (perhaps delaying it? to what end?), which my current understanding is loosely analogous to the code emission step of traditional compilation, when the verilog is converted to an "actual" hardware representation?
I would appreciate an explanation of what templates are / do in Verilog and perhaps a correction on my understanding of 'elaboration' in this context - Thanks!
It goes on to imply this directive affects "elaboration" (perhaps delaying it? to what
end?), which my current understanding is loosely analogous to the code
emission step of traditional compilation, when the verilog is
converted to an "actual" hardware representation?
Not really. Elaboration is part of the language specification and is a required step to process a design. Processing Verilog usually requires two distinct steps which the specification describes as parsing and elaboration. SystemVerilog more precisely defines these and calls them compilation and elaboration.
1364-2005:
Elaboration is the process that occurs between parsing and simulation.
It binds modules to module instances, builds the model hierarchy,
computes parameter values, resolves hierarchical names, establishes
net connectivit, and prepares all of this for simulation. With the
addition of generate constructs, the order in which these tasks occur
becomes significant.
Verilog contains some constructs that makes it impossible to completely build a module then 'link' it to a larger design later. Consider the following code:
module mod1 #(parameter WIDTH = 0) (output [WIDTH:0] port1);
generate
if(WIDTH > 3)
assign port1 = {WIDTH{1'b1}};
else
assign port1 = {WIDTH{1'b0}};
endgenerate
endmodule
When the above module is read, the parser has no idea what WIDTH will be because the value given can be overridden in the instantiation. This prevents it from resolving the code inside the generate block until the entire Verilog source text is read. It gets more complicated with defparams, forward declarations of functions and hierarchical references.
The command // synopsys template and the term 'templates' are not part of verilog. Given toolic's answer and the doc you linked, it appears to tell the tool that any module read after the command will need a parameter definition so it should not be elaborated when read. For instance a netlist will not have any parameter overrides in the instantiations so if you want to place an RTL instance in a netlist, you would need to tell the synthesis tool directly what the parameters should be.
The // synopsys template comment is used by the Synopsys Design Compiler tool when synthesizing Verilog RTL code into a gate netlist. The pragma only affects Verilog code which contains parameters. It is especially useful when synthesizing several instances of the same Verilog module, each having a different passed parameter value.
For example, if you have a FIFO that uses a parameter to specify its word depth:
parameter DEPTH = 4;
you can synthesize two FIFOs, overriding the default depth, if desired.
Using the template pragma also allows control over the synthesized instance names, using other Design Compiler script variables.
The template pragma only has meaning to the synthesis tool; it does not affect simulation.
Whilst refactoring some old code I realised that a particular header file was full of function declarations for functions long since removed from the .cpp file. Does anyone know of a tool that could find (and strip) these automatically?
You could if possible make a test.cpp file to call them all, the linker will flag the ones that have no code as unresolved, this way your test code only need compile and not worry about actually running.
PC-lint can be tunned for dedicated purpose:
I tested the following code against for your question:
void foo(int );
int main()
{
return 0;
}
lint.bat test_unused.cpp
and got the following result:
============================================================
--- Module: test_unused.cpp (C++)
--- Wrap-up for Module: test_unused.cpp
Info 752: local declarator 'foo(int)' (line 2, file test_unused.cpp) not referenced
test_unused.cpp(2) : Info 830: Location cited in prior message
============================================================
So you can pass the warning number 752 for your puropse:
lint.bat -"e*" +e752 test_unused.cpp
-e"*" will remove all the warnings and +e752 will turn on this specific one
If you index to code with Doxygen you can see from where is each function referenced. However, you would have to browse through each class (1 HTML page per class) and scan for those that don't have anything pointing to them.
Alternatively, you could use ctags to generate list of all functions in the code, and then use objdump or some similar tool to get list of all function in .o files - and then compare those lists. However, this can be problematic due to name mangling.
I don't think there is such thing because some functions not having a body in the actual source tree might be defined in some external library. This can only be done by creating a script which makes a list of declared functions in a header and verifies if they are sometimes called.
I have a C++ ftplugin for vim that is able is check and report unmatched functions -- vimmers, the ftplugin suite is not yet straightforward to install. The ftplugin is based on ctags results (hence its heuristic could be easily adapted to other environments), sometimes there are false positives in the case of inline functions.
HTH,
In addition Doxygen (#Milan Babuskov), you can see if there are warnings for this in your compiler. E.g. gcc has -Wunused-function for static functions; -fdump-ipa-cgraph.
I've heard good things about PC-Lint, but I imagine it's probably overkill for your needs.