Comment parsing: extract TableGen'able pieces into new CommandTraits class.
llvm-svn: 161548
This commit is contained in:
parent
5fbbc5bfe8
commit
ca7f80ada0
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue