Comment parsing: extract TableGen'able pieces into new CommandTraits class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161548 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 0ff0e35..4e8587d 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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 @@
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;
diff --git a/lib/AST/CommentBriefParser.cpp b/lib/AST/CommentBriefParser.cpp
index 22209c0..0aebc1e 100644
--- a/lib/AST/CommentBriefParser.cpp
+++ b/lib/AST/CommentBriefParser.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/CommentBriefParser.h"
+#include "clang/AST/CommentCommandTraits.h"
#include "llvm/ADT/StringSwitch.h"
namespace clang {
@@ -39,20 +40,14 @@
S.resize(O - S.begin());
}
-
-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);
-}
} // unnamed namespace
+BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
+ L(L), Traits(Traits) {
+ // Get lookahead token.
+ ConsumeToken();
+}
+
std::string BriefParser::Parse() {
std::string FirstParagraphOrBrief;
std::string ReturnsParagraph;
@@ -72,18 +67,18 @@
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 @@
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
index 0000000..804f2ae
--- /dev/null
+++ b/lib/AST/CommentCommandTraits.cpp
@@ -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
+
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index dde4845..b6516ec 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -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 @@
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 @@
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 @@
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 @@
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
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index eb1027a..43abf6a 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -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 @@
};
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 @@
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 @@
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;
}
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 978c748..c39ee57 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -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 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::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::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 @@
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)
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 41866cf..4f7165f 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -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 @@
// 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();