[cfe-dev] Notes on Doxygen documentation style

Douglas Gregor dgregor at apple.com
Tue Jan 20 09:46:06 PST 2009


I'm a documentation nut, and there are some places in Clang's internal  
documentation that I think we can do even better. Here are some  
comments on the subject.

Coverage
========

Naturally, every data type and non-private function should be  
documented. Most important for clients of Clang are the AST nodes: we  
should strive to have good documentation for each Expr, Stmt, and Decl  
node, including code examples illustrating where these kinds of  
declarations will show up in the source code.

I don't have any concerns about this in particular: we have decent  
documentation coverage, and we'll keep improving it as we go.

Style
====

In my view, good documentation always includes a brief one-sentence  
description (so the reader can answer the question "does this look  
like what I want?") followed by an in-depth description of the  
routine's behavior and its parameters and (often) language-standard  
citations and examples. Our current style of documentation doesn't fit  
this quite so well; picking one example of many, Action::isTypeName is  
documented like this:

   /// isTypeName - Return non-null if the specified identifier is a  
type name
   /// in the current scope.
   /// An optional CXXScopeSpec can be passed to indicate the C++  
scope (class or
   /// namespace) that the identifier must be a member of.
   /// i.e. for "foo::bar", 'II' will be "bar" and 'SS' will be "foo::".
   virtual TypeTy *isTypeName(IdentifierInfo &II, Scope *S,
                              const CXXScopeSpec *SS = 0) = 0;

That says what we need, but it doesn't format well with Doxygen:

   http://clang.llvm.org/doxygen/classclang_1_1Sema.html#6dc9964792711aab89e41067aca3581c

Also, scroll down to isTypeName within Sema's documentation:

   http://clang.llvm.org/doxygen/classclang_1_1Sema.html

Then, scroll down a little further to "LookupName". This is how I,  
personally, would like to see documentation for a function. First of  
all, we've used Doxygen to give a one-sentence description of what  
LookupName does, and it shows up under the declaration of LookupName:  
that's great for finding what operation we need, quickly.

Clicking on LookupName, we get the lengthier description with an  
example, specific information about the parameters, language  
citations, etc. It takes some extra Doxygen markup to do this, but in  
my opinion it's absolutely worth it. Here's how LookupName is written:

/// @brief Perform unqualified name lookup starting from a given
/// scope.
///
/// Unqualified name lookup (C++ [basic.lookup.unqual], C99 6.2.1) is
/// used to find names within the current scope. For example, 'x' in
/// @code
/// int x;
/// int f() {
///   return x; // unqualified name look finds 'x' in the global scope
/// }
/// @endcode
///
/// Different lookup criteria can find different names. For example, a
/// particular scope can have both a struct and a function of the same
/// name, and each can be found by certain lookup criteria. For more
/// information about lookup criteria, see the documentation for the
/// class LookupCriteria.
///
/// @param S        The scope from which unqualified name lookup will
/// begin. If the lookup criteria permits, name lookup may also search
/// in the parent scopes.
///
/// @param Name     The name of the entity that we are searching for.
///
/// @param Criteria The criteria that this routine will use to
/// determine which names are visible and which names will be
/// found. Note that name lookup will find a name that is visible by
/// the given criteria, but the entity itself may not be semantically
/// correct or even the kind of entity expected based on the
/// lookup. For example, searching for a nested-name-specifier name
/// might result in an EnumDecl, which is visible but is not permitted
/// as a nested-name-specifier in C++03.
///
/// @returns The result of name lookup, which includes zero or more
/// declarations and possibly additional information used to diagnose
/// ambiguities.
Sema::LookupResult
Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria  
Criteria) {

The important bits are @brief (for the one-sentence description),  
@param (for parameter documentation) and @code/@endcode (for examples).

Grouping
=======

Sema::LookupName was also an experiment with grouping routines  
together. The Sema class is large, but we can give it structure using  
Doxygen's //@{ and //@} grouping constructs. If you look back at

	http://clang.llvm.org/doxygen/classclang_1_1Sema.html

and search for "Name lookup", you'll come across a grouping of the  
various name-lookup routines. I really like this style: it logically  
groups related pieces of the (large!) Sema class, and puts them all in  
context together. It also gives some guidance for someone who knows  
they need name lookup but doesn't necessarily know what kind.

Groups are easy to make. The heading of the group should use @name or  
\name, then provide documentation for the group as a whole:

   /// \name Name lookup
   ///
   /// These routines provide name lookup that is used during semantic
   /// analysis to resolve the various kinds of names (identifiers,
and so on

Then,

//@{

starts grouping all of the methods, classes, etc., that will be  
documented together. Terminate the group with

//@}

Not all of the groups will be obvious, but there are some sets of  
routines that really need it, such as C++ function overloading.

Architectural Descriptions
====================

We currently have a Clang "internals" manual, with documentation about  
various subsystems within Clang:

   http://clang.llvm.org/docs/InternalsManual.html

We could consider bringing this documentation in with the rest of the  
Doxygen documentation using, e.g., Doxygen's \page and \newpage  
markup. The benefit of bringing all of the internals documentation  
into Doxygen is that we can more easily cross-link between specific  
function/class documentation and the more general, architectural  
information.

   - Doug



More information about the cfe-dev mailing list