diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2012-09-10 20:32:42 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2012-09-10 20:32:42 +0000 |
commit | e4330a302ac20b41b9800267ebd4b5b01f8553f8 (patch) | |
tree | 2a0fe1a83b27fd60a74bbdf5ea4026c0fd1b380e /include/clang/AST/CommentCommandTraits.h | |
parent | db133151fc405573634877f13da7bcc2e9f2a1cd (diff) |
Comment AST: TableGen'ize all command lists in CommentCommandTraits.cpp.
Now we have a list of all commands. This is a good thing in itself, but it
also enables us to easily implement typo correction for command names.
With this change we have objects that contain information about each command,
so it makes sense to resolve command name just once during lexing (currently we
store command names as strings and do a linear search every time some property
value is needed). Thus comment token and AST nodes were changed to contain a
command ID -- index into a tables of builtin and registered commands. Unknown
commands are registered during parsing and thus are also uniformly assigned an
ID. Using an ID instead of a StringRef is also a nice memory optimization
since ID is a small integer that fits into a common bitfield in Comment class.
This change implies that to get any information about a command (even a command
name) we need a CommandTraits object to resolve the command ID to CommandInfo*.
Currently a fresh temporary CommandTraits object is created whenever it is
needed since it does not have any state. But with this change it has state --
new commands can be registered, so a CommandTraits object was added to
ASTContext.
Also, in libclang CXComment has to be expanded to include a CXTranslationUnit
so that all functions working on comment AST nodes can get a CommandTraits
object. This breaks binary compatibility of CXComment APIs.
Now clang_FullComment_getAsXML(CXTranslationUnit TU, CXComment CXC) doesn't
need TU parameter anymore, so it was removed. This is a source-incompatible
change for this C API.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163540 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/CommentCommandTraits.h')
-rw-r--r-- | include/clang/AST/CommentCommandTraits.h | 179 |
1 files changed, 84 insertions, 95 deletions
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index 5f0269a465..07d9a489e3 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -19,136 +19,125 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { namespace comments { -/// This class provides informaiton about commands that can be used -/// in comments. -class CommandTraits { -public: - CommandTraits() { } +/// \brief Information about a single command. +/// +/// When reordering, adding or removing members please update the corresponding +/// TableGen backend. +struct CommandInfo { + unsigned getID() const { + return ID; + } + + const char *Name; + + /// Name of the command that ends the verbatim block. + const char *EndCommandName; + + unsigned ID : 8; + + /// Number of word-like arguments for a given block command, except for + /// \\param and \\tparam commands -- these have special argument parsers. + unsigned NumArgs : 4; + + /// True if this command is a inline command (of any kind). + unsigned IsInlineCommand : 1; + + /// True if this command is a block command (of any kind). + unsigned IsBlockCommand : 1; + + /// True if this command is introducing a brief documentation + /// paragraph (\\brief or an alias). + unsigned IsBriefCommand : 1; + + /// True if this command is \\returns or an alias. + unsigned IsReturnsCommand : 1; + + /// True if this command is introducing documentation for a function + /// parameter (\\param or an alias). + unsigned IsParamCommand : 1; - /// \brief Check if a given command is a verbatim-like block command. + /// True if this command is introducing documentation for + /// a template parameter (\\tparam or an alias). + unsigned IsTParamCommand : 1; + + /// \brief True if this command is a verbatim-like block command. /// /// A verbatim-like block command eats every character (except line starting /// decorations) until matching end command is seen or comment end is hit. - /// - /// \param StartName name of the command that starts the verbatim block. - /// \param [out] EndName name of the command that ends the verbatim block. - /// - /// \returns true if a given command is a verbatim block command. - bool isVerbatimBlockCommand(StringRef StartName, StringRef &EndName) const; + unsigned IsVerbatimBlockCommand : 1; - /// \brief Register a new verbatim block command. - void addVerbatimBlockCommand(StringRef StartName, StringRef EndName); + /// \brief True if this command is an end command for a verbatim-like block. + unsigned IsVerbatimBlockEndCommand : 1; - /// \brief Check if a given command is a verbatim line command. + /// \brief True if this command is a verbatim line command. /// /// A verbatim-like line command eats everything until a newline is seen or /// comment end is hit. - bool isVerbatimLineCommand(StringRef Name) const; + unsigned IsVerbatimLineCommand : 1; - /// \brief Check if a given command is a command that contains a declaration - /// for the entity being documented. + /// \brief True if this command contains a declaration for the entity being + /// documented. /// /// For example: /// \code /// \fn void f(int a); /// \endcode - bool isDeclarationCommand(StringRef Name) const; + unsigned IsDeclarationCommand : 1; - /// \brief Register a new verbatim line command. - void addVerbatimLineCommand(StringRef Name); + /// \brief True if this command is unknown. This \c CommandInfo object was + /// created during parsing. + unsigned IsUnknownCommand : 1; +}; - /// \brief Check if a given command is a block command (of any kind). - bool isBlockCommand(StringRef Name) const; +/// This class provides information about commands that can be used +/// in comments. +class CommandTraits { +public: + CommandTraits(llvm::BumpPtrAllocator &Allocator); - /// \brief Check if a given command is introducing documentation for - /// a function parameter (\\param or an alias). - bool isParamCommand(StringRef Name) const; + /// \returns a CommandInfo object for a given command name or + /// NULL if no CommandInfo object exists for this command. + const CommandInfo *getCommandInfoOrNULL(StringRef Name) const; - /// \brief Check if a given command is introducing documentation for - /// a template parameter (\\tparam or an alias). - bool isTParamCommand(StringRef Name) const; + const CommandInfo *getCommandInfo(StringRef Name) const { + if (const CommandInfo *Info = getCommandInfoOrNULL(Name)) + return Info; + llvm_unreachable("the command should be known"); + } - /// \brief Check if a given command is introducing a brief documentation - /// paragraph (\\brief or an alias). - bool isBriefCommand(StringRef Name) const; + const CommandInfo *getCommandInfo(unsigned CommandID) const; - /// \brief Check if a given command is \\brief or an alias. - bool isReturnsCommand(StringRef Name) const; + const CommandInfo *registerUnknownCommand(StringRef CommandName); - /// \returns the number of word-like arguments for a given block command, - /// except for \\param and \\tparam commands -- these have special argument - /// parsers. - unsigned getBlockCommandNumArgs(StringRef Name) const; + /// \returns a CommandInfo object for a given command name or + /// NULL if \c Name is not a builtin command. + static const CommandInfo *getBuiltinCommandInfo(StringRef Name); - /// \brief Check if a given command is a inline command (of any kind). - bool isInlineCommand(StringRef Name) const; + /// \returns a CommandInfo object for a given command ID or + /// NULL if \c CommandID is not a builtin command. + static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID); private: - struct VerbatimBlockCommand { - StringRef StartName; - StringRef EndName; - }; - - typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector; + CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION; + void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION; - /// Registered additional verbatim-like block commands. - VerbatimBlockCommandVector VerbatimBlockCommands; + const CommandInfo *getRegisteredCommandInfo(StringRef Name) const; + const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const; - struct VerbatimLineCommand { - StringRef Name; - }; + unsigned NextID; - typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector; + /// Allocator for CommandInfo objects. + llvm::BumpPtrAllocator &Allocator; - /// Registered verbatim-like line commands. - VerbatimLineCommandVector VerbatimLineCommands; + SmallVector<CommandInfo *, 4> RegisteredCommands; }; -inline bool CommandTraits::isBlockCommand(StringRef Name) const { - return isBriefCommand(Name) || isReturnsCommand(Name) || - isParamCommand(Name) || isTParamCommand(Name) || - llvm::StringSwitch<bool>(Name) - .Case("author", true) - .Case("authors", true) - .Case("pre", true) - .Case("post", true) - .Default(false); -} - -inline bool CommandTraits::isParamCommand(StringRef Name) const { - return Name == "param"; -} - -inline bool CommandTraits::isTParamCommand(StringRef Name) const { - return Name == "tparam" || // Doxygen - Name == "templatefield"; // HeaderDoc -} - -inline bool CommandTraits::isBriefCommand(StringRef Name) const { - return Name == "brief" || Name == "short"; -} - -inline bool CommandTraits::isReturnsCommand(StringRef Name) const { - return Name == "returns" || Name == "return" || Name == "result"; -} - -inline unsigned CommandTraits::getBlockCommandNumArgs(StringRef Name) const { - return 0; -} - -inline bool CommandTraits::isInlineCommand(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) - .Case("b", true) - .Cases("c", "p", true) - .Cases("a", "e", "em", true) - .Default(false); -} - } // end namespace comments } // end namespace clang |