Comment parsing: extract TableGen'able pieces into new CommandTraits class.

llvm-svn: 161548
This commit is contained in:
Dmitri Gribenko 2012-08-09 00:03:17 +00:00
parent 5fbbc5bfe8
commit ca7f80ada0
14 changed files with 322 additions and 231 deletions

View 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.

View File

@ -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

View 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

View 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,

View 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;

View 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;

View File

@ -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 @@ void cleanupBrief(std::string &S) {
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 @@ 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

View File

@ -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

View 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

View 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;
}

View 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)

View 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();

View 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) {

View 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) {