]> granicus.if.org Git - clang/commitdiff
Comment parsing: extract TableGen'able pieces into new CommandTraits class.
authorDmitri Gribenko <gribozavr@gmail.com>
Thu, 9 Aug 2012 00:03:17 +0000 (00:03 +0000)
committerDmitri Gribenko <gribozavr@gmail.com>
Thu, 9 Aug 2012 00:03:17 +0000 (00:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161548 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/clang/AST/CommentBriefParser.h
include/clang/AST/CommentCommandTraits.h [new file with mode: 0644]
include/clang/AST/CommentLexer.h
include/clang/AST/CommentParser.h
include/clang/AST/CommentSema.h
lib/AST/ASTContext.cpp
lib/AST/CommentBriefParser.cpp
lib/AST/CommentCommandTraits.cpp [new file with mode: 0644]
lib/AST/CommentLexer.cpp
lib/AST/CommentParser.cpp
lib/AST/CommentSema.cpp
lib/AST/RawCommentList.cpp
unittests/AST/CommentLexer.cpp
unittests/AST/CommentParser.cpp

index 62fdf6bdc4123c2342a9b705bf007550a6d449de..003c33727e35ebc6404cf878b92d1887f1a5f65c 100644 (file)
@@ -30,6 +30,8 @@ namespace comments {
 class BriefParser {
   Lexer &L;
 
+  const CommandTraits &Traits;
+
   /// Current lookahead token.
   Token Tok;
 
@@ -40,7 +42,7 @@ class BriefParser {
   }
 
 public:
-  BriefParser(Lexer &L);
+  BriefParser(Lexer &L, const CommandTraits &Traits);
 
   /// Return \\brief paragraph, if it exists; otherwise return the first
   /// paragraph.
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
new file mode 100644 (file)
index 0000000..85f2d82
--- /dev/null
@@ -0,0 +1,145 @@
+//===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the class that provides information about comment
+//  commands.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace clang {
+namespace comments {
+
+/// This class provides informaiton about commands that can be used
+/// in comments.
+class CommandTraits {
+public:
+  /// \brief Check if a given 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 BeginName 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;
+
+  /// \brief Register a new verbatim block command.
+  void addVerbatimBlockCommand(StringRef BeginName, StringRef EndName);
+
+  /// \brief Check if a given 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;
+
+  /// \brief Register a new verbatim line command.
+  void addVerbatimLineCommand(StringRef Name);
+
+  /// \brief Check if a given command is a block command (of any kind).
+  bool isBlockCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is introducing documentation for
+  /// a function parameter (\\param or an alias).
+  bool isParamCommand(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;
+
+  /// \brief Check if a given command is introducing a brief documentation
+  /// paragraph (\\brief or an alias).
+  bool isBriefCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is \\brief or an alias.
+  bool isReturnsCommand(StringRef Name) const;
+
+  /// \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;
+
+  /// \brief Check if a given command is a inline command (of any kind).
+  bool isInlineCommand(StringRef Name) const;
+
+private:
+  struct VerbatimBlockCommand {
+    StringRef BeginName;
+    StringRef EndName;
+  };
+
+  typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector;
+
+  /// Registered additional verbatim-like block commands.
+  VerbatimBlockCommandVector VerbatimBlockCommands;
+
+  struct VerbatimLineCommand {
+    StringRef Name;
+  };
+
+  typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector;
+
+  /// Registered verbatim-like line commands.
+  VerbatimLineCommandVector VerbatimLineCommands;
+};
+
+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
+
+#endif
+
index 5b69a95ee0601f0610314b6878abed99a158de05..7a24b116317834262741f75414d6ea613f8e1676 100644 (file)
@@ -26,6 +26,7 @@ namespace comments {
 
 class Lexer;
 class TextTokenRetokenizer;
+class CommandTraits;
 
 namespace tok {
 enum TokenKind {
@@ -215,6 +216,8 @@ private:
   /// computed (for example, resolved decimal character references).
   llvm::BumpPtrAllocator &Allocator;
 
+  const CommandTraits &Traits;
+
   const char *const BufferStart;
   const char *const BufferEnd;
   SourceLocation FileLoc;
@@ -262,37 +265,10 @@ private:
   /// Current lexing mode.
   LexerState State;
 
-  /// A verbatim-like block command eats every character (except line starting
-  /// decorations) until matching end command is seen or comment end is hit.
-  struct VerbatimBlockCommand {
-    StringRef BeginName;
-    StringRef EndName;
-  };
-
-  typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector;
-
-  /// Registered verbatim-like block commands.
-  VerbatimBlockCommandVector VerbatimBlockCommands;
-
   /// If State is LS_VerbatimBlock, contains the name of verbatim end
   /// command, including command marker.
   SmallString<16> VerbatimBlockEndCommandName;
 
-  bool isVerbatimBlockCommand(StringRef BeginName, StringRef &EndName) const;
-
-  /// A verbatim-like line command eats everything until a newline is seen or
-  /// comment end is hit.
-  struct VerbatimLineCommand {
-    StringRef Name;
-  };
-
-  typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector;
-
-  /// Registered verbatim-like line commands.
-  VerbatimLineCommandVector VerbatimLineCommands;
-
-  bool isVerbatimLineCommand(StringRef Name) const;
-
   /// Given a character reference name (e.g., "lt"), return the character that
   /// it stands for (e.g., "<").
   StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
@@ -359,7 +335,7 @@ private:
   void lexHTMLEndTag(Token &T);
 
 public:
-  Lexer(llvm::BumpPtrAllocator &Allocator,
+  Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
         SourceLocation FileLoc, const CommentOptions &CommOpts,
         const char *BufferStart, const char *BufferEnd);
 
@@ -368,12 +344,6 @@ public:
   StringRef getSpelling(const Token &Tok,
                         const SourceManager &SourceMgr,
                         bool *Invalid = NULL) const;
-
-  /// \brief Register a new verbatim block command.
-  void addVerbatimBlockCommand(StringRef BeginName, StringRef EndName);
-
-  /// \brief Register a new verbatim line command.
-  void addVerbatimLineCommand(StringRef Name);
 };
 
 } // end namespace comments
index 9539c9f54e6891b96e01af78c169e4c8999ed639..039079931c589993a25d959efd20e365f1f5fe7e 100644 (file)
@@ -24,6 +24,7 @@ namespace clang {
 class SourceManager;
 
 namespace comments {
+class CommandTraits;
 
 /// Doxygen comment parser.
 class Parser {
@@ -48,6 +49,8 @@ class Parser {
     return Diags.Report(Loc, DiagID);
   }
 
+  const CommandTraits &Traits;
+
   /// Current lookahead token.  We can safely assume that all tokens are from
   /// a single source file.
   Token Tok;
@@ -85,7 +88,8 @@ class Parser {
 
 public:
   Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
-         const SourceManager &SourceMgr, DiagnosticsEngine &Diags);
+         const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+         const CommandTraits &Traits);
 
   /// Parse arguments for \\param command.
   void parseParamCommandArgs(ParamCommandComment *PC,
index 2fc741e7d1ce2f8245df3c466c8cf3e0e3956413..e1756ca3e2f1ea8ee4736e7f6e6519a5de21e5d1 100644 (file)
@@ -27,6 +27,7 @@ class Decl;
 class SourceMgr;
 
 namespace comments {
+class CommandTraits;
 
 class Sema {
   Sema(const Sema&);           // DO NOT IMPLEMENT
@@ -40,6 +41,8 @@ class Sema {
 
   DiagnosticsEngine &Diags;
 
+  const CommandTraits &Traits;
+
   /// Information about the declaration this comment is attached to.
   DeclInfo *ThisDeclInfo;
 
@@ -72,7 +75,7 @@ class Sema {
 
 public:
   Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
-       DiagnosticsEngine &Diags);
+       DiagnosticsEngine &Diags, const CommandTraits &Traits);
 
   void setDecl(const Decl *D);
 
@@ -213,15 +216,6 @@ public:
                               StringRef Typo,
                               const TemplateParameterList *TemplateParameters);
 
-  bool isBlockCommand(StringRef Name);
-  bool isParamCommand(StringRef Name);
-  bool isTParamCommand(StringRef Name);
-  bool isBriefCommand(StringRef Name);
-  bool isReturnsCommand(StringRef Name);
-  unsigned getBlockCommandNumArgs(StringRef Name);
-
-  bool isInlineCommand(StringRef Name) const;
-
   InlineCommandComment::RenderKind
   getInlineCommandRenderKind(StringRef Name) const;
 
index 0ff0e35a433f8e840ed7927a3868a64ee9cdd799..4e8587d19191c23ca76c7f89a62637e2f71433fb 100644 (file)
@@ -14,6 +14,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/Comment.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentSema.h"
 #include "clang/AST/CommentParser.h"
@@ -226,14 +227,16 @@ comments::FullComment *ASTContext::getCommentForDecl(const Decl *D) const {
     return NULL;
 
   const StringRef RawText = RC->getRawText(SourceMgr);
-  comments::Lexer L(getAllocator(),
+  comments::CommandTraits Traits;
+  comments::Lexer L(getAllocator(), Traits,
                     RC->getSourceRange().getBegin(), comments::CommentOptions(),
                     RawText.begin(), RawText.end());
 
-  comments::Sema S(getAllocator(), getSourceManager(), getDiagnostics());
+  comments::Sema S(getAllocator(), getSourceManager(), getDiagnostics(),
+                   Traits);
   S.setDecl(D);
   comments::Parser P(L, S, getAllocator(), getSourceManager(),
-                     getDiagnostics());
+                     getDiagnostics(), Traits);
 
   comments::FullComment *FC = P.parseFullComment();
   DeclComments[D].second = FC;
index 22209c097fd3f448553f229a6ec5d7602c373903..0aebc1e4e3ddb6a71606f4c39b7048645e1edfcb 100644 (file)
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/CommentBriefParser.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/StringSwitch.h"
 
 namespace clang {
@@ -39,19 +40,13 @@ void cleanupBrief(std::string &S) {
 
   S.resize(O - S.begin());
 }
+} // unnamed namespace
 
-bool isBlockCommand(StringRef Name) {
-  return llvm::StringSwitch<bool>(Name)
-      .Cases("brief", "short", true)
-      .Cases("result", "return", "returns", true)
-      .Cases("author", "authors", true)
-      .Case("pre", true)
-      .Case("post", true)
-      .Cases("param", "arg", true)
-      .Case("tparam", true)
-      .Default(false);
+BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
+    L(L), Traits(Traits) {
+  // Get lookahead token.
+  ConsumeToken();
 }
-} // unnamed namespace
 
 std::string BriefParser::Parse() {
   std::string FirstParagraphOrBrief;
@@ -72,18 +67,18 @@ std::string BriefParser::Parse() {
 
     if (Tok.is(tok::command)) {
       StringRef Name = Tok.getCommandName();
-      if (Name == "brief" || Name == "short") {
+      if (Traits.isBriefCommand(Name)) {
         FirstParagraphOrBrief.clear();
         InBrief = true;
         ConsumeToken();
         continue;
       }
-      if (Name == "result" || Name == "return" || Name == "returns") {
+      if (Traits.isReturnsCommand(Name)) {
         InReturns = true;
         ReturnsParagraph += "Returns ";
       }
       // Block commands implicitly start a new paragraph.
-      if (isBlockCommand(Name)) {
+      if (Traits.isBlockCommand(Name)) {
         // We found an implicit paragraph end.
         InFirstParagraph = false;
         if (InBrief)
@@ -121,11 +116,6 @@ std::string BriefParser::Parse() {
   return ReturnsParagraph;
 }
 
-BriefParser::BriefParser(Lexer &L) : L(L) {
-  // Get lookahead token.
-  ConsumeToken();
-}
-
 } // end namespace comments
 } // end namespace clang
 
diff --git a/lib/AST/CommentCommandTraits.cpp b/lib/AST/CommentCommandTraits.cpp
new file mode 100644 (file)
index 0000000..804f2ae
--- /dev/null
@@ -0,0 +1,110 @@
+//===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/CommentCommandTraits.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace clang {
+namespace comments {
+
+// TODO: tablegen
+
+bool CommandTraits::isVerbatimBlockCommand(StringRef BeginName,
+                                           StringRef &EndName) const {
+  const char *Result = llvm::StringSwitch<const char *>(BeginName)
+    .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;
+  }
+
+  for (VerbatimBlockCommandVector::const_iterator
+           I = VerbatimBlockCommands.begin(),
+           E = VerbatimBlockCommands.end();
+       I != E; ++I)
+    if (I->BeginName == BeginName) {
+      EndName = I->EndName;
+      return true;
+    }
+
+  return false;
+}
+
+bool CommandTraits::isVerbatimLineCommand(StringRef Name) const {
+  bool Result = llvm::StringSwitch<bool>(Name)
+  .Case("fn", true)
+  .Case("var", true)
+  .Case("property", true)
+  .Case("typedef", true)
+
+  .Case("overload", true)
+
+  .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;
+}
+
+void CommandTraits::addVerbatimBlockCommand(StringRef BeginName,
+                                            StringRef EndName) {
+  VerbatimBlockCommand VBC;
+  VBC.BeginName = BeginName;
+  VBC.EndName = EndName;
+  VerbatimBlockCommands.push_back(VBC);
+}
+
+void CommandTraits::addVerbatimLineCommand(StringRef Name) {
+  VerbatimLineCommand VLC;
+  VLC.Name = Name;
+  VerbatimLineCommands.push_back(VLC);
+}
+
+} // end namespace comments
+} // end namespace clang
+
index dde484510ff180acc4c9bd485ddaa6278c2d7b75..b6516ec126f6f66feea25201ca7801a5493375d9 100644 (file)
@@ -1,4 +1,5 @@
 #include "clang/AST/CommentLexer.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/Basic/ConvertUTF.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -12,82 +13,6 @@ void Token::dump(const Lexer &L, const SourceManager &SM) const {
   llvm::errs() << " " << Length << " \"" << L.getSpelling(*this, SM) << "\"\n";
 }
 
-bool Lexer::isVerbatimBlockCommand(StringRef BeginName,
-                                  StringRef &EndName) const {
-  const char *Result = llvm::StringSwitch<const char *>(BeginName)
-    .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;
-  }
-
-  for (VerbatimBlockCommandVector::const_iterator
-           I = VerbatimBlockCommands.begin(),
-           E = VerbatimBlockCommands.end();
-       I != E; ++I)
-    if (I->BeginName == BeginName) {
-      EndName = I->EndName;
-      return true;
-    }
-
-  return false;
-}
-
-bool Lexer::isVerbatimLineCommand(StringRef Name) const {
-  bool Result = llvm::StringSwitch<bool>(Name)
-  .Case("fn", true)
-  .Case("var", true)
-  .Case("property", true)
-  .Case("typedef", true)
-
-  .Case("overload", true)
-
-  .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;
-}
-
 namespace {
 bool isHTMLNamedCharacterReferenceCharacter(char C) {
   return (C >= 'a' && C <= 'z') ||
@@ -433,11 +358,11 @@ void Lexer::lexCommentText(Token &T) {
         const StringRef CommandName(BufferPtr + 1, Length);
         StringRef EndName;
 
-        if (isVerbatimBlockCommand(CommandName, EndName)) {
+        if (Traits.isVerbatimBlockCommand(CommandName, EndName)) {
           setupAndLexVerbatimBlock(T, TokenPtr, *BufferPtr, EndName);
           return;
         }
-        if (isVerbatimLineCommand(CommandName)) {
+        if (Traits.isVerbatimLineCommand(CommandName)) {
           setupAndLexVerbatimLine(T, TokenPtr);
           return;
         }
@@ -757,10 +682,10 @@ void Lexer::lexHTMLEndTag(Token &T) {
   State = LS_Normal;
 }
 
-Lexer::Lexer(llvm::BumpPtrAllocator &Allocator,
+Lexer::Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
              SourceLocation FileLoc, const CommentOptions &CommOpts,
              const char *BufferStart, const char *BufferEnd):
-    Allocator(Allocator),
+    Allocator(Allocator), Traits(Traits),
     BufferStart(BufferStart), BufferEnd(BufferEnd),
     FileLoc(FileLoc), CommOpts(CommOpts), BufferPtr(BufferStart),
     CommentState(LCS_BeforeComment), State(LS_Normal) {
@@ -885,19 +810,6 @@ StringRef Lexer::getSpelling(const Token &Tok,
   return StringRef(Begin, Tok.getLength());
 }
 
-void Lexer::addVerbatimBlockCommand(StringRef BeginName, StringRef EndName) {
-  VerbatimBlockCommand VBC;
-  VBC.BeginName = BeginName;
-  VBC.EndName = EndName;
-  VerbatimBlockCommands.push_back(VBC);
-}
-
-void Lexer::addVerbatimLineCommand(StringRef Name) {
-  VerbatimLineCommand VLC;
-  VLC.Name = Name;
-  VerbatimLineCommands.push_back(VLC);
-}
-
 } // end namespace comments
 } // end namespace clang
 
index eb1027a9b6396772166cc76f10c18c8e2d24207e..43abf6a476a8c5f9e045916d6e683dead1587934 100644 (file)
@@ -10,6 +10,7 @@
 #include "clang/AST/CommentParser.h"
 #include "clang/AST/CommentSema.h"
 #include "clang/AST/CommentDiagnostic.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -250,8 +251,10 @@ public:
 };
 
 Parser::Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
-               const SourceManager &SourceMgr, DiagnosticsEngine &Diags):
-    L(L), S(S), Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags) {
+               const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+               const CommandTraits &Traits):
+    L(L), S(S), Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags),
+    Traits(Traits) {
   consumeToken();
 }
 
@@ -310,25 +313,25 @@ BlockCommandComment *Parser::parseBlockCommand() {
   bool IsParam = false;
   bool IsTParam = false;
   unsigned NumArgs = 0;
-  if (S.isParamCommand(Tok.getCommandName())) {
+  if (Traits.isParamCommand(Tok.getCommandName())) {
     IsParam = true;
     PC = S.actOnParamCommandStart(Tok.getLocation(),
                                   Tok.getEndLocation(),
                                   Tok.getCommandName());
-  } if (S.isTParamCommand(Tok.getCommandName())) {
+  } if (Traits.isTParamCommand(Tok.getCommandName())) {
     IsTParam = true;
     TPC = S.actOnTParamCommandStart(Tok.getLocation(),
                                     Tok.getEndLocation(),
                                     Tok.getCommandName());
   } else {
-    NumArgs = S.getBlockCommandNumArgs(Tok.getCommandName());
+    NumArgs = Traits.getBlockCommandNumArgs(Tok.getCommandName());
     BC = S.actOnBlockCommandStart(Tok.getLocation(),
                                   Tok.getEndLocation(),
                                   Tok.getCommandName());
   }
   consumeToken();
 
-  if (Tok.is(tok::command) && S.isBlockCommand(Tok.getCommandName())) {
+  if (Tok.is(tok::command) && Traits.isBlockCommand(Tok.getCommandName())) {
     // Block command ahead.  We can't nest block commands, so pretend that this
     // command has an empty argument.
     ParagraphComment *Paragraph = S.actOnParagraphComment(
@@ -538,12 +541,12 @@ BlockContentComment *Parser::parseParagraphOrBlockCommand() {
       break; // Block content or EOF ahead, finish this parapgaph.
 
     case tok::command:
-      if (S.isBlockCommand(Tok.getCommandName())) {
+      if (Traits.isBlockCommand(Tok.getCommandName())) {
         if (Content.size() == 0)
           return parseBlockCommand();
         break; // Block command ahead, finish this parapgaph.
       }
-      if (S.isInlineCommand(Tok.getCommandName())) {
+      if (Traits.isInlineCommand(Tok.getCommandName())) {
         Content.push_back(parseInlineCommand());
         continue;
       }
index 978c748b7416da8347e9a74265091aaac46fb816..c39ee573ef6f57120b455afcb794f890604f777a 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "clang/AST/CommentSema.h"
 #include "clang/AST/CommentDiagnostic.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/Basic/SourceManager.h"
@@ -18,8 +19,8 @@ namespace clang {
 namespace comments {
 
 Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
-           DiagnosticsEngine &Diags) :
-    Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags),
+           DiagnosticsEngine &Diags, const CommandTraits &Traits) :
+    Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
     ThisDeclInfo(NULL), BriefCommand(NULL), ReturnsCommand(NULL) {
 }
 
@@ -462,7 +463,7 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
 }
 
 void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
-  if (!isReturnsCommand(Command->getCommandName()))
+  if (!Traits.isReturnsCommand(Command->getCommandName()))
     return;
   if (isFunctionDecl()) {
     if (ThisDeclInfo->ResultType->isVoidType()) {
@@ -498,13 +499,13 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
 void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
   StringRef Name = Command->getCommandName();
   const BlockCommandComment *PrevCommand = NULL;
-  if (isBriefCommand(Name)) {
+  if (Traits.isBriefCommand(Name)) {
     if (!BriefCommand) {
       BriefCommand = Command;
       return;
     }
     PrevCommand = BriefCommand;
-  } else if (isReturnsCommand(Name)) {
+  } else if (Traits.isReturnsCommand(Name)) {
     if (!ReturnsCommand) {
       ReturnsCommand = Command;
       return;
@@ -697,58 +698,9 @@ StringRef Sema::correctTypoInTParamReference(
   return StringRef();
 }
 
-// TODO: tablegen
-bool Sema::isBlockCommand(StringRef Name) {
-  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);
-}
-
-bool Sema::isParamCommand(StringRef Name) {
-  return llvm::StringSwitch<bool>(Name)
-      .Case("param", true)
-      .Case("arg", true)
-      .Default(false);
-}
-
-bool Sema::isTParamCommand(StringRef Name) {
-  return Name == "tparam";
-}
-
-bool Sema::isBriefCommand(StringRef Name) {
-  return Name == "brief" || Name == "short";
-}
-
-bool Sema::isReturnsCommand(StringRef Name) {
-  return Name == "returns" || Name == "return" || Name == "result";
-}
-
-unsigned Sema::getBlockCommandNumArgs(StringRef Name) {
-  return llvm::StringSwitch<unsigned>(Name)
-      .Cases("brief", "short", 0)
-      .Case("pre", 0)
-      .Case("post", 0)
-      .Case("author", 0)
-      .Case("authors", 0)
-      .Default(0);
-}
-
-bool Sema::isInlineCommand(StringRef Name) const {
-  return llvm::StringSwitch<bool>(Name)
-      .Case("b", true)
-      .Cases("c", "p", true)
-      .Cases("a", "e", "em", true)
-      .Default(false);
-}
-
 InlineCommandComment::RenderKind
 Sema::getInlineCommandRenderKind(StringRef Name) const {
-  assert(isInlineCommand(Name));
+  assert(Traits.isInlineCommand(Name));
 
   return llvm::StringSwitch<InlineCommandComment::RenderKind>(Name)
       .Case("b", InlineCommandComment::RenderBold)
index 41866cf03f114a1e5a57b8a38fc6f874ddd12dc7..4f7165f0e4a9e1ddbf034cc0e0d5c41132605689 100644 (file)
@@ -11,6 +11,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentBriefParser.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/STLExtras.h"
 
 using namespace clang;
@@ -139,10 +140,11 @@ const char *RawComment::extractBriefText(const ASTContext &Context) const {
   // a separate allocator for all temporary stuff.
   llvm::BumpPtrAllocator Allocator;
 
-  comments::Lexer L(Allocator,
+  comments::CommandTraits Traits;
+  comments::Lexer L(Allocator, Traits,
                     Range.getBegin(), comments::CommentOptions(),
                     RawText.begin(), RawText.end());
-  comments::BriefParser P(L);
+  comments::BriefParser P(L, Traits);
 
   const std::string Result = P.Parse();
   const unsigned BriefTextLength = Result.size();
index 8b5d0c8cf015ddf836f7efd9dc2f416a537f2d19..cab0fdddbc2fb7f605ff9f23b8dd4887cf6d5db3 100644 (file)
@@ -11,6 +11,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/AST/CommentLexer.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/STLExtras.h"
 #include <vector>
 
@@ -48,7 +49,8 @@ void CommentLexerTest::lexString(const char *Source,
   FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
-  comments::Lexer L(Allocator, Begin, CommentOptions(),
+  comments::CommandTraits Traits;
+  comments::Lexer L(Allocator, Traits, Begin, CommentOptions(),
                     Source, Source + strlen(Source));
 
   while (1) {
index 1e106c59f1886875324f468e4aec96deda979559..7258a7ef576c6777e19d695eb7f5438b017ece27 100644 (file)
@@ -14,6 +14,7 @@
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentParser.h"
 #include "clang/AST/CommentSema.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Allocator.h"
 #include <vector>
@@ -54,11 +55,12 @@ FullComment *CommentParserTest::parseString(const char *Source) {
   FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
-  comments::Lexer L(Allocator, Begin, CommentOptions(),
+  comments::CommandTraits Traits;
+  comments::Lexer L(Allocator, Traits, Begin, CommentOptions(),
                     Source, Source + strlen(Source));
 
-  comments::Sema S(Allocator, SourceMgr, Diags);
-  comments::Parser P(L, S, Allocator, SourceMgr, Diags);
+  comments::Sema S(Allocator, SourceMgr, Diags, Traits);
+  comments::Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
   comments::FullComment *FC = P.parseFullComment();
 
   if (DEBUG) {