[cfe-commits] r163540 - in /cfe/trunk: include/clang-c/ include/clang/AST/ lib/AST/ test/Index/ tools/c-index-test/ tools/libclang/ unittests/AST/ utils/TableGen/

Dmitri Gribenko gribozavr at gmail.com
Mon Sep 10 13:32:43 PDT 2012


Author: gribozavr
Date: Mon Sep 10 15:32:42 2012
New Revision: 163540

URL: http://llvm.org/viewvc/llvm-project?rev=163540&view=rev
Log:
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.


Added:
    cfe/trunk/include/clang/AST/CommentCommands.td
    cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/CMakeLists.txt
    cfe/trunk/include/clang/AST/Comment.h
    cfe/trunk/include/clang/AST/CommentCommandTraits.h
    cfe/trunk/include/clang/AST/CommentLexer.h
    cfe/trunk/include/clang/AST/CommentSema.h
    cfe/trunk/include/clang/AST/Makefile
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/CMakeLists.txt
    cfe/trunk/lib/AST/Comment.cpp
    cfe/trunk/lib/AST/CommentBriefParser.cpp
    cfe/trunk/lib/AST/CommentCommandTraits.cpp
    cfe/trunk/lib/AST/CommentDumper.cpp
    cfe/trunk/lib/AST/CommentLexer.cpp
    cfe/trunk/lib/AST/CommentParser.cpp
    cfe/trunk/lib/AST/CommentSema.cpp
    cfe/trunk/lib/AST/RawCommentList.cpp
    cfe/trunk/test/Index/annotate-comments.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXComment.cpp
    cfe/trunk/tools/libclang/CXComment.h
    cfe/trunk/unittests/AST/CommentLexer.cpp
    cfe/trunk/unittests/AST/CommentParser.cpp
    cfe/trunk/utils/TableGen/CMakeLists.txt
    cfe/trunk/utils/TableGen/TableGen.cpp
    cfe/trunk/utils/TableGen/TableGenBackends.h

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Mon Sep 10 15:32:42 2012
@@ -2040,7 +2040,8 @@
  * \brief A comment AST node.
  */
 typedef struct {
-  const void *Data;
+  const void *ASTNode;
+  CXTranslationUnit TranslationUnit;
 } CXComment;
 
 /**
@@ -3692,14 +3693,11 @@
  * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
  * inside clang source tree.
  *
- * \param TU the translation unit \c Comment belongs to.
- *
  * \param Comment a \c CXComment_FullComment AST node.
  *
  * \returns string containing an XML document.
  */
-CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXTranslationUnit TU,
-                                                   CXComment Comment);
+CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
 
 /**
  * @}

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Sep 10 15:32:42 2012
@@ -29,6 +29,7 @@
 #include "clang/AST/Type.h"
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/RawCommentList.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -529,6 +530,14 @@
   /// Returns NULL if no comment is attached.
   comments::FullComment *getCommentForDecl(const Decl *D) const;
 
+private:
+  mutable comments::CommandTraits CommentCommandTraits;
+
+public:
+  comments::CommandTraits &getCommentCommandTraits() const {
+    return CommentCommandTraits;
+  }
+
   /// \brief Retrieve the attributes for the given declaration.
   AttrVec& getDeclAttrs(const Decl *D);
 

Modified: cfe/trunk/include/clang/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/AST/CMakeLists.txt Mon Sep 10 15:32:42 2012
@@ -28,3 +28,7 @@
   SOURCE CommentHTMLTags.td
   TARGET ClangCommentHTMLTagsProperties)
 
+clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info
+  SOURCE CommentCommands.td
+  TARGET ClangCommentCommandInfo)
+

Modified: cfe/trunk/include/clang/AST/Comment.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Comment.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Comment.h (original)
+++ cfe/trunk/include/clang/AST/Comment.h Mon Sep 10 15:32:42 2012
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 
@@ -74,8 +75,9 @@
     unsigned : NumInlineContentCommentBits;
 
     unsigned RenderKind : 2;
+    unsigned CommandID : 8;
   };
-  enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 };
+  enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
 
   class HTMLStartTagCommentBitfields {
     friend class HTMLStartTagComment;
@@ -101,10 +103,19 @@
   };
   enum { NumParagraphCommentBits = NumCommentBits + 2 };
 
+  class BlockCommandCommentBitfields {
+    friend class BlockCommandComment;
+
+    unsigned : NumCommentBits;
+
+    unsigned CommandID : 8;
+  };
+  enum { NumBlockCommandCommentBits = NumCommentBits + 8 };
+
   class ParamCommandCommentBitfields {
     friend class ParamCommandComment;
 
-    unsigned : NumCommentBits;
+    unsigned : NumBlockCommandCommentBits;
 
     /// Parameter passing direction, see ParamCommandComment::PassDirection.
     unsigned Direction : 2;
@@ -112,7 +123,7 @@
     /// True if direction was specified explicitly in the comment.
     unsigned IsDirectionExplicit : 1;
   };
-  enum { NumParamCommandCommentBits = 11 };
+  enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
 
   union {
     CommentBitfields CommentBits;
@@ -121,6 +132,7 @@
     InlineCommandCommentBitfields InlineCommandCommentBits;
     HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
     ParagraphCommentBitfields ParagraphCommentBits;
+    BlockCommandCommentBitfields BlockCommandCommentBits;
     ParamCommandCommentBitfields ParamCommandCommentBits;
   };
 
@@ -158,8 +170,9 @@
   const char *getCommentKindName() const;
 
   LLVM_ATTRIBUTE_USED void dump() const;
-  LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
-  void dump(llvm::raw_ostream &OS, SourceManager *SM) const;
+  LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
+  void dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
+            const SourceManager *SM) const;
 
   static bool classof(const Comment *) { return true; }
 
@@ -273,21 +286,19 @@
   };
 
 protected:
-  /// Command name.
-  StringRef Name;
-
   /// Command arguments.
   llvm::ArrayRef<Argument> Args;
 
 public:
   InlineCommandComment(SourceLocation LocBegin,
                        SourceLocation LocEnd,
-                       StringRef Name,
+                       unsigned CommandID,
                        RenderKind RK,
                        llvm::ArrayRef<Argument> Args) :
       InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
-      Name(Name), Args(Args) {
+      Args(Args) {
     InlineCommandCommentBits.RenderKind = RK;
+    InlineCommandCommentBits.CommandID = CommandID;
   }
 
   static bool classof(const Comment *C) {
@@ -300,8 +311,12 @@
 
   child_iterator child_end() const { return NULL; }
 
-  StringRef getCommandName() const {
-    return Name;
+  unsigned getCommandID() const {
+    return InlineCommandCommentBits.CommandID;
+  }
+
+  StringRef getCommandName(const CommandTraits &Traits) const {
+    return Traits.getCommandInfo(getCommandID())->Name;
   }
 
   SourceRange getCommandNameRange() const {
@@ -566,9 +581,6 @@
   };
 
 protected:
-  /// Command name.
-  StringRef Name;
-
   /// Word-like arguments.
   llvm::ArrayRef<Argument> Args;
 
@@ -578,21 +590,21 @@
   BlockCommandComment(CommentKind K,
                       SourceLocation LocBegin,
                       SourceLocation LocEnd,
-                      StringRef Name) :
+                      unsigned CommandID) :
       BlockContentComment(K, LocBegin, LocEnd),
-      Name(Name),
       Paragraph(NULL) {
-    setLocation(getCommandNameRange().getBegin());
+    setLocation(getCommandNameBeginLoc());
+    BlockCommandCommentBits.CommandID = CommandID;
   }
 
 public:
   BlockCommandComment(SourceLocation LocBegin,
                       SourceLocation LocEnd,
-                      StringRef Name) :
+                      unsigned CommandID) :
       BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
-      Name(Name),
       Paragraph(NULL) {
-    setLocation(getCommandNameRange().getBegin());
+    setLocation(getCommandNameBeginLoc());
+    BlockCommandCommentBits.CommandID = CommandID;
   }
 
   static bool classof(const Comment *C) {
@@ -610,12 +622,21 @@
     return reinterpret_cast<child_iterator>(&Paragraph + 1);
   }
 
-  StringRef getCommandName() const {
-    return Name;
+  unsigned getCommandID() const {
+    return BlockCommandCommentBits.CommandID;
   }
 
-  SourceRange getCommandNameRange() const {
-    return SourceRange(getLocStart().getLocWithOffset(1),
+  StringRef getCommandName(const CommandTraits &Traits) const {
+    return Traits.getCommandInfo(getCommandID())->Name;
+  }
+
+  SourceLocation getCommandNameBeginLoc() const {
+    return getLocStart().getLocWithOffset(1);
+  }
+
+  SourceRange getCommandNameRange(const CommandTraits &Traits) const {
+    StringRef Name = getCommandName(Traits);
+    return SourceRange(getCommandNameBeginLoc(),
                        getLocStart().getLocWithOffset(1 + Name.size()));
   }
 
@@ -667,8 +688,9 @@
 
   ParamCommandComment(SourceLocation LocBegin,
                       SourceLocation LocEnd,
-                      StringRef Name) :
-      BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, Name),
+                      unsigned CommandID) :
+      BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
+                          CommandID),
       ParamIndex(InvalidParamIndex) {
     ParamCommandCommentBits.Direction = In;
     ParamCommandCommentBits.IsDirectionExplicit = false;
@@ -748,8 +770,8 @@
 public:
   TParamCommandComment(SourceLocation LocBegin,
                        SourceLocation LocEnd,
-                       StringRef Name) :
-      BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, Name)
+                       unsigned CommandID) :
+      BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID)
   { }
 
   static bool classof(const Comment *C) {
@@ -830,9 +852,9 @@
 public:
   VerbatimBlockComment(SourceLocation LocBegin,
                        SourceLocation LocEnd,
-                       StringRef Name) :
+                       unsigned CommandID) :
       BlockCommandComment(VerbatimBlockCommentKind,
-                          LocBegin, LocEnd, Name)
+                          LocBegin, LocEnd, CommandID)
   { }
 
   static bool classof(const Comment *C) {
@@ -882,12 +904,12 @@
 public:
   VerbatimLineComment(SourceLocation LocBegin,
                       SourceLocation LocEnd,
-                      StringRef Name,
+                      unsigned CommandID,
                       SourceLocation TextBegin,
                       StringRef Text) :
       BlockCommandComment(VerbatimLineCommentKind,
                           LocBegin, LocEnd,
-                          Name),
+                          CommandID),
       Text(Text),
       TextBegin(TextBegin)
   { }

Modified: cfe/trunk/include/clang/AST/CommentCommandTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentCommandTraits.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CommentCommandTraits.h (original)
+++ cfe/trunk/include/clang/AST/CommentCommandTraits.h Mon Sep 10 15:32:42 2012
@@ -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
 

Added: cfe/trunk/include/clang/AST/CommentCommands.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentCommands.td?rev=163540&view=auto
==============================================================================
--- cfe/trunk/include/clang/AST/CommentCommands.td (added)
+++ cfe/trunk/include/clang/AST/CommentCommands.td Mon Sep 10 15:32:42 2012
@@ -0,0 +1,133 @@
+class Command<string name> {
+  string Name = name;
+  string EndCommandName = "";
+
+  int NumArgs = 0;
+
+  bit IsInlineCommand = 0;
+
+  bit IsBlockCommand = 0;
+  bit IsBriefCommand = 0;
+  bit IsReturnsCommand = 0;
+  bit IsParamCommand = 0;
+  bit IsTParamCommand = 0;
+
+  bit IsVerbatimBlockCommand = 0;
+  bit IsVerbatimBlockEndCommand = 0;
+  bit IsVerbatimLineCommand = 0;
+  bit IsDeclarationCommand = 0;
+}
+
+class InlineCommand<string name> : Command<name> {
+  let IsInlineCommand = 1;
+}
+
+class BlockCommand<string name> : Command<name> {
+  let IsBlockCommand = 1;
+}
+
+class VerbatimBlockCommand<string name> : Command<name> {
+  let EndCommandName = name;
+  let IsVerbatimBlockCommand = 1;
+}
+
+multiclass VerbatimBlockCommand<string name, string endCommandName> {
+  def Begin : Command<name> {
+    let EndCommandName = endCommandName;
+    let IsVerbatimBlockCommand = 1;
+  }
+
+  def End : Command<endCommandName> {
+    let IsVerbatimBlockEndCommand = 1;
+  }
+}
+
+class VerbatimLineCommand<string name> : Command<name> {
+  let IsVerbatimLineCommand = 1;
+}
+
+class DeclarationVerbatimLineCommand<string name> :
+      VerbatimLineCommand<name> {
+  let IsDeclarationCommand = 1;
+}
+
+def B  : InlineCommand<"b">;
+def C  : InlineCommand<"c">;
+def P  : InlineCommand<"p">;
+def A  : InlineCommand<"a">;
+def E  : InlineCommand<"e">;
+def Em : InlineCommand<"em">;
+
+def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; }
+def Short : BlockCommand<"short"> { let IsBriefCommand = 1; }
+
+def Returns : BlockCommand<"returns"> { let IsReturnsCommand = 1; }
+def Return  : BlockCommand<"return"> { let IsReturnsCommand = 1; }
+def Result  : BlockCommand<"result"> { let IsReturnsCommand = 1; }
+
+def Param : BlockCommand<"param"> { let IsParamCommand = 1; }
+
+// Doxygen
+def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
+
+// HeaderDoc
+def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
+
+def Author  : BlockCommand<"author">;
+def Authors : BlockCommand<"authors">;
+def Pre     : BlockCommand<"pre">;
+def Post    : BlockCommand<"post">;
+
+defm Code      : VerbatimBlockCommand<"code", "endcode">;
+defm Verbatim  : VerbatimBlockCommand<"verbatim", "endverbatim">;
+defm Htmlonly  : VerbatimBlockCommand<"htmlonly", "endhtmlonly">;
+defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">;
+defm Xmlonly   : VerbatimBlockCommand<"xmlonly", "endxmlonly">;
+defm Manonly   : VerbatimBlockCommand<"manonly", "endmanonly">;
+defm Rtfonly   : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
+
+defm Dot : VerbatimBlockCommand<"dot", "enddot">;
+defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
+
+// These commands have special support in lexer.
+def  FDollar  : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
+defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
+defm FBrace   : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
+
+def Defgroup   : VerbatimLineCommand<"defgroup">;
+def Ingroup    : VerbatimLineCommand<"ingroup">;
+def Addtogroup : VerbatimLineCommand<"addtogroup">;
+def Weakgroup  : VerbatimLineCommand<"weakgroup">;
+def Name       : VerbatimLineCommand<"name">;
+
+def Section       : VerbatimLineCommand<"section">;
+def Subsection    : VerbatimLineCommand<"subsection">;
+def Subsubsection : VerbatimLineCommand<"subsubsection">;
+def Paragraph     : VerbatimLineCommand<"paragraph">;
+
+def Mainpage : VerbatimLineCommand<"mainpage">;
+def Subpage  : VerbatimLineCommand<"subpage">;
+def Ref      : VerbatimLineCommand<"ref">;
+
+// Doxygen commands.
+def Fn       : DeclarationVerbatimLineCommand<"fn">;
+def Var      : DeclarationVerbatimLineCommand<"var">;
+def Property : DeclarationVerbatimLineCommand<"property">;
+def Typedef  : DeclarationVerbatimLineCommand<"typedef">;
+def Overload : DeclarationVerbatimLineCommand<"overload">;
+
+// HeaderDoc commands.
+def Class     : DeclarationVerbatimLineCommand<"class">;
+def Interface : DeclarationVerbatimLineCommand<"interface">;
+def Protocol  : DeclarationVerbatimLineCommand<"protocol">;
+def Category  : DeclarationVerbatimLineCommand<"category">;
+def Template  : DeclarationVerbatimLineCommand<"template">;
+def Function  : DeclarationVerbatimLineCommand<"function">;
+def Method    : DeclarationVerbatimLineCommand<"method">;
+def Callback  : DeclarationVerbatimLineCommand<"callback">;
+def Const     : DeclarationVerbatimLineCommand<"const">;
+def Constant  : DeclarationVerbatimLineCommand<"constant">;
+def Struct    : DeclarationVerbatimLineCommand<"struct">;
+def Union     : DeclarationVerbatimLineCommand<"union">;
+def Enum      : DeclarationVerbatimLineCommand<"enum">;
+

Modified: cfe/trunk/include/clang/AST/CommentLexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentLexer.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CommentLexer.h (original)
+++ cfe/trunk/include/clang/AST/CommentLexer.h Mon Sep 10 15:32:42 2012
@@ -26,6 +26,7 @@
 
 class Lexer;
 class TextTokenRetokenizer;
+struct CommandInfo;
 class CommandTraits;
 
 namespace tok {
@@ -33,6 +34,7 @@
   eof,
   newline,
   text,
+  unknown_command,
   command,
   verbatim_block_begin,
   verbatim_block_line,
@@ -65,8 +67,14 @@
   unsigned Length;
 
   /// Contains text value associated with a token.
-  const char *TextPtr1;
-  unsigned TextLen1;
+  const char *TextPtr;
+
+  /// Integer value associated with a token.
+  ///
+  /// If the token is a konwn command, contains command ID and TextPtr is
+  /// unused (command spelling can be found with CommandTraits).  Otherwise,
+  /// contains the length of the string that starts at TextPtr.
+  unsigned IntVal;
 
 public:
   SourceLocation getLocation() const LLVM_READONLY { return Loc; }
@@ -89,113 +97,120 @@
 
   StringRef getText() const LLVM_READONLY {
     assert(is(tok::text));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setText(StringRef Text) {
     assert(is(tok::text));
-    TextPtr1 = Text.data();
-    TextLen1 = Text.size();
+    TextPtr = Text.data();
+    IntVal = Text.size();
+  }
+
+  StringRef getUnknownCommandName() const LLVM_READONLY {
+    assert(is(tok::unknown_command));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setUnknownCommandName(StringRef Name) {
+    assert(is(tok::unknown_command));
+    TextPtr = Name.data();
+    IntVal = Name.size();
   }
 
-  StringRef getCommandName() const LLVM_READONLY {
+  unsigned getCommandID() const LLVM_READONLY {
     assert(is(tok::command));
-    return StringRef(TextPtr1, TextLen1);
+    return IntVal;
   }
 
-  void setCommandName(StringRef Name) {
+  void setCommandID(unsigned ID) {
     assert(is(tok::command));
-    TextPtr1 = Name.data();
-    TextLen1 = Name.size();
+    IntVal = ID;
   }
 
-  StringRef getVerbatimBlockName() const LLVM_READONLY {
+  unsigned getVerbatimBlockID() const LLVM_READONLY {
     assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
-    return StringRef(TextPtr1, TextLen1);
+    return IntVal;
   }
 
-  void setVerbatimBlockName(StringRef Name) {
+  void setVerbatimBlockID(unsigned ID) {
     assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
-    TextPtr1 = Name.data();
-    TextLen1 = Name.size();
+    IntVal = ID;
   }
 
   StringRef getVerbatimBlockText() const LLVM_READONLY {
     assert(is(tok::verbatim_block_line));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setVerbatimBlockText(StringRef Text) {
     assert(is(tok::verbatim_block_line));
-    TextPtr1 = Text.data();
-    TextLen1 = Text.size();
+    TextPtr = Text.data();
+    IntVal = Text.size();
   }
 
-  /// Returns the name of verbatim line command.
-  StringRef getVerbatimLineName() const LLVM_READONLY {
+  unsigned getVerbatimLineID() const LLVM_READONLY {
     assert(is(tok::verbatim_line_name));
-    return StringRef(TextPtr1, TextLen1);
+    return IntVal;
   }
 
-  void setVerbatimLineName(StringRef Name) {
+  void setVerbatimLineID(unsigned ID) {
     assert(is(tok::verbatim_line_name));
-    TextPtr1 = Name.data();
-    TextLen1 = Name.size();
+    IntVal = ID;
   }
 
   StringRef getVerbatimLineText() const LLVM_READONLY {
     assert(is(tok::verbatim_line_text));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setVerbatimLineText(StringRef Text) {
     assert(is(tok::verbatim_line_text));
-    TextPtr1 = Text.data();
-    TextLen1 = Text.size();
+    TextPtr = Text.data();
+    IntVal = Text.size();
   }
 
   StringRef getHTMLTagStartName() const LLVM_READONLY {
     assert(is(tok::html_start_tag));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setHTMLTagStartName(StringRef Name) {
     assert(is(tok::html_start_tag));
-    TextPtr1 = Name.data();
-    TextLen1 = Name.size();
+    TextPtr = Name.data();
+    IntVal = Name.size();
   }
 
   StringRef getHTMLIdent() const LLVM_READONLY {
     assert(is(tok::html_ident));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setHTMLIdent(StringRef Name) {
     assert(is(tok::html_ident));
-    TextPtr1 = Name.data();
-    TextLen1 = Name.size();
+    TextPtr = Name.data();
+    IntVal = Name.size();
   }
 
   StringRef getHTMLQuotedString() const LLVM_READONLY {
     assert(is(tok::html_quoted_string));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setHTMLQuotedString(StringRef Str) {
     assert(is(tok::html_quoted_string));
-    TextPtr1 = Str.data();
-    TextLen1 = Str.size();
+    TextPtr = Str.data();
+    IntVal = Str.size();
   }
 
   StringRef getHTMLTagEndName() const LLVM_READONLY {
     assert(is(tok::html_end_tag));
-    return StringRef(TextPtr1, TextLen1);
+    return StringRef(TextPtr, IntVal);
   }
 
   void setHTMLTagEndName(StringRef Name) {
     assert(is(tok::html_end_tag));
-    TextPtr1 = Name.data();
-    TextLen1 = Name.size();
+    TextPtr = Name.data();
+    IntVal = Name.size();
   }
 
   void dump(const Lexer &L, const SourceManager &SM) const;
@@ -280,8 +295,8 @@
     Result.setKind(Kind);
     Result.setLength(TokLen);
 #ifndef NDEBUG
-    Result.TextPtr1 = "<UNSET>";
-    Result.TextLen1 = 7;
+    Result.TextPtr = "<UNSET>";
+    Result.IntVal = 7;
 #endif
     BufferPtr = TokEnd;
   }
@@ -308,13 +323,14 @@
 
   void setupAndLexVerbatimBlock(Token &T,
                                 const char *TextBegin,
-                                char Marker, StringRef EndName);
+                                char Marker, const CommandInfo *Info);
 
   void lexVerbatimBlockFirstLine(Token &T);
 
   void lexVerbatimBlockBody(Token &T);
 
-  void setupAndLexVerbatimLine(Token &T, const char *TextBegin);
+  void setupAndLexVerbatimLine(Token &T, const char *TextBegin,
+                               const CommandInfo *Info);
 
   void lexVerbatimLineText(Token &T);
 

Modified: cfe/trunk/include/clang/AST/CommentSema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentSema.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CommentSema.h (original)
+++ cfe/trunk/include/clang/AST/CommentSema.h Mon Sep 10 15:32:42 2012
@@ -41,7 +41,7 @@
 
   DiagnosticsEngine &Diags;
 
-  const CommandTraits &Traits;
+  CommandTraits &Traits;
 
   /// Information about the declaration this comment is attached to.
   DeclInfo *ThisDeclInfo;
@@ -68,7 +68,7 @@
 
 public:
   Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
-       DiagnosticsEngine &Diags, const CommandTraits &Traits);
+       DiagnosticsEngine &Diags, CommandTraits &Traits);
 
   void setDecl(const Decl *D);
 
@@ -89,7 +89,7 @@
 
   BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
                                               SourceLocation LocEnd,
-                                              StringRef Name);
+                                              unsigned CommandID);
 
   void actOnBlockCommandArgs(BlockCommandComment *Command,
                              ArrayRef<BlockCommandComment::Argument> Args);
@@ -99,7 +99,7 @@
 
   ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
                                               SourceLocation LocEnd,
-                                              StringRef Name);
+                                              unsigned CommandID);
 
   void actOnParamCommandDirectionArg(ParamCommandComment *Command,
                                      SourceLocation ArgLocBegin,
@@ -116,7 +116,7 @@
 
   TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
                                                 SourceLocation LocEnd,
-                                                StringRef Name);
+                                                unsigned CommandID);
 
   void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
                                       SourceLocation ArgLocBegin,
@@ -128,11 +128,11 @@
 
   InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
                                            SourceLocation CommandLocEnd,
-                                           StringRef CommandName);
+                                           unsigned CommandID);
 
   InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
                                            SourceLocation CommandLocEnd,
-                                           StringRef CommandName,
+                                           unsigned CommandID,
                                            SourceLocation ArgLocBegin,
                                            SourceLocation ArgLocEnd,
                                            StringRef Arg);
@@ -146,7 +146,7 @@
                          StringRef Text);
 
   VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
-                                                StringRef Name);
+                                                unsigned CommandID);
 
   VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
                                                    StringRef Text);
@@ -157,7 +157,7 @@
                                 ArrayRef<VerbatimBlockLineComment *> Lines);
 
   VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
-                                         StringRef Name,
+                                         unsigned CommandID,
                                          SourceLocation TextBegin,
                                          StringRef Text);
 

Modified: cfe/trunk/include/clang/AST/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Makefile?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Makefile (original)
+++ cfe/trunk/include/clang/AST/Makefile Mon Sep 10 15:32:42 2012
@@ -2,7 +2,7 @@
 TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
 BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \
                 CommentNodes.inc CommentHTMLTags.inc \
-                CommentHTMLTagsProperties.inc
+                CommentHTMLTagsProperties.inc CommentCommandInfo.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
@@ -45,3 +45,8 @@
 	$(Echo) "Building Clang comment HTML tag properties with tblgen"
 	$(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $<
 
+$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
+                                              $(CLANG_TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang comment command info with tblgen"
+	$(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $<
+

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Sep 10 15:32:42 2012
@@ -573,6 +573,7 @@
     DeclarationNames(*this),
     ExternalSource(0), Listener(0),
     Comments(SM), CommentsLoaded(false),
+    CommentCommandTraits(BumpAlloc),
     LastSDM(0, 0),
     UniqueBlockByRefTypeID(0) 
 {

Modified: cfe/trunk/lib/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CMakeLists.txt (original)
+++ cfe/trunk/lib/AST/CMakeLists.txt Mon Sep 10 15:32:42 2012
@@ -64,6 +64,7 @@
   ClangAttrClasses
   ClangAttrList
   ClangAttrImpl
+  ClangCommentCommandInfo
   ClangCommentNodes
   ClangCommentHTMLTags
   ClangCommentHTMLTagsProperties

Modified: cfe/trunk/lib/AST/Comment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Comment.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Comment.cpp (original)
+++ cfe/trunk/lib/AST/Comment.cpp Mon Sep 10 15:32:42 2012
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/Comment.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -37,11 +38,12 @@
   // in CommentDumper.cpp, that object file would be removed by linker because
   // none of its functions are referenced by other object files, despite the
   // LLVM_ATTRIBUTE_USED.
-  dump(llvm::errs(), NULL);
+  dump(llvm::errs(), NULL, NULL);
 }
 
-void Comment::dump(SourceManager &SM) const {
-  dump(llvm::errs(), &SM);
+void Comment::dump(const ASTContext &Context) const {
+  dump(llvm::errs(), &Context.getCommentCommandTraits(),
+       &Context.getSourceManager());
 }
 
 namespace {

Modified: cfe/trunk/lib/AST/CommentBriefParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentBriefParser.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentBriefParser.cpp (original)
+++ cfe/trunk/lib/AST/CommentBriefParser.cpp Mon Sep 10 15:32:42 2012
@@ -79,14 +79,14 @@
     }
 
     if (Tok.is(tok::command)) {
-      StringRef Name = Tok.getCommandName();
-      if (Traits.isBriefCommand(Name)) {
+      const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
+      if (Info->IsBriefCommand) {
         FirstParagraphOrBrief.clear();
         InBrief = true;
         ConsumeToken();
         continue;
       }
-      if (Traits.isReturnsCommand(Name)) {
+      if (Info->IsReturnsCommand) {
         InReturns = true;
         InBrief = false;
         InFirstParagraph = false;
@@ -95,7 +95,7 @@
         continue;
       }
       // Block commands implicitly start a new paragraph.
-      if (Traits.isBlockCommand(Name)) {
+      if (Info->IsBlockCommand) {
         // We found an implicit paragraph end.
         InFirstParagraph = false;
         if (InBrief)

Modified: cfe/trunk/lib/AST/CommentCommandTraits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentCommandTraits.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentCommandTraits.cpp (original)
+++ cfe/trunk/lib/AST/CommentCommandTraits.cpp Mon Sep 10 15:32:42 2012
@@ -8,125 +8,63 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/CommentCommandTraits.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/STLExtras.h"
 
 namespace clang {
 namespace comments {
 
-// TODO: tablegen
+#include "clang/AST/CommentCommandInfo.inc"
 
-bool CommandTraits::isVerbatimBlockCommand(StringRef StartName,
-                                           StringRef &EndName) const {
-  const char *Result = llvm::StringSwitch<const char *>(StartName)
-    .Case("code", "endcode")
-    .Case("verbatim", "endverbatim")
-    .Case("htmlonly", "endhtmlonly")
-    .Case("latexonly", "endlatexonly")
-    .Case("xmlonly", "endxmlonly")
-    .Case("manonly", "endmanonly")
-    .Case("rtfonly", "endrtfonly")
-
-    .Case("dot", "enddot")
-    .Case("msc", "endmsc")
-
-    .Case("f$", "f$") // Inline LaTeX formula
-    .Case("f[", "f]") // Displayed LaTeX formula
-    .Case("f{", "f}") // LaTeX environment
-
-    .Default(NULL);
-
-  if (Result) {
-    EndName = Result;
-    return true;
+CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator) :
+    NextID(llvm::array_lengthof(Commands)), Allocator(Allocator)
+{ }
+
+const CommandInfo *CommandTraits::getCommandInfoOrNULL(StringRef Name) const {
+  if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
+    return Info;
+  return getRegisteredCommandInfo(Name);
+}
+
+const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
+  if (const CommandInfo *Info = getBuiltinCommandInfo(CommandID))
+    return Info;
+  return getRegisteredCommandInfo(CommandID);
+}
+
+const CommandInfo *CommandTraits::registerUnknownCommand(StringRef CommandName) {
+  char *Name = Allocator.Allocate<char>(CommandName.size());
+  memcpy(Name, CommandName.data(), CommandName.size());
+  Name[CommandName.size() + 1] = '\0';
+
+  // Value-initialize (=zero-initialize in this case) a new CommandInfo.
+  CommandInfo *Info = new (Allocator) CommandInfo();
+  Info->Name = Name;
+  Info->ID = NextID++;
+
+  RegisteredCommands.push_back(Info);
+
+  return Info;
+}
+
+const CommandInfo *CommandTraits::getBuiltinCommandInfo(
+                                                  unsigned CommandID) {
+  if (CommandID < llvm::array_lengthof(Commands))
+    return &Commands[CommandID];
+  return NULL;
+}
+
+const CommandInfo *CommandTraits::getRegisteredCommandInfo(
+                                                  StringRef Name) const {
+  for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i) {
+    if (RegisteredCommands[i]->Name == Name)
+      return RegisteredCommands[i];
   }
+  return NULL;
+}
 
-  for (VerbatimBlockCommandVector::const_iterator
-           I = VerbatimBlockCommands.begin(),
-           E = VerbatimBlockCommands.end();
-       I != E; ++I)
-    if (I->StartName == StartName) {
-      EndName = I->EndName;
-      return true;
-    }
-
-  return false;
-}
-
-bool CommandTraits::isVerbatimLineCommand(StringRef Name) const {
-  bool Result = isDeclarationCommand(Name) || llvm::StringSwitch<bool>(Name)
-  .Case("defgroup", true)
-  .Case("ingroup", true)
-  .Case("addtogroup", true)
-  .Case("weakgroup", true)
-  .Case("name", true)
-
-  .Case("section", true)
-  .Case("subsection", true)
-  .Case("subsubsection", true)
-  .Case("paragraph", true)
-
-  .Case("mainpage", true)
-  .Case("subpage", true)
-  .Case("ref", true)
-
-  .Default(false);
-
-  if (Result)
-    return true;
-
-  for (VerbatimLineCommandVector::const_iterator
-           I = VerbatimLineCommands.begin(),
-           E = VerbatimLineCommands.end();
-       I != E; ++I)
-    if (I->Name == Name)
-      return true;
-
-  return false;
-}
-
-bool CommandTraits::isDeclarationCommand(StringRef Name) const {
-  return llvm::StringSwitch<bool>(Name)
-      // Doxygen commands.
-      .Case("fn", true)
-      .Case("var", true)
-      .Case("property", true)
-      .Case("typedef", true)
-
-      .Case("overload", true)
-
-      // HeaderDoc commands.
-      .Case("class", true)
-      .Case("interface", true)
-      .Case("protocol", true)
-      .Case("category", true)
-      .Case("template", true)
-      .Case("function", true)
-      .Case("method", true)
-      .Case("callback", true)
-      .Case("var", true)
-      .Case("const", true)
-      .Case("constant", true)
-      .Case("property", true)
-      .Case("struct", true)
-      .Case("union", true)
-      .Case("typedef", true)
-      .Case("enum", true)
-
-      .Default(false);
-}
-
-void CommandTraits::addVerbatimBlockCommand(StringRef StartName,
-                                            StringRef EndName) {
-  VerbatimBlockCommand VBC;
-  VBC.StartName = StartName;
-  VBC.EndName = EndName;
-  VerbatimBlockCommands.push_back(VBC);
-}
-
-void CommandTraits::addVerbatimLineCommand(StringRef Name) {
-  VerbatimLineCommand VLC;
-  VLC.Name = Name;
-  VerbatimLineCommands.push_back(VLC);
+const CommandInfo *CommandTraits::getRegisteredCommandInfo(
+                                                  unsigned CommandID) const {
+  return RegisteredCommands[CommandID - llvm::array_lengthof(Commands)];
 }
 
 } // end namespace comments

Modified: cfe/trunk/lib/AST/CommentDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentDumper.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentDumper.cpp (original)
+++ cfe/trunk/lib/AST/CommentDumper.cpp Mon Sep 10 15:32:42 2012
@@ -16,12 +16,15 @@
 namespace {
 class CommentDumper: public comments::ConstCommentVisitor<CommentDumper> {
   raw_ostream &OS;
-  SourceManager *SM;
+  const CommandTraits *Traits;
+  const SourceManager *SM;
   unsigned IndentLevel;
 
 public:
-  CommentDumper(raw_ostream &OS, SourceManager *SM) :
-      OS(OS), SM(SM), IndentLevel(0)
+  CommentDumper(raw_ostream &OS,
+                const CommandTraits *Traits,
+                const SourceManager *SM) :
+      OS(OS), Traits(Traits), SM(SM), IndentLevel(0)
   { }
 
   void dumpIndent() const {
@@ -56,6 +59,15 @@
   void visitVerbatimLineComment(const VerbatimLineComment *C);
 
   void visitFullComment(const FullComment *C);
+
+  const char *getCommandName(unsigned CommandID) {
+    if (Traits)
+      return Traits->getCommandInfo(CommandID)->Name;
+    const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
+    if (Info)
+      return Info->Name;
+    return "<not a builtin command>";
+  }
 };
 
 void CommentDumper::dumpSourceRange(const Comment *C) {
@@ -107,7 +119,7 @@
 void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
   dumpComment(C);
 
-  OS << " Name=\"" << C->getCommandName() << "\"";
+  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
   switch (C->getRenderKind()) {
   case InlineCommandComment::RenderNormal:
     OS << " RenderNormal";
@@ -155,7 +167,7 @@
 void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) {
   dumpComment(C);
 
-  OS << " Name=\"" << C->getCommandName() << "\"";
+  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
 }
@@ -198,7 +210,7 @@
 void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
   dumpComment(C);
 
-  OS << " Name=\"" << C->getCommandName() << "\""
+  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
         " CloseName=\"" << C->getCloseName() << "\"";
 }
 
@@ -220,8 +232,9 @@
 
 } // unnamed namespace
 
-void Comment::dump(llvm::raw_ostream &OS, SourceManager *SM) const {
-  CommentDumper D(llvm::errs(), SM);
+void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
+                   const SourceManager *SM) const {
+  CommentDumper D(llvm::errs(), Traits, SM);
   D.dumpSubtree(this);
   llvm::errs() << '\n';
 }

Modified: cfe/trunk/lib/AST/CommentLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentLexer.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentLexer.cpp (original)
+++ cfe/trunk/lib/AST/CommentLexer.cpp Mon Sep 10 15:32:42 2012
@@ -359,18 +359,23 @@
         }
 
         const StringRef CommandName(BufferPtr + 1, Length);
-        StringRef EndName;
 
-        if (Traits.isVerbatimBlockCommand(CommandName, EndName)) {
-          setupAndLexVerbatimBlock(T, TokenPtr, *BufferPtr, EndName);
+        const CommandInfo *Info = Traits.getCommandInfoOrNULL(CommandName);
+        if (!Info) {
+          formTokenWithChars(T, TokenPtr, tok::unknown_command);
+          T.setUnknownCommandName(CommandName);
           return;
         }
-        if (Traits.isVerbatimLineCommand(CommandName)) {
-          setupAndLexVerbatimLine(T, TokenPtr);
+        if (Info->IsVerbatimBlockCommand) {
+          setupAndLexVerbatimBlock(T, TokenPtr, *BufferPtr, Info);
+          return;
+        }
+        if (Info->IsVerbatimLineCommand) {
+          setupAndLexVerbatimLine(T, TokenPtr, Info);
           return;
         }
         formTokenWithChars(T, TokenPtr, tok::command);
-        T.setCommandName(CommandName);
+        T.setCommandID(Info->getID());
         return;
       }
 
@@ -423,14 +428,15 @@
 
 void Lexer::setupAndLexVerbatimBlock(Token &T,
                                      const char *TextBegin,
-                                     char Marker, StringRef EndName) {
+                                     char Marker, const CommandInfo *Info) {
+  assert(Info->IsVerbatimBlockCommand);
+
   VerbatimBlockEndCommandName.clear();
   VerbatimBlockEndCommandName.append(Marker == '\\' ? "\\" : "@");
-  VerbatimBlockEndCommandName.append(EndName);
+  VerbatimBlockEndCommandName.append(Info->EndCommandName);
 
-  StringRef Name(BufferPtr + 1, TextBegin - (BufferPtr + 1));
   formTokenWithChars(T, TextBegin, tok::verbatim_block_begin);
-  T.setVerbatimBlockName(Name);
+  T.setVerbatimBlockID(Info->getID());
 
   // If there is a newline following the verbatim opening command, skip the
   // newline so that we don't create an tok::verbatim_block_line with empty
@@ -471,7 +477,7 @@
     const char *End = BufferPtr + VerbatimBlockEndCommandName.size();
     StringRef Name(BufferPtr + 1, End - (BufferPtr + 1));
     formTokenWithChars(T, End, tok::verbatim_block_end);
-    T.setVerbatimBlockName(Name);
+    T.setVerbatimBlockID(Traits.getCommandInfo(Name)->getID());
     State = LS_Normal;
     return;
   } else {
@@ -501,10 +507,11 @@
   lexVerbatimBlockFirstLine(T);
 }
 
-void Lexer::setupAndLexVerbatimLine(Token &T, const char *TextBegin) {
-  const StringRef Name(BufferPtr + 1, TextBegin - BufferPtr - 1);
+void Lexer::setupAndLexVerbatimLine(Token &T, const char *TextBegin,
+                                    const CommandInfo *Info) {
+  assert(Info->IsVerbatimLineCommand);
   formTokenWithChars(T, TextBegin, tok::verbatim_line_name);
-  T.setVerbatimLineName(Name);
+  T.setVerbatimLineID(Info->getID());
 
   State = LS_VerbatimLineText;
 }

Modified: cfe/trunk/lib/AST/CommentParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentParser.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentParser.cpp (original)
+++ cfe/trunk/lib/AST/CommentParser.cpp Mon Sep 10 15:32:42 2012
@@ -132,8 +132,8 @@
     Result.setKind(tok::text);
     Result.setLength(TokLength);
 #ifndef NDEBUG
-    Result.TextPtr1 = "<UNSET>";
-    Result.TextLen1 = 7;
+    Result.TextPtr = "<UNSET>";
+    Result.IntVal = 7;
 #endif
     Result.setText(Text);
   }
@@ -312,26 +312,26 @@
   BlockCommandComment *BC;
   bool IsParam = false;
   bool IsTParam = false;
-  unsigned NumArgs = 0;
-  if (Traits.isParamCommand(Tok.getCommandName())) {
+  const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
+  if (Info->IsParamCommand) {
     IsParam = true;
     PC = S.actOnParamCommandStart(Tok.getLocation(),
                                   Tok.getEndLocation(),
-                                  Tok.getCommandName());
-  } if (Traits.isTParamCommand(Tok.getCommandName())) {
+                                  Tok.getCommandID());
+  } if (Info->IsTParamCommand) {
     IsTParam = true;
     TPC = S.actOnTParamCommandStart(Tok.getLocation(),
                                     Tok.getEndLocation(),
-                                    Tok.getCommandName());
+                                    Tok.getCommandID());
   } else {
-    NumArgs = Traits.getBlockCommandNumArgs(Tok.getCommandName());
     BC = S.actOnBlockCommandStart(Tok.getLocation(),
                                   Tok.getEndLocation(),
-                                  Tok.getCommandName());
+                                  Tok.getCommandID());
   }
   consumeToken();
 
-  if (Tok.is(tok::command) && Traits.isBlockCommand(Tok.getCommandName())) {
+  if (Tok.is(tok::command) &&
+      Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand) {
     // Block command ahead.  We can't nest block commands, so pretend that this
     // command has an empty argument.
     ParagraphComment *Paragraph = S.actOnParagraphComment(
@@ -348,7 +348,7 @@
     }
   }
 
-  if (IsParam || IsTParam || NumArgs > 0) {
+  if (IsParam || IsTParam || Info->NumArgs > 0) {
     // In order to parse command arguments we need to retokenize a few
     // following text tokens.
     TextTokenRetokenizer Retokenizer(Allocator, *this);
@@ -358,7 +358,7 @@
     else if (IsTParam)
       parseTParamCommandArgs(TPC, Retokenizer);
     else
-      parseBlockCommandArgs(BC, Retokenizer, NumArgs);
+      parseBlockCommandArgs(BC, Retokenizer, Info->NumArgs);
 
     Retokenizer.putBackLeftoverTokens();
   }
@@ -394,14 +394,14 @@
   if (ArgTokValid) {
     IC = S.actOnInlineCommand(CommandTok.getLocation(),
                               CommandTok.getEndLocation(),
-                              CommandTok.getCommandName(),
+                              CommandTok.getCommandID(),
                               ArgTok.getLocation(),
                               ArgTok.getEndLocation(),
                               ArgTok.getText());
   } else {
     IC = S.actOnInlineCommand(CommandTok.getLocation(),
                               CommandTok.getEndLocation(),
-                              CommandTok.getCommandName());
+                              CommandTok.getCommandID());
   }
 
   Retokenizer.putBackLeftoverTokens();
@@ -540,23 +540,24 @@
       assert(Content.size() != 0);
       break; // Block content or EOF ahead, finish this parapgaph.
 
-    case tok::command:
-      if (Traits.isBlockCommand(Tok.getCommandName())) {
+    case tok::unknown_command:
+      Content.push_back(S.actOnUnknownCommand(Tok.getLocation(),
+                                              Tok.getEndLocation(),
+                                              Tok.getUnknownCommandName()));
+      consumeToken();
+      continue;
+
+    case tok::command: {
+      const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
+      if (Info->IsBlockCommand) {
         if (Content.size() == 0)
           return parseBlockCommand();
         break; // Block command ahead, finish this parapgaph.
       }
-      if (Traits.isInlineCommand(Tok.getCommandName())) {
-        Content.push_back(parseInlineCommand());
-        continue;
-      }
-
-      // Not a block command, not an inline command ==> an unknown command.
-      Content.push_back(S.actOnUnknownCommand(Tok.getLocation(),
-                                              Tok.getEndLocation(),
-                                              Tok.getCommandName()));
-      consumeToken();
+      assert(Info->IsInlineCommand);
+      Content.push_back(parseInlineCommand());
       continue;
+    }
 
     case tok::newline: {
       consumeToken();
@@ -606,7 +607,7 @@
 
   VerbatimBlockComment *VB =
       S.actOnVerbatimBlockStart(Tok.getLocation(),
-                                Tok.getVerbatimBlockName());
+                                Tok.getVerbatimBlockID());
   consumeToken();
 
   // Don't create an empty line if verbatim opening command is followed
@@ -634,8 +635,9 @@
   }
 
   if (Tok.is(tok::verbatim_block_end)) {
+    const CommandInfo *Info = Traits.getCommandInfo(Tok.getVerbatimBlockID());
     S.actOnVerbatimBlockFinish(VB, Tok.getLocation(),
-                               Tok.getVerbatimBlockName(),
+                               Info->Name,
                                S.copyArray(llvm::makeArrayRef(Lines)));
     consumeToken();
   } else {
@@ -666,7 +668,7 @@
   }
 
   VerbatimLineComment *VL = S.actOnVerbatimLine(NameTok.getLocation(),
-                                                NameTok.getVerbatimLineName(),
+                                                NameTok.getVerbatimLineID(),
                                                 TextBegin,
                                                 Text);
   consumeToken();
@@ -676,6 +678,7 @@
 BlockContentComment *Parser::parseBlockContent() {
   switch (Tok.getKind()) {
   case tok::text:
+  case tok::unknown_command:
   case tok::command:
   case tok::html_start_tag:
   case tok::html_end_tag:

Modified: cfe/trunk/lib/AST/CommentSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentSema.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentSema.cpp (original)
+++ cfe/trunk/lib/AST/CommentSema.cpp Mon Sep 10 15:32:42 2012
@@ -23,7 +23,7 @@
 } // unnamed namespace
 
 Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
-           DiagnosticsEngine &Diags, const CommandTraits &Traits) :
+           DiagnosticsEngine &Diags, CommandTraits &Traits) :
     Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
     ThisDeclInfo(NULL), BriefCommand(NULL), ReturnsCommand(NULL) {
 }
@@ -44,8 +44,8 @@
 
 BlockCommandComment *Sema::actOnBlockCommandStart(SourceLocation LocBegin,
                                                   SourceLocation LocEnd,
-                                                  StringRef Name) {
-  return new (Allocator) BlockCommandComment(LocBegin, LocEnd, Name);
+                                                  unsigned CommandID) {
+  return new (Allocator) BlockCommandComment(LocBegin, LocEnd, CommandID);
 }
 
 void Sema::actOnBlockCommandArgs(BlockCommandComment *Command,
@@ -63,14 +63,14 @@
 
 ParamCommandComment *Sema::actOnParamCommandStart(SourceLocation LocBegin,
                                                   SourceLocation LocEnd,
-                                                  StringRef Name) {
+                                                  unsigned CommandID) {
   ParamCommandComment *Command =
-      new (Allocator) ParamCommandComment(LocBegin, LocEnd, Name);
+      new (Allocator) ParamCommandComment(LocBegin, LocEnd, CommandID);
 
   if (!isFunctionDecl())
     Diag(Command->getLocation(),
          diag::warn_doc_param_not_attached_to_a_function_decl)
-      << Command->getCommandNameRange();
+      << Command->getCommandNameRange(Traits);
 
   return Command;
 }
@@ -156,14 +156,14 @@
 
 TParamCommandComment *Sema::actOnTParamCommandStart(SourceLocation LocBegin,
                                                     SourceLocation LocEnd,
-                                                    StringRef Name) {
+                                                    unsigned CommandID) {
   TParamCommandComment *Command =
-      new (Allocator) TParamCommandComment(LocBegin, LocEnd, Name);
+      new (Allocator) TParamCommandComment(LocBegin, LocEnd, CommandID);
 
   if (!isTemplateOrSpecialization())
     Diag(Command->getLocation(),
          diag::warn_doc_tparam_not_attached_to_a_template_decl)
-      << Command->getCommandNameRange();
+      << Command->getCommandNameRange(Traits);
 
   return Command;
 }
@@ -239,19 +239,20 @@
 
 InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
                                                SourceLocation CommandLocEnd,
-                                               StringRef CommandName) {
+                                               unsigned CommandID) {
   ArrayRef<InlineCommandComment::Argument> Args;
+  StringRef CommandName = Traits.getCommandInfo(CommandID)->Name;
   return new (Allocator) InlineCommandComment(
                                   CommandLocBegin,
                                   CommandLocEnd,
-                                  CommandName,
+                                  CommandID,
                                   getInlineCommandRenderKind(CommandName),
                                   Args);
 }
 
 InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
                                                SourceLocation CommandLocEnd,
-                                               StringRef CommandName,
+                                               unsigned CommandID,
                                                SourceLocation ArgLocBegin,
                                                SourceLocation ArgLocEnd,
                                                StringRef Arg) {
@@ -259,11 +260,12 @@
   Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin,
                                                      ArgLocEnd),
                                          Arg);
+  StringRef CommandName = Traits.getCommandInfo(CommandID)->Name;
 
   return new (Allocator) InlineCommandComment(
                                   CommandLocBegin,
                                   CommandLocEnd,
-                                  CommandName,
+                                  CommandID,
                                   getInlineCommandRenderKind(CommandName),
                                   llvm::makeArrayRef(A, 1));
 }
@@ -272,8 +274,9 @@
                                                 SourceLocation LocEnd,
                                                 StringRef Name) {
   ArrayRef<InlineCommandComment::Argument> Args;
+  unsigned CommandID = Traits.registerUnknownCommand(Name)->getID();
   return new (Allocator) InlineCommandComment(
-                                  LocBegin, LocEnd, Name,
+                                  LocBegin, LocEnd, CommandID,
                                   InlineCommandComment::RenderNormal,
                                   Args);
 }
@@ -285,11 +288,12 @@
 }
 
 VerbatimBlockComment *Sema::actOnVerbatimBlockStart(SourceLocation Loc,
-                                                    StringRef Name) {
+                                                    unsigned CommandID) {
+  StringRef CommandName = Traits.getCommandInfo(CommandID)->Name;
   return new (Allocator) VerbatimBlockComment(
                                   Loc,
-                                  Loc.getLocWithOffset(1 + Name.size()),
-                                  Name);
+                                  Loc.getLocWithOffset(1 + CommandName.size()),
+                                  CommandID);
 }
 
 VerbatimBlockLineComment *Sema::actOnVerbatimBlockLine(SourceLocation Loc,
@@ -307,13 +311,13 @@
 }
 
 VerbatimLineComment *Sema::actOnVerbatimLine(SourceLocation LocBegin,
-                                             StringRef Name,
+                                             unsigned CommandID,
                                              SourceLocation TextBegin,
                                              StringRef Text) {
   return new (Allocator) VerbatimLineComment(
                               LocBegin,
                               TextBegin.getLocWithOffset(Text.size()),
-                              Name,
+                              CommandID,
                               TextBegin,
                               Text);
 }
@@ -411,15 +415,15 @@
     if (Command->getNumArgs() > 0)
       DiagLoc = Command->getArgRange(Command->getNumArgs() - 1).getEnd();
     if (!DiagLoc.isValid())
-      DiagLoc = Command->getCommandNameRange().getEnd();
+      DiagLoc = Command->getCommandNameRange(Traits).getEnd();
     Diag(DiagLoc, diag::warn_doc_block_command_empty_paragraph)
-      << Command->getCommandName()
+      << Command->getCommandName(Traits)
       << Command->getSourceRange();
   }
 }
 
 void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
-  if (!Traits.isReturnsCommand(Command->getCommandName()))
+  if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand)
     return;
   if (isFunctionDecl()) {
     if (ThisDeclInfo->ResultType->isVoidType()) {
@@ -440,7 +444,7 @@
       }
       Diag(Command->getLocation(),
            diag::warn_doc_returns_attached_to_a_void_function)
-        << Command->getCommandName()
+        << Command->getCommandName(Traits)
         << DiagKind
         << Command->getSourceRange();
     }
@@ -448,20 +452,20 @@
   }
   Diag(Command->getLocation(),
        diag::warn_doc_returns_not_attached_to_a_function_decl)
-    << Command->getCommandName()
+    << Command->getCommandName(Traits)
     << Command->getSourceRange();
 }
 
 void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
-  StringRef Name = Command->getCommandName();
+  const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID());
   const BlockCommandComment *PrevCommand = NULL;
-  if (Traits.isBriefCommand(Name)) {
+  if (Info->IsBriefCommand) {
     if (!BriefCommand) {
       BriefCommand = Command;
       return;
     }
     PrevCommand = BriefCommand;
-  } else if (Traits.isReturnsCommand(Name)) {
+  } else if (Info->IsReturnsCommand) {
     if (!ReturnsCommand) {
       ReturnsCommand = Command;
       return;
@@ -471,18 +475,20 @@
     // We don't want to check this command for duplicates.
     return;
   }
+  StringRef CommandName = Command->getCommandName(Traits);
+  StringRef PrevCommandName = PrevCommand->getCommandName(Traits);
   Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate)
-      << Name
+      << CommandName
       << Command->getSourceRange();
-  if (Name == PrevCommand->getCommandName())
+  if (CommandName == PrevCommandName)
     Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous)
-        << PrevCommand->getCommandName()
-        << Command->getSourceRange();
+        << PrevCommandName
+        << PrevCommand->getSourceRange();
   else
     Diag(PrevCommand->getLocation(),
          diag::note_doc_block_command_previous_alias)
-        << PrevCommand->getCommandName()
-        << Name;
+        << PrevCommandName
+        << CommandName;
 }
 
 void Sema::resolveParamCommandIndexes(const FullComment *FC) {
@@ -740,7 +746,7 @@
 
 InlineCommandComment::RenderKind
 Sema::getInlineCommandRenderKind(StringRef Name) const {
-  assert(Traits.isInlineCommand(Name));
+  assert(Traits.getCommandInfo(Name)->IsInlineCommand);
 
   return llvm::StringSwitch<InlineCommandComment::RenderKind>(Name)
       .Case("b", InlineCommandComment::RenderBold)

Modified: cfe/trunk/lib/AST/RawCommentList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RawCommentList.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RawCommentList.cpp (original)
+++ cfe/trunk/lib/AST/RawCommentList.cpp Mon Sep 10 15:32:42 2012
@@ -143,10 +143,10 @@
   // a separate allocator for all temporary stuff.
   llvm::BumpPtrAllocator Allocator;
 
-  comments::CommandTraits Traits;
-  comments::Lexer L(Allocator, Traits, Range.getBegin(),
+  comments::Lexer L(Allocator, Context.getCommentCommandTraits(),
+                    Range.getBegin(),
                     RawText.begin(), RawText.end());
-  comments::BriefParser P(L, Traits);
+  comments::BriefParser P(L, Context.getCommentCommandTraits());
 
   const std::string Result = P.Parse();
   const unsigned BriefTextLength = Result.size();
@@ -163,15 +163,16 @@
   // Make sure that RawText is valid.
   getRawText(Context.getSourceManager());
 
-  comments::CommandTraits Traits;
-  comments::Lexer L(Context.getAllocator(), Traits,
+  comments::Lexer L(Context.getAllocator(), Context.getCommentCommandTraits(),
                     getSourceRange().getBegin(),
                     RawText.begin(), RawText.end());
   comments::Sema S(Context.getAllocator(), Context.getSourceManager(),
-                   Context.getDiagnostics(), Traits);
+                   Context.getDiagnostics(),
+                   Context.getCommentCommandTraits());
   S.setDecl(D);
   comments::Parser P(L, S, Context.getAllocator(), Context.getSourceManager(),
-                     Context.getDiagnostics(), Traits);
+                     Context.getDiagnostics(),
+                     Context.getCommentCommandTraits());
 
   return P.parseFullComment();
 }

Modified: cfe/trunk/test/Index/annotate-comments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-comments.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/test/Index/annotate-comments.cpp (original)
+++ cfe/trunk/test/Index/annotate-comments.cpp Mon Sep 10 15:32:42 2012
@@ -370,27 +370,30 @@
 /// Blah blah.
 void comment_to_html_conversion_25();
 
-/// \b Aaa
+/// \unknown
 void comment_to_html_conversion_26();
 
-/// \c Aaa \p Bbb
+/// \b Aaa
 void comment_to_html_conversion_27();
 
-/// \a Aaa \e Bbb \em Ccc
+/// \c Aaa \p Bbb
 void comment_to_html_conversion_28();
 
-/// \a 1<2 \e 3<4 \em 5<6 \param 7<8 aaa \tparam 9<10 bbb
+/// \a Aaa \e Bbb \em Ccc
 void comment_to_html_conversion_29();
 
-/// \\ \@ \& \$ \# \< \> \% \" \. \::
+/// \a 1<2 \e 3<4 \em 5<6 \param 7<8 aaa \tparam 9<10 bbb
 void comment_to_html_conversion_30();
 
-/// & < > "
+/// \\ \@ \& \$ \# \< \> \% \" \. \::
 void comment_to_html_conversion_31();
 
-/// <em>0<i</em>
+/// & < > "
 void comment_to_html_conversion_32();
 
+/// <em>0<i</em>
+void comment_to_html_conversion_33();
+
 /// Aaa.
 class comment_to_xml_conversion_01 {
   /// \param aaa Blah blah.
@@ -838,13 +841,19 @@
 // CHECK:       (CXComment_VerbatimLine Text=[ foo])
 // CHECK:       (CXComment_Paragraph
 // CHECK:         (CXComment_Text Text=[ Blah blah.])))]
-// CHECK: annotate-comments.cpp:374:6: FunctionDecl=comment_to_html_conversion_26:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <b>Aaa</b></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="374" column="6"><Name>comment_to_html_conversion_26</Name><USR>c:@F at comment_to_html_conversion_26#</USR><Abstract><Para> <bold>Aaa</bold></Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:374:6: FunctionDecl=comment_to_html_conversion_26:{{.*}} FullCommentAsHTML=[<p class="para-brief"> </p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="374" column="6"><Name>comment_to_html_conversion_26</Name><USR>c:@F at comment_to_html_conversion_26#</USR><Abstract><Para> </Para></Abstract></Function>]
+// CHECK:  CommentAST=[
+// CHECK:    (CXComment_FullComment
+// CHECK:       (CXComment_Paragraph
+// CHECK:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK:         (CXComment_InlineCommand CommandName=[unknown] RenderNormal)))]
+// CHECK: annotate-comments.cpp:377:6: FunctionDecl=comment_to_html_conversion_27:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <b>Aaa</b></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="377" column="6"><Name>comment_to_html_conversion_27</Name><USR>c:@F at comment_to_html_conversion_27#</USR><Abstract><Para> <bold>Aaa</bold></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[b] RenderBold Arg[0]=Aaa)))]
-// CHECK: annotate-comments.cpp:377:6: FunctionDecl=comment_to_html_conversion_27:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="377" column="6"><Name>comment_to_html_conversion_27</Name><USR>c:@F at comment_to_html_conversion_27#</USR><Abstract><Para> <monospaced>Aaa</monospaced> <monospaced>Bbb</monospaced></Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:380:6: FunctionDecl=comment_to_html_conversion_28:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="380" column="6"><Name>comment_to_html_conversion_28</Name><USR>c:@F at comment_to_html_conversion_28#</USR><Abstract><Para> <monospaced>Aaa</monospaced> <monospaced>Bbb</monospaced></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -852,7 +861,7 @@
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=Aaa)
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[p] RenderMonospaced Arg[0]=Bbb)))]
-// CHECK: annotate-comments.cpp:380:6: FunctionDecl=comment_to_html_conversion_28:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="380" column="6"><Name>comment_to_html_conversion_28</Name><USR>c:@F at comment_to_html_conversion_28#</USR><Abstract><Para> <emphasized>Aaa</emphasized> <emphasized>Bbb</emphasized> <emphasized>Ccc</emphasized></Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:383:6: FunctionDecl=comment_to_html_conversion_29:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="383" column="6"><Name>comment_to_html_conversion_29</Name><USR>c:@F at comment_to_html_conversion_29#</USR><Abstract><Para> <emphasized>Aaa</emphasized> <emphasized>Bbb</emphasized> <emphasized>Ccc</emphasized></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -862,7 +871,7 @@
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[e] RenderEmphasized Arg[0]=Bbb)
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[em] RenderEmphasized Arg[0]=Ccc)))]
-// CHECK: annotate-comments.cpp:383:6: FunctionDecl=comment_to_html_conversion_29:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>1<2</em> <em>3<4</em> <em>5<6</em> </p><dl><dt class="tparam-name-index-invalid">9<10</dt><dd class="tparam-descr-index-invalid"> bbb</dd></dl><dl><dt class="param-name-index-invalid">7<8</dt><dd class="param-descr-index-invalid"> aaa </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="383" column="6"><Name>comment_to_html_conversion_29</Name><USR>c:@F at comment_to_html_conversion_29#</USR><Abstract><Para> <emphasized>1<2</emphasized> <emphasized>3<4</emphasized> <emphasized>5<6</emphasized> </Para></Abstract><TemplateParameters><Parameter><Name>9<10</Name><Discussion><Para> bbb</Para></Discussion></Parameter></TemplateParameters><Parameters><Parameter><Name>7<8</Name><Direction isExplicit="0">in</Direction><Discussion><Para> aaa </Para></Discussion></Parameter></Parameters></Functio
 n>]
+// CHECK: annotate-comments.cpp:386:6: FunctionDecl=comment_to_html_conversion_30:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>1<2</em> <em>3<4</em> <em>5<6</em> </p><dl><dt class="tparam-name-index-invalid">9<10</dt><dd class="tparam-descr-index-invalid"> bbb</dd></dl><dl><dt class="param-name-index-invalid">7<8</dt><dd class="param-descr-index-invalid"> aaa </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="386" column="6"><Name>comment_to_html_conversion_30</Name><USR>c:@F at comment_to_html_conversion_30#</USR><Abstract><Para> <emphasized>1<2</emphasized> <emphasized>3<4</emphasized> <emphasized>5<6</emphasized> </Para></Abstract><TemplateParameters><Parameter><Name>9<10</Name><Discussion><Para> bbb</Para></Discussion></Parameter></TemplateParameters><Parameters><Parameter><Name>7<8</Name><Direction isExplicit="0">in</Direction><Discussion><Para> aaa </Para></Discussion></Parameter></Parameters></Functio
 n>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -879,7 +888,7 @@
 // CHECK-NEXT:       (CXComment_TParamCommand ParamName=[9<10] ParamPosition=Invalid
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ bbb]))))]
-// CHECK: annotate-comments.cpp:386:6: FunctionDecl=comment_to_html_conversion_30:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ & $ # < > % " . ::</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="386" column="6"><Name>comment_to_html_conversion_30</Name><USR>c:@F at comment_to_html_conversion_30#</USR><Abstract><Para> \ @ & $ # < > % " . ::</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:389:6: FunctionDecl=comment_to_html_conversion_31:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ & $ # < > % " . ::</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="389" column="6"><Name>comment_to_html_conversion_31</Name><USR>c:@F at comment_to_html_conversion_31#</USR><Abstract><Para> \ @ & $ # < > % " . ::</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -905,7 +914,7 @@
 // CHECK-NEXT:         (CXComment_Text Text=[.])
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_Text Text=[::])))]
-// CHECK: annotate-comments.cpp:389:6: FunctionDecl=comment_to_html_conversion_31:{{.*}} FullCommentAsHTML=[<p class="para-brief"> & < > "</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="389" column="6"><Name>comment_to_html_conversion_31</Name><USR>c:@F at comment_to_html_conversion_31#</USR><Abstract><Para> & < > "</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:392:6: FunctionDecl=comment_to_html_conversion_32:{{.*}} FullCommentAsHTML=[<p class="para-brief"> & < > "</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="392" column="6"><Name>comment_to_html_conversion_32</Name><USR>c:@F at comment_to_html_conversion_32#</USR><Abstract><Para> & < > "</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -917,7 +926,7 @@
 // CHECK-NEXT:         (CXComment_Text Text=[>])
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_Text Text=["])))]
-// CHECK: annotate-comments.cpp:392:6: FunctionDecl=comment_to_html_conversion_32:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>0<i</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="392" column="6"><Name>comment_to_html_conversion_32</Name><USR>c:@F at comment_to_html_conversion_32#</USR><Abstract><Para> <rawHTML><![CDATA[<em>]]></rawHTML>0<i<rawHTML></em></rawHTML></Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:395:6: FunctionDecl=comment_to_html_conversion_33:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>0<i</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="395" column="6"><Name>comment_to_html_conversion_33</Name><USR>c:@F at comment_to_html_conversion_33#</USR><Abstract><Para> <rawHTML><![CDATA[<em>]]></rawHTML>0<i<rawHTML></em></rawHTML></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -928,27 +937,27 @@
 // CHECK-NEXT:         (CXComment_Text Text=[i])
 // CHECK-NEXT:         (CXComment_HTMLEndTag Name=[em])))]
 
-// CHECK: annotate-comments.cpp:395:7: ClassDecl=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments.cpp" line="395" column="7"><Name>comment_to_xml_conversion_01</Name><USR>c:@C at comment_to_xml_conversion_01</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
-// CHECK: annotate-comments.cpp:397:3: CXXConstructor=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="397" column="3"><Name>comment_to_xml_conversion_01</Name><USR>c:@C at comment_to_xml_conversion_01@F at comment_to_xml_conversion_01#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
-// CHECK: annotate-comments.cpp:400:3: CXXDestructor=~comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="400" column="3"><Name>~comment_to_xml_conversion_01</Name><USR>c:@C at comment_to_xml_conversion_01@F@~comment_to_xml_conversion_01#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
-// CHECK: annotate-comments.cpp:403:7: CXXMethod=comment_to_xml_conversion_02:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="403" column="7"><Name>comment_to_xml_conversion_02</Name><USR>c:@C at comment_to_xml_conversion_01@F at comment_to_xml_conversion_02#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
-// CHECK: annotate-comments.cpp:406:14: CXXMethod=comment_to_xml_conversion_03:{{.*}} FullCommentAsXML=[<Function isClassMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="406" column="14"><Name>comment_to_xml_conversion_03</Name><USR>c:@C at comment_to_xml_conversion_01@F at comment_to_xml_conversion_03#I#S</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
-// CHECK: annotate-comments.cpp:409:7: FieldDecl=comment_to_xml_conversion_04:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="409" column="7"><Name>comment_to_xml_conversion_04</Name><USR>c:@C at comment_to_xml_conversion_01@FI at comment_to_xml_conversion_04</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
-// CHECK: annotate-comments.cpp:412:14: VarDecl=comment_to_xml_conversion_05:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="412" column="14"><Name>comment_to_xml_conversion_05</Name><USR>c:@C at comment_to_xml_conversion_01@comment_to_xml_conversion_05</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
-// CHECK: annotate-comments.cpp:415:8: CXXMethod=operator():{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="415" column="8"><Name>operator()</Name><USR>c:@C at comment_to_xml_conversion_01@F at operator()#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
-// CHECK: annotate-comments.cpp:418:3: CXXConversion=operator _Bool:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="418" column="3"><Name>operator _Bool</Name><USR>c:@C at comment_to_xml_conversion_01@F at operator _Bool#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
-// CHECK: annotate-comments.cpp:421:15: TypedefDecl=comment_to_xml_conversion_06:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="421" column="15"><Name>comment_to_xml_conversion_06</Name><USR>c:annotate-comments.cpp at 8453@C at comment_to_xml_conversion_01@T at comment_to_xml_conversion_06</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
-// CHECK: annotate-comments.cpp:424:9: TypeAliasDecl=comment_to_xml_conversion_07:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="424" column="9"><Name>comment_to_xml_conversion_07</Name><USR>c:@C at comment_to_xml_conversion_01@comment_to_xml_conversion_07</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
-// CHECK: annotate-comments.cpp:431:3: UnexposedDecl=comment_to_xml_conversion_09:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="431" column="3"><Name>comment_to_xml_conversion_09</Name><USR>c:@C at comment_to_xml_conversion_01@comment_to_xml_conversion_09</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
-// CHECK: annotate-comments.cpp:436:6: FunctionTemplate=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="436" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@FT@>2#T#Tcomment_to_xml_conversion_10#t0.0#t0.1#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
-// CHECK: annotate-comments.cpp:440:6: FunctionDecl=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="440" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@F at comment_to_xml_conversion_10<#I#I>#I#I#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
-// CHECK: annotate-comments.cpp:444:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="444" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CT>2#T#T at comment_to_xml_conversion_11</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
-// CHECK: annotate-comments.cpp:448:7: ClassTemplatePartialSpecialization=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="partialSpecialization" file="{{[^"]+}}annotate-comments.cpp" line="448" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CP>1#T at comment_to_xml_conversion_11>#t0.0#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
-// CHECK: annotate-comments.cpp:452:7: ClassDecl=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="452" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@C at comment_to_xml_conversion_11>#I#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
-// CHECK: annotate-comments.cpp:455:5: VarDecl=comment_to_xml_conversion_12:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="455" column="5"><Name>comment_to_xml_conversion_12</Name><USR>c:@comment_to_xml_conversion_12</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
-// CHECK: annotate-comments.cpp:458:11: Namespace=comment_to_xml_conversion_13:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="458" column="11"><Name>comment_to_xml_conversion_13</Name><USR>c:@N at comment_to_xml_conversion_13</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>]
-// CHECK: annotate-comments.cpp:460:13: Namespace=comment_to_xml_conversion_14:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="460" column="13"><Name>comment_to_xml_conversion_14</Name><USR>c:@N at comment_to_xml_conversion_13@N at comment_to_xml_conversion_14</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>]
-// CHECK: annotate-comments.cpp:465:6: EnumDecl=comment_to_xml_conversion_15:{{.*}} FullCommentAsXML=[<Enum file="{{[^"]+}}annotate-comments.cpp" line="465" column="6"><Name>comment_to_xml_conversion_15</Name><USR>c:@E at comment_to_xml_conversion_15</USR><Abstract><Para> Aaa.</Para></Abstract></Enum>]
-// CHECK: annotate-comments.cpp:467:3: EnumConstantDecl=comment_to_xml_conversion_16:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="467" column="3"><Name>comment_to_xml_conversion_16</Name><USR>c:@E at comment_to_xml_conversion_15@comment_to_xml_conversion_16</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
-// CHECK: annotate-comments.cpp:471:12: EnumDecl=comment_to_xml_conversion_17:{{.*}} FullCommentAsXML=[<Enum file="{{[^"]+}}annotate-comments.cpp" line="471" column="12"><Name>comment_to_xml_conversion_17</Name><USR>c:@E at comment_to_xml_conversion_17</USR><Abstract><Para> Aaa.</Para></Abstract></Enum>]
-// CHECK: annotate-comments.cpp:473:3: EnumConstantDecl=comment_to_xml_conversion_18:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="473" column="3"><Name>comment_to_xml_conversion_18</Name><USR>c:@E at comment_to_xml_conversion_17@comment_to_xml_conversion_18</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:398:7: ClassDecl=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments.cpp" line="398" column="7"><Name>comment_to_xml_conversion_01</Name><USR>c:@C at comment_to_xml_conversion_01</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:400:3: CXXConstructor=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="400" column="3"><Name>comment_to_xml_conversion_01</Name><USR>c:@C at comment_to_xml_conversion_01@F at comment_to_xml_conversion_01#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:403:3: CXXDestructor=~comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="403" column="3"><Name>~comment_to_xml_conversion_01</Name><USR>c:@C at comment_to_xml_conversion_01@F@~comment_to_xml_conversion_01#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:406:7: CXXMethod=comment_to_xml_conversion_02:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="406" column="7"><Name>comment_to_xml_conversion_02</Name><USR>c:@C at comment_to_xml_conversion_01@F at comment_to_xml_conversion_02#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:409:14: CXXMethod=comment_to_xml_conversion_03:{{.*}} FullCommentAsXML=[<Function isClassMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="409" column="14"><Name>comment_to_xml_conversion_03</Name><USR>c:@C at comment_to_xml_conversion_01@F at comment_to_xml_conversion_03#I#S</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:412:7: FieldDecl=comment_to_xml_conversion_04:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="412" column="7"><Name>comment_to_xml_conversion_04</Name><USR>c:@C at comment_to_xml_conversion_01@FI at comment_to_xml_conversion_04</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:415:14: VarDecl=comment_to_xml_conversion_05:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="415" column="14"><Name>comment_to_xml_conversion_05</Name><USR>c:@C at comment_to_xml_conversion_01@comment_to_xml_conversion_05</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:418:8: CXXMethod=operator():{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="418" column="8"><Name>operator()</Name><USR>c:@C at comment_to_xml_conversion_01@F at operator()#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:421:3: CXXConversion=operator _Bool:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="421" column="3"><Name>operator _Bool</Name><USR>c:@C at comment_to_xml_conversion_01@F at operator _Bool#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:424:15: TypedefDecl=comment_to_xml_conversion_06:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="424" column="15"><Name>comment_to_xml_conversion_06</Name><USR>c:annotate-comments.cpp at 8505@C at comment_to_xml_conversion_01@T at comment_to_xml_conversion_06</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
+// CHECK: annotate-comments.cpp:427:9: TypeAliasDecl=comment_to_xml_conversion_07:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="427" column="9"><Name>comment_to_xml_conversion_07</Name><USR>c:@C at comment_to_xml_conversion_01@comment_to_xml_conversion_07</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
+// CHECK: annotate-comments.cpp:434:3: UnexposedDecl=comment_to_xml_conversion_09:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="434" column="3"><Name>comment_to_xml_conversion_09</Name><USR>c:@C at comment_to_xml_conversion_01@comment_to_xml_conversion_09</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
+// CHECK: annotate-comments.cpp:439:6: FunctionTemplate=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="439" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@FT@>2#T#Tcomment_to_xml_conversion_10#t0.0#t0.1#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:443:6: FunctionDecl=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="443" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@F at comment_to_xml_conversion_10<#I#I>#I#I#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:447:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="447" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CT>2#T#T at comment_to_xml_conversion_11</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:451:7: ClassTemplatePartialSpecialization=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="partialSpecialization" file="{{[^"]+}}annotate-comments.cpp" line="451" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CP>1#T at comment_to_xml_conversion_11>#t0.0#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:455:7: ClassDecl=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="455" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@C at comment_to_xml_conversion_11>#I#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:458:5: VarDecl=comment_to_xml_conversion_12:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="458" column="5"><Name>comment_to_xml_conversion_12</Name><USR>c:@comment_to_xml_conversion_12</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:461:11: Namespace=comment_to_xml_conversion_13:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="461" column="11"><Name>comment_to_xml_conversion_13</Name><USR>c:@N at comment_to_xml_conversion_13</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>]
+// CHECK: annotate-comments.cpp:463:13: Namespace=comment_to_xml_conversion_14:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="463" column="13"><Name>comment_to_xml_conversion_14</Name><USR>c:@N at comment_to_xml_conversion_13@N at comment_to_xml_conversion_14</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>]
+// CHECK: annotate-comments.cpp:468:6: EnumDecl=comment_to_xml_conversion_15:{{.*}} FullCommentAsXML=[<Enum file="{{[^"]+}}annotate-comments.cpp" line="468" column="6"><Name>comment_to_xml_conversion_15</Name><USR>c:@E at comment_to_xml_conversion_15</USR><Abstract><Para> Aaa.</Para></Abstract></Enum>]
+// CHECK: annotate-comments.cpp:470:3: EnumConstantDecl=comment_to_xml_conversion_16:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="470" column="3"><Name>comment_to_xml_conversion_16</Name><USR>c:@E at comment_to_xml_conversion_15@comment_to_xml_conversion_16</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:474:12: EnumDecl=comment_to_xml_conversion_17:{{.*}} FullCommentAsXML=[<Enum file="{{[^"]+}}annotate-comments.cpp" line="474" column="12"><Name>comment_to_xml_conversion_17</Name><USR>c:@E at comment_to_xml_conversion_17</USR><Abstract><Para> Aaa.</Para></Abstract></Enum>]
+// CHECK: annotate-comments.cpp:476:3: EnumConstantDecl=comment_to_xml_conversion_18:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="476" column="3"><Name>comment_to_xml_conversion_18</Name><USR>c:@E at comment_to_xml_conversion_17@comment_to_xml_conversion_18</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Mon Sep 10 15:32:42 2012
@@ -512,8 +512,7 @@
 #endif
 }
 
-static void PrintCursorComments(CXTranslationUnit TU,
-                                CXCursor Cursor,
+static void PrintCursorComments(CXCursor Cursor,
                                 CommentXMLValidationData *ValidationData) {
   {
     CXString RawComment;
@@ -543,7 +542,7 @@
                                         clang_FullComment_getAsHTML(Comment));
       {
         CXString XML;
-        XML = clang_FullComment_getAsXML(TU, Comment);
+        XML = clang_FullComment_getAsXML(Comment);
         PrintCXStringWithPrefix("FullCommentAsXML", XML);
         ValidateCommentXML(clang_getCString(XML), ValidationData);
         clang_disposeString(XML);
@@ -781,7 +780,7 @@
         PrintRange(RefNameRange, "RefName");
     }
 
-    PrintCursorComments(TU, Cursor, ValidationData);
+    PrintCursorComments(Cursor, ValidationData);
   }
 }
 

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Sep 10 15:32:42 2012
@@ -5800,13 +5800,13 @@
 
 CXComment clang_Cursor_getParsedComment(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
-    return cxcomment::createCXComment(NULL);
+    return cxcomment::createCXComment(NULL, NULL);
 
   const Decl *D = getCursorDecl(C);
   const ASTContext &Context = getCursorContext(C);
   const comments::FullComment *FC = Context.getCommentForDecl(D);
 
-  return cxcomment::createCXComment(FC);
+  return cxcomment::createCXComment(FC, getCursorTU(C));
 }
 
 } // end: extern "C"

Modified: cfe/trunk/tools/libclang/CXComment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXComment.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXComment.cpp (original)
+++ cfe/trunk/tools/libclang/CXComment.cpp Mon Sep 10 15:32:42 2012
@@ -15,12 +15,10 @@
 #include "CXString.h"
 #include "CXComment.h"
 #include "CXCursor.h"
-#include "CXTranslationUnit.h"
 
 #include "clang/AST/CommentVisitor.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
-#include "clang/Frontend/ASTUnit.h"
 
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -94,9 +92,9 @@
 CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
   const Comment *C = getASTNode(CXC);
   if (!C || ChildIdx >= C->child_count())
-    return createCXComment(NULL);
+    return createCXComment(NULL, NULL);
 
-  return createCXComment(*(C->child_begin() + ChildIdx));
+  return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
 }
 
 unsigned clang_Comment_isWhitespace(CXComment CXC) {
@@ -134,7 +132,8 @@
   if (!ICC)
     return createCXString((const char *) 0);
 
-  return createCXString(ICC->getCommandName(), /*DupString=*/ false);
+  const CommandTraits &Traits = getCommandTraits(CXC);
+  return createCXString(ICC->getCommandName(Traits), /*DupString=*/ false);
 }
 
 enum CXCommentInlineCommandRenderKind
@@ -221,7 +220,8 @@
   if (!BCC)
     return createCXString((const char *) 0);
 
-  return createCXString(BCC->getCommandName(), /*DupString=*/ false);
+  const CommandTraits &Traits = getCommandTraits(CXC);
+  return createCXString(BCC->getCommandName(Traits), /*DupString=*/ false);
 }
 
 unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
@@ -244,9 +244,9 @@
 CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
   const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
   if (!BCC)
-    return createCXComment(NULL);
+    return createCXComment(NULL, NULL);
 
-  return createCXComment(BCC->getParagraph());
+  return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
 }
 
 CXString clang_ParamCommandComment_getParamName(CXComment CXC) {
@@ -405,7 +405,8 @@
 /// Separate parts of a FullComment.
 struct FullCommentParts {
   /// Take a full comment apart and initialize members accordingly.
-  FullCommentParts(const FullComment *C);
+  FullCommentParts(const FullComment *C,
+                   const CommandTraits &Traits);
 
   const BlockContentComment *Brief;
   const ParagraphComment *FirstParagraph;
@@ -415,9 +416,9 @@
   SmallVector<const BlockContentComment *, 8> MiscBlocks;
 };
 
-FullCommentParts::FullCommentParts(const FullComment *C) :
+FullCommentParts::FullCommentParts(const FullComment *C,
+                                   const CommandTraits &Traits) :
     Brief(NULL), FirstParagraph(NULL), Returns(NULL) {
-  const CommandTraits Traits;
   for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
        I != E; ++I) {
     const Comment *Child = *I;
@@ -440,12 +441,12 @@
 
     case Comment::BlockCommandCommentKind: {
       const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
-      StringRef CommandName = BCC->getCommandName();
-      if (!Brief && Traits.isBriefCommand(CommandName)) {
+      const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID());
+      if (!Brief && Info->IsBriefCommand) {
         Brief = BCC;
         break;
       }
-      if (!Returns && Traits.isReturnsCommand(CommandName)) {
+      if (!Returns && Info->IsReturnsCommand) {
         Returns = BCC;
         break;
       }
@@ -483,7 +484,8 @@
 
     case Comment::VerbatimLineCommentKind: {
       const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child);
-      if (!Traits.isDeclarationCommand(VLC->getCommandName()))
+      const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID());
+      if (!Info->IsDeclarationCommand)
         MiscBlocks.push_back(VLC);
       break;
     }
@@ -533,7 +535,10 @@
     public ConstCommentVisitor<CommentASTToHTMLConverter> {
 public:
   /// \param Str accumulator for HTML.
-  CommentASTToHTMLConverter(SmallVectorImpl<char> &Str) : Result(Str) { }
+  CommentASTToHTMLConverter(SmallVectorImpl<char> &Str,
+                            const CommandTraits &Traits) :
+      Result(Str), Traits(Traits)
+  { }
 
   // Inline content.
   void visitTextComment(const TextComment *C);
@@ -561,10 +566,10 @@
   void appendToResultWithHTMLEscaping(StringRef S);
 
 private:
-  const CommandTraits Traits;
-
   /// Output stream for HTML.
   llvm::raw_svector_ostream Result;
+
+  const CommandTraits &Traits;
 };
 } // end unnamed namespace
 
@@ -637,14 +642,14 @@
 
 void CommentASTToHTMLConverter::visitBlockCommandComment(
                                   const BlockCommandComment *C) {
-  StringRef CommandName = C->getCommandName();
-  if (Traits.isBriefCommand(CommandName)) {
+  const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID());
+  if (Info->IsBriefCommand) {
     Result << "<p class=\"para-brief\">";
     visitNonStandaloneParagraphComment(C->getParagraph());
     Result << "</p>";
     return;
   }
-  if (Traits.isReturnsCommand(CommandName)) {
+  if (Info->IsReturnsCommand) {
     Result << "<p class=\"para-returns\">"
               "<span class=\"word-returns\">Returns</span> ";
     visitNonStandaloneParagraphComment(C->getParagraph());
@@ -735,7 +740,7 @@
 }
 
 void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
-  FullCommentParts Parts(C);
+  FullCommentParts Parts(C, Traits);
 
   bool FirstParagraphIsBrief = false;
   if (Parts.Brief)
@@ -822,7 +827,7 @@
     return createCXString((const char *) 0);
 
   SmallString<128> HTML;
-  CommentASTToHTMLConverter Converter(HTML);
+  CommentASTToHTMLConverter Converter(HTML, getCommandTraits(CXC));
   Converter.visit(HTC);
   return createCXString(HTML.str(), /* DupString = */ true);
 }
@@ -833,7 +838,7 @@
     return createCXString((const char *) 0);
 
   SmallString<1024> HTML;
-  CommentASTToHTMLConverter Converter(HTML);
+  CommentASTToHTMLConverter Converter(HTML, getCommandTraits(CXC));
   Converter.visit(FC);
   return createCXString(HTML.str(), /* DupString = */ true);
 }
@@ -845,9 +850,10 @@
     public ConstCommentVisitor<CommentASTToXMLConverter> {
 public:
   /// \param Str accumulator for XML.
-  CommentASTToXMLConverter(const SourceManager &SM,
-                           SmallVectorImpl<char> &Str) :
-    SM(SM), Result(Str) { }
+  CommentASTToXMLConverter(SmallVectorImpl<char> &Str,
+                           const CommandTraits &Traits,
+                           const SourceManager &SM) :
+      Result(Str), Traits(Traits), SM(SM) { }
 
   // Inline content.
   void visitTextComment(const TextComment *C);
@@ -870,10 +876,11 @@
   void appendToResultWithXMLEscaping(StringRef S);
 
 private:
-  const SourceManager &SM;
-
   /// Output stream for XML.
   llvm::raw_svector_ostream Result;
+
+  const CommandTraits &Traits;
+  const SourceManager &SM;
 };
 } // end unnamed namespace
 
@@ -991,7 +998,7 @@
   if (NumLines == 0)
     return;
 
-  Result << llvm::StringSwitch<const char *>(C->getCommandName())
+  Result << llvm::StringSwitch<const char *>(C->getCommandName(Traits))
       .Case("code", "<Verbatim xml:space=\"preserve\" kind=\"code\">")
       .Default("<Verbatim xml:space=\"preserve\" kind=\"verbatim\">");
   for (unsigned i = 0; i != NumLines; ++i) {
@@ -1015,7 +1022,7 @@
 }
 
 void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
-  FullCommentParts Parts(C);
+  FullCommentParts Parts(C, Traits);
 
   const DeclInfo *DI = C->getDeclInfo();
   StringRef RootEndTag;
@@ -1213,15 +1220,16 @@
 
 extern "C" {
 
-CXString clang_FullComment_getAsXML(CXTranslationUnit TU, CXComment CXC) {
+CXString clang_FullComment_getAsXML(CXComment CXC) {
   const FullComment *FC = getASTNodeAs<FullComment>(CXC);
   if (!FC)
     return createCXString((const char *) 0);
 
+  CXTranslationUnit TU = CXC.TranslationUnit;
   SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
 
   SmallString<1024> XML;
-  CommentASTToXMLConverter Converter(SM, XML);
+  CommentASTToXMLConverter Converter(XML, getCommandTraits(CXC), SM);
   Converter.visit(FC);
   return createCXString(XML.str(), /* DupString = */ true);
 }

Modified: cfe/trunk/tools/libclang/CXComment.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXComment.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXComment.h (original)
+++ cfe/trunk/tools/libclang/CXComment.h Mon Sep 10 15:32:42 2012
@@ -15,20 +15,29 @@
 #define LLVM_CLANG_CXCOMMENT_H
 
 #include "clang-c/Index.h"
+#include "CXTranslationUnit.h"
 
 #include "clang/AST/Comment.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Frontend/ASTUnit.h"
 
 namespace clang {
+namespace comments {
+  class CommandTraits;
+}
+
 namespace cxcomment {
 
-inline CXComment createCXComment(const comments::Comment *C) {
+inline CXComment createCXComment(const comments::Comment *C,
+                                 CXTranslationUnit TU) {
   CXComment Result;
-  Result.Data = C;
+  Result.ASTNode = C;
+  Result.TranslationUnit = TU;
   return Result;
 }
 
 inline const comments::Comment *getASTNode(CXComment CXC) {
-  return static_cast<const comments::Comment *>(CXC.Data);
+  return static_cast<const comments::Comment *>(CXC.ASTNode);
 }
 
 template<typename T>
@@ -40,6 +49,14 @@
   return dyn_cast<T>(C);
 }
 
+inline ASTContext &getASTContext(CXComment CXC) {
+  return static_cast<ASTUnit *>(CXC.TranslationUnit->TUData)->getASTContext();
+}
+
+inline comments::CommandTraits &getCommandTraits(CXComment CXC) {
+  return getASTContext(CXC).getCommentCommandTraits();
+}
+
 } // end namespace cxcomment
 } // end namespace clang
 

Modified: cfe/trunk/unittests/AST/CommentLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CommentLexer.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/CommentLexer.cpp (original)
+++ cfe/trunk/unittests/AST/CommentLexer.cpp Mon Sep 10 15:32:42 2012
@@ -30,7 +30,8 @@
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
       Diags(DiagID, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr) {
+      SourceMgr(Diags, FileMgr),
+      Traits(Allocator) {
   }
 
   FileSystemOptions FileMgrOpts;
@@ -39,8 +40,21 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   llvm::BumpPtrAllocator Allocator;
+  CommandTraits Traits;
 
   void lexString(const char *Source, std::vector<Token> &Toks);
+
+  StringRef getCommandName(const Token &Tok) {
+    return Traits.getCommandInfo(Tok.getCommandID())->Name;
+  }
+
+  StringRef getVerbatimBlockName(const Token &Tok) {
+    return Traits.getCommandInfo(Tok.getVerbatimBlockID())->Name;
+  }
+
+  StringRef getVerbatimLineName(const Token &Tok) {
+    return Traits.getCommandInfo(Tok.getVerbatimLineID())->Name;
+  }
 };
 
 void CommentLexerTest::lexString(const char *Source,
@@ -49,9 +63,7 @@
   FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
-  comments::CommandTraits Traits;
-  comments::Lexer L(Allocator, Traits, Begin,
-                    Source, Source + strlen(Source));
+  Lexer L(Allocator, Traits, Begin, Source, Source + strlen(Source));
 
   while (1) {
     Token Tok;
@@ -322,7 +334,7 @@
   ASSERT_EQ(StringRef(" "),     Toks[0].getText());
 
   ASSERT_EQ(tok::command,       Toks[1].getKind());
-  ASSERT_EQ(StringRef("brief"), Toks[1].getCommandName());
+  ASSERT_EQ(StringRef("brief"), getCommandName(Toks[1]));
 
   ASSERT_EQ(tok::text,          Toks[2].getKind());
   ASSERT_EQ(StringRef(" Aaa."), Toks[2].getText());
@@ -331,6 +343,38 @@
 }
 
 TEST_F(CommentLexerTest, DoxygenCommand6) {
+  const char *Source = "/// \\em\\em \\em\t\\em\n";
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(8U, Toks.size());
+
+  ASSERT_EQ(tok::text,       Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),  Toks[0].getText());
+
+  ASSERT_EQ(tok::command,    Toks[1].getKind());
+  ASSERT_EQ(StringRef("em"), getCommandName(Toks[1]));
+
+  ASSERT_EQ(tok::command,    Toks[2].getKind());
+  ASSERT_EQ(StringRef("em"), getCommandName(Toks[2]));
+
+  ASSERT_EQ(tok::text,       Toks[3].getKind());
+  ASSERT_EQ(StringRef(" "),  Toks[3].getText());
+
+  ASSERT_EQ(tok::command,    Toks[4].getKind());
+  ASSERT_EQ(StringRef("em"), getCommandName(Toks[4]));
+
+  ASSERT_EQ(tok::text,       Toks[5].getKind());
+  ASSERT_EQ(StringRef("\t"), Toks[5].getText());
+
+  ASSERT_EQ(tok::command,    Toks[6].getKind());
+  ASSERT_EQ(StringRef("em"), getCommandName(Toks[6]));
+
+  ASSERT_EQ(tok::newline,    Toks[7].getKind());
+}
+
+TEST_F(CommentLexerTest, DoxygenCommand7) {
   const char *Source = "/// \\aaa\\bbb \\ccc\t\\ddd\n";
   std::vector<Token> Toks;
 
@@ -341,28 +385,28 @@
   ASSERT_EQ(tok::text,        Toks[0].getKind());
   ASSERT_EQ(StringRef(" "),   Toks[0].getText());
 
-  ASSERT_EQ(tok::command,     Toks[1].getKind());
-  ASSERT_EQ(StringRef("aaa"), Toks[1].getCommandName());
+  ASSERT_EQ(tok::unknown_command, Toks[1].getKind());
+  ASSERT_EQ(StringRef("aaa"), Toks[1].getUnknownCommandName());
 
-  ASSERT_EQ(tok::command,     Toks[2].getKind());
-  ASSERT_EQ(StringRef("bbb"), Toks[2].getCommandName());
+  ASSERT_EQ(tok::unknown_command, Toks[2].getKind());
+  ASSERT_EQ(StringRef("bbb"), Toks[2].getUnknownCommandName());
 
   ASSERT_EQ(tok::text,        Toks[3].getKind());
   ASSERT_EQ(StringRef(" "),   Toks[3].getText());
 
-  ASSERT_EQ(tok::command,     Toks[4].getKind());
-  ASSERT_EQ(StringRef("ccc"), Toks[4].getCommandName());
+  ASSERT_EQ(tok::unknown_command, Toks[4].getKind());
+  ASSERT_EQ(StringRef("ccc"), Toks[4].getUnknownCommandName());
 
   ASSERT_EQ(tok::text,        Toks[5].getKind());
   ASSERT_EQ(StringRef("\t"),  Toks[5].getText());
 
-  ASSERT_EQ(tok::command,     Toks[6].getKind());
-  ASSERT_EQ(StringRef("ddd"), Toks[6].getCommandName());
+  ASSERT_EQ(tok::unknown_command, Toks[6].getKind());
+  ASSERT_EQ(StringRef("ddd"), Toks[6].getUnknownCommandName());
 
   ASSERT_EQ(tok::newline,     Toks[7].getKind());
 }
 
-TEST_F(CommentLexerTest, DoxygenCommand7) {
+TEST_F(CommentLexerTest, DoxygenCommand8) {
   const char *Source = "// \\c\n";
   std::vector<Token> Toks;
 
@@ -374,7 +418,7 @@
   ASSERT_EQ(StringRef(" "), Toks[0].getText());
 
   ASSERT_EQ(tok::command,   Toks[1].getKind());
-  ASSERT_EQ(StringRef("c"), Toks[1].getCommandName());
+  ASSERT_EQ(StringRef("c"), getCommandName(Toks[1]));
 
   ASSERT_EQ(tok::newline,   Toks[2].getKind());
 }
@@ -397,10 +441,10 @@
     ASSERT_EQ(StringRef(" "),            Toks[0].getText());
 
     ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-    ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+    ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
     ASSERT_EQ(tok::verbatim_block_end,   Toks[2].getKind());
-    ASSERT_EQ(StringRef("endverbatim"),  Toks[2].getVerbatimBlockName());
+    ASSERT_EQ(StringRef("endverbatim"),  getVerbatimBlockName(Toks[2]));
 
     ASSERT_EQ(tok::newline,              Toks[3].getKind());
     ASSERT_EQ(tok::newline,              Toks[4].getKind());
@@ -421,7 +465,7 @@
   ASSERT_EQ(StringRef(" "),            Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-  ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
   ASSERT_EQ(tok::newline,              Toks[2].getKind());
 }
@@ -440,7 +484,7 @@
   ASSERT_EQ(StringRef(" "),            Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-  ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
   ASSERT_EQ(tok::newline,              Toks[2].getKind());
   ASSERT_EQ(tok::newline,              Toks[3].getKind());
@@ -464,13 +508,13 @@
     ASSERT_EQ(StringRef(" Meow "),       Toks[0].getText());
 
     ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-    ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+    ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
     ASSERT_EQ(tok::verbatim_block_line,  Toks[2].getKind());
     ASSERT_EQ(StringRef(" aaa "),        Toks[2].getVerbatimBlockText());
 
     ASSERT_EQ(tok::verbatim_block_end,   Toks[3].getKind());
-    ASSERT_EQ(StringRef("endverbatim"),  Toks[3].getVerbatimBlockName());
+    ASSERT_EQ(StringRef("endverbatim"),  getVerbatimBlockName(Toks[3]));
 
     ASSERT_EQ(tok::newline,              Toks[4].getKind());
     ASSERT_EQ(tok::newline,              Toks[5].getKind());
@@ -495,7 +539,7 @@
     ASSERT_EQ(StringRef(" Meow "),       Toks[0].getText());
 
     ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-    ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+    ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
     ASSERT_EQ(tok::verbatim_block_line,  Toks[2].getKind());
     ASSERT_EQ(StringRef(" aaa "),        Toks[2].getVerbatimBlockText());
@@ -523,7 +567,7 @@
   ASSERT_EQ(StringRef(" "),            Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-  ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
   ASSERT_EQ(tok::newline,              Toks[2].getKind());
 
@@ -540,7 +584,7 @@
   ASSERT_EQ(tok::newline,              Toks[7].getKind());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[8].getKind());
-  ASSERT_EQ(StringRef("endverbatim"),  Toks[8].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("endverbatim"),  getVerbatimBlockName(Toks[8]));
 
   ASSERT_EQ(tok::newline,              Toks[9].getKind());
 }
@@ -564,7 +608,7 @@
   ASSERT_EQ(StringRef(" "),            Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-  ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
   ASSERT_EQ(tok::verbatim_block_line,  Toks[2].getKind());
   ASSERT_EQ(StringRef(" Aaa"),         Toks[2].getVerbatimBlockText());
@@ -576,7 +620,7 @@
   ASSERT_EQ(StringRef(" Bbb"),         Toks[4].getVerbatimBlockText());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[5].getKind());
-  ASSERT_EQ(StringRef("endverbatim"),  Toks[5].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("endverbatim"),  getVerbatimBlockName(Toks[5]));
 
   ASSERT_EQ(tok::newline,              Toks[6].getKind());
 
@@ -605,7 +649,7 @@
   ASSERT_EQ(StringRef(" Meow "),       Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-  ASSERT_EQ(StringRef("verbatim"),     Toks[1].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[1]));
 
   ASSERT_EQ(tok::verbatim_block_line,  Toks[2].getKind());
   ASSERT_EQ(StringRef(" aaa\\$\\@"),   Toks[2].getVerbatimBlockText());
@@ -620,19 +664,19 @@
   ASSERT_EQ(StringRef("ddd "),         Toks[5].getVerbatimBlockText());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[6].getKind());
-  ASSERT_EQ(StringRef("endverbatim"),  Toks[6].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("endverbatim"),  getVerbatimBlockName(Toks[6]));
 
   ASSERT_EQ(tok::text,                 Toks[7].getKind());
   ASSERT_EQ(StringRef(" Blah "),       Toks[7].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[8].getKind());
-  ASSERT_EQ(StringRef("verbatim"),     Toks[8].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("verbatim"),     getVerbatimBlockName(Toks[8]));
 
   ASSERT_EQ(tok::verbatim_block_line,  Toks[9].getKind());
   ASSERT_EQ(StringRef(" eee"),         Toks[9].getVerbatimBlockText());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[10].getKind());
-  ASSERT_EQ(StringRef("endverbatim"),  Toks[10].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("endverbatim"),  getVerbatimBlockName(Toks[10]));
 
   ASSERT_EQ(tok::text,                 Toks[11].getKind());
   ASSERT_EQ(StringRef(" BlahBlah"),    Toks[11].getText());
@@ -655,37 +699,37 @@
   ASSERT_EQ(StringRef(" "),            Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[1].getKind());
-  ASSERT_EQ(StringRef("f$"),           Toks[1].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("f$"),           getVerbatimBlockName(Toks[1]));
 
   ASSERT_EQ(tok::verbatim_block_line,  Toks[2].getKind());
   ASSERT_EQ(StringRef(" Aaa "),        Toks[2].getVerbatimBlockText());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[3].getKind());
-  ASSERT_EQ(StringRef("f$"),           Toks[3].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("f$"),           getVerbatimBlockName(Toks[3]));
 
   ASSERT_EQ(tok::text,                 Toks[4].getKind());
   ASSERT_EQ(StringRef(" "),            Toks[4].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[5].getKind());
-  ASSERT_EQ(StringRef("f["),           Toks[5].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("f["),           getVerbatimBlockName(Toks[5]));
 
   ASSERT_EQ(tok::verbatim_block_line,  Toks[6].getKind());
   ASSERT_EQ(StringRef(" Bbb "),        Toks[6].getVerbatimBlockText());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[7].getKind());
-  ASSERT_EQ(StringRef("f]"),           Toks[7].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("f]"),           getVerbatimBlockName(Toks[7]));
 
   ASSERT_EQ(tok::text,                 Toks[8].getKind());
   ASSERT_EQ(StringRef(" "),            Toks[8].getText());
 
   ASSERT_EQ(tok::verbatim_block_begin, Toks[9].getKind());
-  ASSERT_EQ(StringRef("f{"),           Toks[9].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("f{"),           getVerbatimBlockName(Toks[9]));
 
   ASSERT_EQ(tok::verbatim_block_line,  Toks[10].getKind());
   ASSERT_EQ(StringRef(" Ccc "),        Toks[10].getVerbatimBlockText());
 
   ASSERT_EQ(tok::verbatim_block_end,   Toks[11].getKind());
-  ASSERT_EQ(StringRef("f}"),           Toks[11].getVerbatimBlockName());
+  ASSERT_EQ(StringRef("f}"),           getVerbatimBlockName(Toks[11]));
 
   ASSERT_EQ(tok::newline,              Toks[12].getKind());
 }
@@ -708,7 +752,7 @@
     ASSERT_EQ(StringRef(" "),          Toks[0].getText());
 
     ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
-    ASSERT_EQ(StringRef("fn"),         Toks[1].getVerbatimLineName());
+    ASSERT_EQ(StringRef("fn"),         getVerbatimLineName(Toks[1]));
 
     ASSERT_EQ(tok::newline,            Toks[2].getKind());
     ASSERT_EQ(tok::newline,            Toks[3].getKind());
@@ -733,7 +777,7 @@
     ASSERT_EQ(StringRef(" "),          Toks[0].getText());
 
     ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
-    ASSERT_EQ(StringRef("fn"),         Toks[1].getVerbatimLineName());
+    ASSERT_EQ(StringRef("fn"),         getVerbatimLineName(Toks[1]));
 
     ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
     ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),
@@ -761,7 +805,7 @@
   ASSERT_EQ(StringRef(" "),          Toks[0].getText());
 
   ASSERT_EQ(tok::verbatim_line_name, Toks[1].getKind());
-  ASSERT_EQ(StringRef("fn"),         Toks[1].getVerbatimLineName());
+  ASSERT_EQ(StringRef("fn"),         getVerbatimLineName(Toks[1]));
 
   ASSERT_EQ(tok::verbatim_line_text, Toks[2].getKind());
   ASSERT_EQ(StringRef(" void *foo(const char *zzz = \"\\$\");"),

Modified: cfe/trunk/unittests/AST/CommentParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CommentParser.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/CommentParser.cpp (original)
+++ cfe/trunk/unittests/AST/CommentParser.cpp Mon Sep 10 15:32:42 2012
@@ -37,7 +37,8 @@
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
       Diags(DiagID, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr) {
+      SourceMgr(Diags, FileMgr),
+      Traits(Allocator) {
   }
 
   FileSystemOptions FileMgrOpts;
@@ -46,6 +47,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   llvm::BumpPtrAllocator Allocator;
+  CommandTraits Traits;
 
   FullComment *parseString(const char *Source);
 };
@@ -55,17 +57,15 @@
   FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
-  comments::CommandTraits Traits;
-  comments::Lexer L(Allocator, Traits, Begin,
-                    Source, Source + strlen(Source));
-
-  comments::Sema S(Allocator, SourceMgr, Diags, Traits);
-  comments::Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
-  comments::FullComment *FC = P.parseFullComment();
+  Lexer L(Allocator, Traits, Begin, Source, Source + strlen(Source));
+
+  Sema S(Allocator, SourceMgr, Diags, Traits);
+  Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
+  FullComment *FC = P.parseFullComment();
 
   if (DEBUG) {
     llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n";
-    FC->dump(SourceMgr);
+    FC->dump(llvm::errs(), &Traits, &SourceMgr);
   }
 
   Token Tok;
@@ -157,6 +157,7 @@
 }
 
 ::testing::AssertionResult HasBlockCommandAt(const Comment *C,
+                                             const CommandTraits &Traits,
                                              size_t Idx,
                                              BlockCommandComment *&BCC,
                                              StringRef Name,
@@ -165,7 +166,7 @@
   if (!AR)
     return AR;
 
-  StringRef ActualName = BCC->getCommandName();
+  StringRef ActualName = BCC->getCommandName(Traits);
   if (ActualName != Name)
     return ::testing::AssertionFailure()
         << "BlockCommandComment has name \"" << ActualName.str() << "\", "
@@ -178,6 +179,7 @@
 
 ::testing::AssertionResult HasParamCommandAt(
                               const Comment *C,
+                              const CommandTraits &Traits,
                               size_t Idx,
                               ParamCommandComment *&PCC,
                               StringRef CommandName,
@@ -189,7 +191,7 @@
   if (!AR)
     return AR;
 
-  StringRef ActualCommandName = PCC->getCommandName();
+  StringRef ActualCommandName = PCC->getCommandName(Traits);
   if (ActualCommandName != CommandName)
     return ::testing::AssertionFailure()
         << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", "
@@ -225,6 +227,7 @@
 
 ::testing::AssertionResult HasTParamCommandAt(
                               const Comment *C,
+                              const CommandTraits &Traits,
                               size_t Idx,
                               TParamCommandComment *&TPCC,
                               StringRef CommandName,
@@ -234,7 +237,7 @@
   if (!AR)
     return AR;
 
-  StringRef ActualCommandName = TPCC->getCommandName();
+  StringRef ActualCommandName = TPCC->getCommandName(Traits);
   if (ActualCommandName != CommandName)
     return ::testing::AssertionFailure()
         << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", "
@@ -257,6 +260,7 @@
 }
 
 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               InlineCommandComment *&ICC,
                                               StringRef Name) {
@@ -264,7 +268,7 @@
   if (!AR)
     return AR;
 
-  StringRef ActualName = ICC->getCommandName();
+  StringRef ActualName = ICC->getCommandName(Traits);
   if (ActualName != Name)
     return ::testing::AssertionFailure()
         << "InlineCommandComment has name \"" << ActualName.str() << "\", "
@@ -276,11 +280,12 @@
 struct NoArgs {};
 
 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               InlineCommandComment *&ICC,
                                               StringRef Name,
                                               NoArgs) {
-  ::testing::AssertionResult AR = HasInlineCommandAt(C, Idx, ICC, Name);
+  ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
   if (!AR)
     return AR;
 
@@ -293,11 +298,12 @@
 }
 
 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               InlineCommandComment *&ICC,
                                               StringRef Name,
                                               StringRef Arg) {
-  ::testing::AssertionResult AR = HasInlineCommandAt(C, Idx, ICC, Name);
+  ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
   if (!AR)
     return AR;
 
@@ -452,6 +458,7 @@
 }
 
 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               VerbatimBlockComment *&VBC,
                                               StringRef Name,
@@ -460,7 +467,7 @@
   if (!AR)
     return AR;
 
-  StringRef ActualName = VBC->getCommandName();
+  StringRef ActualName = VBC->getCommandName(Traits);
   if (ActualName != Name)
     return ::testing::AssertionFailure()
         << "VerbatimBlockComment has name \"" << ActualName.str() << "\", "
@@ -480,12 +487,13 @@
 struct Lines {};
 
 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               VerbatimBlockComment *&VBC,
                                               StringRef Name,
                                               StringRef CloseName,
                                               NoLines) {
-  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
+  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
                                                      CloseName);
   if (!AR)
     return AR;
@@ -499,13 +507,14 @@
 }
 
 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               VerbatimBlockComment *&VBC,
                                               StringRef Name,
                                               StringRef CloseName,
                                               Lines,
                                               StringRef Line0) {
-  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
+  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
                                                      CloseName);
   if (!AR)
     return AR;
@@ -525,6 +534,7 @@
 }
 
 ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
+                                              const CommandTraits &Traits,
                                               size_t Idx,
                                               VerbatimBlockComment *&VBC,
                                               StringRef Name,
@@ -532,7 +542,7 @@
                                               Lines,
                                               StringRef Line0,
                                               StringRef Line1) {
-  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
+  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
                                                      CloseName);
   if (!AR)
     return AR;
@@ -558,6 +568,7 @@
 }
 
 ::testing::AssertionResult HasVerbatimLineAt(const Comment *C,
+                                             const CommandTraits &Traits,
                                              size_t Idx,
                                              VerbatimLineComment *&VLC,
                                              StringRef Name,
@@ -566,7 +577,7 @@
   if (!AR)
     return AR;
 
-  StringRef ActualName = VLC->getCommandName();
+  StringRef ActualName = VLC->getCommandName(Traits);
   if (ActualName != Name)
     return ::testing::AssertionFailure()
         << "VerbatimLineComment has name \"" << ActualName.str() << "\", "
@@ -651,7 +662,7 @@
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
 
     ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa"));
   }
@@ -668,14 +679,14 @@
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
 
     ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " "));
   }
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "author", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
 
     ASSERT_TRUE(GetChildAt(BCC, 0, PC));
       ASSERT_TRUE(HasChildCount(PC, 0));
@@ -695,7 +706,7 @@
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
 
     ASSERT_TRUE(GetChildAt(BCC, 0, PC));
       ASSERT_TRUE(HasChildCount(PC, 2));
@@ -705,7 +716,7 @@
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "author", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
 
     ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc"));
   }
@@ -721,7 +732,7 @@
   {
     ParamCommandComment *PCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+    ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                   ParamCommandComment::In,
                                   /* IsDirectionExplicit = */ false,
                                   "aaa", PC));
@@ -740,7 +751,7 @@
   {
     ParamCommandComment *PCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+    ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                   ParamCommandComment::In,
                                   /* IsDirectionExplicit = */ false,
                                   "", PC));
@@ -750,7 +761,7 @@
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "brief", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
     ASSERT_TRUE(HasChildCount(PC, 0));
   }
 }
@@ -774,7 +785,7 @@
     {
       ParamCommandComment *PCC;
       ParagraphComment *PC;
-      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+      ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                     ParamCommandComment::In,
                                     /* IsDirectionExplicit = */ false,
                                     "aaa", PC));
@@ -804,7 +815,7 @@
     {
       ParamCommandComment *PCC;
       ParagraphComment *PC;
-      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+      ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                     ParamCommandComment::In,
                                     /* IsDirectionExplicit = */ true,
                                     "aaa", PC));
@@ -834,7 +845,7 @@
     {
       ParamCommandComment *PCC;
       ParagraphComment *PC;
-      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+      ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                     ParamCommandComment::Out,
                                     /* IsDirectionExplicit = */ true,
                                     "aaa", PC));
@@ -865,7 +876,7 @@
     {
       ParamCommandComment *PCC;
       ParagraphComment *PC;
-      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+      ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                     ParamCommandComment::InOut,
                                     /* IsDirectionExplicit = */ true,
                                     "aaa", PC));
@@ -886,7 +897,7 @@
   {
     ParamCommandComment *PCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+    ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
                                   ParamCommandComment::In,
                                   /* IsDirectionExplicit = */ false,
                                   "aaa", PC));
@@ -920,7 +931,7 @@
     {
       TParamCommandComment *TPCC;
       ParagraphComment *PC;
-      ASSERT_TRUE(HasTParamCommandAt(FC, 1, TPCC, "tparam",
+      ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam",
                                      "aaa", PC));
       ASSERT_TRUE(HasChildCount(TPCC, 1));
       ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
@@ -938,14 +949,14 @@
   {
     TParamCommandComment *TPCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasTParamCommandAt(FC, 1, TPCC, "tparam", "", PC));
+    ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC));
     ASSERT_TRUE(HasChildCount(TPCC, 1));
     ASSERT_TRUE(HasChildCount(PC, 0));
   }
   {
     BlockCommandComment *BCC;
     ParagraphComment *PC;
-    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "brief", PC));
+    ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
     ASSERT_TRUE(HasChildCount(PC, 0));
   }
 }
@@ -964,7 +975,7 @@
 
     ASSERT_TRUE(HasChildCount(PC, 2));
       ASSERT_TRUE(HasTextAt(PC, 0, " "));
-      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
+      ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
   }
 }
 
@@ -981,7 +992,7 @@
 
     ASSERT_TRUE(HasChildCount(PC, 3));
       ASSERT_TRUE(HasTextAt(PC, 0, " "));
-      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
+      ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
       ASSERT_TRUE(HasTextAt(PC, 2, " "));
   }
 }
@@ -999,7 +1010,7 @@
 
     ASSERT_TRUE(HasChildCount(PC, 2));
       ASSERT_TRUE(HasTextAt(PC, 0, " "));
-      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
+      ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
   }
 }
 
@@ -1016,7 +1027,7 @@
 
     ASSERT_TRUE(HasChildCount(PC, 3));
       ASSERT_TRUE(HasTextAt(PC, 0, " "));
-      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
+      ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
       ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
   }
 }
@@ -1034,7 +1045,7 @@
 
     ASSERT_TRUE(HasChildCount(PC, 3));
       ASSERT_TRUE(HasTextAt(PC, 0, " "));
-      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "unknown", NoArgs()));
+      ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs()));
       ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
   }
 }
@@ -1188,7 +1199,8 @@
   ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
   {
     VerbatimBlockComment *VCC;
-    ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VCC, "verbatim", "endverbatim",
+    ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC,
+                                   "verbatim", "endverbatim",
                                    NoLines()));
   }
 }
@@ -1202,7 +1214,8 @@
   ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
   {
     VerbatimBlockComment *VBC;
-    ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
+    ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
+                                   "verbatim", "endverbatim",
                                    Lines(), " Aaa "));
   }
 }
@@ -1216,7 +1229,7 @@
   ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
   {
     VerbatimBlockComment *VBC;
-    ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "",
+    ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "",
                                    Lines(), " Aaa"));
   }
 }
@@ -1231,7 +1244,8 @@
 
   {
     VerbatimBlockComment *VBC;
-    ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
+    ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
+                                   "verbatim", "endverbatim",
                                    NoLines()));
   }
 }
@@ -1253,7 +1267,8 @@
 
     {
       VerbatimBlockComment *VBC;
-      ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
+      ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
+                                     "verbatim", "endverbatim",
                                      Lines(), " Aaa"));
     }
   }
@@ -1277,7 +1292,8 @@
     ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
     {
       VerbatimBlockComment *VBC;
-      ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
+      ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
+                                     "verbatim", "endverbatim",
                                      Lines(), " Aaa"));
     }
   }
@@ -1303,7 +1319,8 @@
     ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
     {
       VerbatimBlockComment *VBC;
-      ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
+      ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
+                                     "verbatim", "endverbatim",
                                      Lines(), " Aaa", " Bbb"));
     }
   }
@@ -1330,7 +1347,8 @@
     ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
     {
       VerbatimBlockComment *VBC;
-      ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim"));
+      ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
+                                     "verbatim", "endverbatim"));
       ASSERT_EQ(3U, VBC->getNumLines());
       ASSERT_EQ(" Aaa", VBC->getText(0));
       ASSERT_EQ("",     VBC->getText(1));
@@ -1352,7 +1370,7 @@
     ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
     {
       VerbatimLineComment *VLC;
-      ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn", ""));
+      ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", ""));
     }
   }
 }
@@ -1370,7 +1388,7 @@
     ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
     {
       VerbatimLineComment *VLC;
-      ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn",
+      ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn",
                   " void *foo(const char *zzz = \"\\$\");"));
     }
   }

Modified: cfe/trunk/utils/TableGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/CMakeLists.txt?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/CMakeLists.txt (original)
+++ cfe/trunk/utils/TableGen/CMakeLists.txt Mon Sep 10 15:32:42 2012
@@ -5,6 +5,7 @@
 add_tablegen(clang-tblgen CLANG
   ClangASTNodesEmitter.cpp
   ClangAttrEmitter.cpp
+  ClangCommentCommandInfoEmitter.cpp
   ClangCommentHTMLTagsEmitter.cpp
   ClangDiagnosticsEmitter.cpp
   ClangSACheckersEmitter.cpp

Added: cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp?rev=163540&view=auto
==============================================================================
--- cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp (added)
+++ cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp Mon Sep 10 15:32:42 2012
@@ -0,0 +1,70 @@
+//===--- ClangCommentCommandInfoEmitter.cpp - Generate command lists -----====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits command lists and efficient matchers command
+// names that are used in documentation comments.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/StringMatcher.h"
+#include <vector>
+
+using namespace llvm;
+
+namespace clang {
+void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) {
+  OS << "// This file is generated by TableGen.  Do not edit.\n\n";
+
+  OS << "namespace {\n"
+        "const CommandInfo Commands[] = {\n";
+  std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command");
+  for (size_t i = 0, e = Tags.size(); i != e; ++i) {
+    Record &Tag = *Tags[i];
+    OS << "  { "
+       << "\"" << Tag.getValueAsString("Name") << "\", "
+       << "\"" << Tag.getValueAsString("EndCommandName") << "\", "
+       << i << ", "
+       << Tag.getValueAsInt("NumArgs") << ", "
+       << Tag.getValueAsBit("IsInlineCommand") << ", "
+       << Tag.getValueAsBit("IsBlockCommand") << ", "
+       << Tag.getValueAsBit("IsBriefCommand") << ", "
+       << Tag.getValueAsBit("IsReturnsCommand") << ", "
+       << Tag.getValueAsBit("IsParamCommand") << ", "
+       << Tag.getValueAsBit("IsTParamCommand") << ", "
+       << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", "
+       << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", "
+       << Tag.getValueAsBit("IsVerbatimLineCommand") << ", "
+       << Tag.getValueAsBit("IsDeclarationCommand") << ", "
+       << /* IsUnknownCommand = */ "0"
+       << " }";
+    if (i + 1 != e)
+      OS << ",";
+    OS << "\n";
+  }
+  OS << "};\n"
+        "} // unnamed namespace\n\n";
+
+  std::vector<StringMatcher::StringPair> Matches;
+  for (size_t i = 0, e = Tags.size(); i != e; ++i) {
+    Record &Tag = *Tags[i];
+    std::string Name = Tag.getValueAsString("Name");
+    std::string Return;
+    raw_string_ostream(Return) << "return &Commands[" << i << "];";
+    Matches.push_back(StringMatcher::StringPair(Name, Return));
+  }
+
+  OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n"
+     << "                                         StringRef Name) {\n";
+  StringMatcher("Name", Matches, OS).Emit();
+  OS << "  return NULL;\n"
+     << "}\n\n";
+}
+} // end namespace clang
+

Modified: cfe/trunk/utils/TableGen/TableGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGen.cpp (original)
+++ cfe/trunk/utils/TableGen/TableGen.cpp Mon Sep 10 15:32:42 2012
@@ -44,6 +44,7 @@
   GenClangSACheckers,
   GenClangCommentHTMLTags,
   GenClangCommentHTMLTagsProperties,
+  GenClangCommentCommandInfo,
   GenOptParserDefs, GenOptParserImpl,
   GenArmNeon,
   GenArmNeonSema,
@@ -105,6 +106,10 @@
                                "gen-clang-comment-html-tags-properties",
                                "Generate efficient matchers for HTML tag "
                                "properties"),
+                    clEnumValN(GenClangCommentCommandInfo,
+                               "gen-clang-comment-command-info",
+                               "Generate list of commands that are used in "
+                               "documentation comments"),
                     clEnumValN(GenArmNeon, "gen-arm-neon",
                                "Generate arm_neon.h for clang"),
                     clEnumValN(GenArmNeonSema, "gen-arm-neon-sema",
@@ -180,6 +185,9 @@
     case GenClangCommentHTMLTagsProperties:
       EmitClangCommentHTMLTagsProperties(Records, OS);
       break;
+    case GenClangCommentCommandInfo:
+      EmitClangCommentCommandInfo(Records, OS);
+      break;
     case GenOptParserDefs:
       EmitOptParser(Records, OS, true);
       break;

Modified: cfe/trunk/utils/TableGen/TableGenBackends.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=163540&r1=163539&r2=163540&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGenBackends.h (original)
+++ cfe/trunk/utils/TableGen/TableGenBackends.h Mon Sep 10 15:32:42 2012
@@ -50,6 +50,8 @@
 void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, raw_ostream &OS);
 
+void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS);
+
 void EmitNeon(RecordKeeper &Records, raw_ostream &OS);
 void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS);
 void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS);





More information about the cfe-commits mailing list