diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 0c45697a80..c21dafd2dc 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -3307,6 +3307,33 @@ enum CXCommentKind { CXComment_FullComment = 11 }; +/** + * \brief The most appropriate rendering mode for an inline command, chosen on + * command semantics in Doxygen. + */ +enum CXCommentInlineCommandRenderKind { + /** + * \brief Command argument should be rendered in a normal font. + */ + CXCommentInlineCommandRenderKind_Normal, + + /** + * \brief Command argument should be rendered in a bold font. + */ + CXCommentInlineCommandRenderKind_Bold, + + /** + * \brief Command argument should be rendered in a monospaced font. + */ + CXCommentInlineCommandRenderKind_Monospaced, + + /** + * \brief Command argument should be rendered emphasized (typically italic + * font). + */ + CXCommentInlineCommandRenderKind_Emphasized +}; + /** * \brief Describes parameter passing direction for \\param or \\arg command. */ @@ -3385,6 +3412,15 @@ CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment); CINDEX_LINKAGE CXString clang_InlineCommandComment_getCommandName(CXComment Comment); +/** + * \param Comment a \c CXComment_InlineCommand AST node. + * + * \returns the most appropriate rendering mode, chosen on command + * semantics in Doxygen. + */ +CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind +clang_InlineCommandComment_getRenderKind(CXComment Comment); + /** * \param Comment a \c CXComment_InlineCommand AST node. * diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h index 544a7e4d53..55cb08141a 100644 --- a/include/clang/AST/Comment.h +++ b/include/clang/AST/Comment.h @@ -63,6 +63,15 @@ protected: }; enum { NumTextCommentBits = NumInlineContentCommentBits + 2 }; + class InlineCommandCommentBitfields { + friend class InlineCommandComment; + + unsigned : NumInlineContentCommentBits; + + unsigned RenderKind : 2; + }; + enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 }; + class HTMLStartTagCommentBitfields { friend class HTMLStartTagComment; @@ -104,6 +113,7 @@ protected: CommentBitfields CommentBits; InlineContentCommentBitfields InlineContentCommentBits; TextCommentBitfields TextCommentBits; + InlineCommandCommentBitfields InlineCommandCommentBits; HTMLStartTagCommentBitfields HTMLStartTagCommentBits; ParagraphCommentBitfields ParagraphCommentBits; ParamCommandCommentBitfields ParamCommandCommentBits; @@ -248,6 +258,15 @@ public: Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { } }; + /// The most appropriate rendering mode for this command, chosen on command + /// semantics in Doxygen. + enum RenderKind { + RenderNormal, + RenderBold, + RenderMonospaced, + RenderEmphasized + }; + protected: /// Command name. StringRef Name; @@ -259,10 +278,12 @@ public: InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Name, + RenderKind RK, llvm::ArrayRef Args) : - InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), - Name(Name), Args(Args) - { } + InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), + Name(Name), Args(Args) { + InlineCommandCommentBits.RenderKind = RK; + } static bool classof(const Comment *C) { return C->getCommentKind() == InlineCommandCommentKind; @@ -283,6 +304,10 @@ public: getLocEnd()); } + RenderKind getRenderKind() const { + return static_cast(InlineCommandCommentBits.RenderKind); + } + unsigned getNumArgs() const { return Args.size(); } diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 14be08a895..be8179d126 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -155,7 +155,10 @@ public: bool isParamCommand(StringRef Name); unsigned getBlockCommandNumArgs(StringRef Name); - bool isInlineCommand(StringRef Name); + bool isInlineCommand(StringRef Name) const; + + InlineCommandComment::RenderKind + getInlineCommandRenderKind(StringRef Name) const; bool isHTMLEndTagOptional(StringRef Name); bool isHTMLEndTagForbidden(StringRef Name); diff --git a/lib/AST/CommentDumper.cpp b/lib/AST/CommentDumper.cpp index 7a4ca0c12a..c930b24504 100644 --- a/lib/AST/CommentDumper.cpp +++ b/lib/AST/CommentDumper.cpp @@ -107,6 +107,21 @@ void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) { dumpComment(C); OS << " Name=\"" << C->getCommandName() << "\""; + switch (C->getRenderKind()) { + case InlineCommandComment::RenderNormal: + OS << " RenderNormal"; + break; + case InlineCommandComment::RenderBold: + OS << " RenderBold"; + break; + case InlineCommandComment::RenderMonospaced: + OS << " RenderMonospaced"; + break; + case InlineCommandComment::RenderEmphasized: + OS << " RenderEmphasized"; + break; + } + for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; } diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp index 3d8635fb19..6c37452e07 100644 --- a/lib/AST/CommentSema.cpp +++ b/lib/AST/CommentSema.cpp @@ -202,10 +202,12 @@ InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, SourceLocation CommandLocEnd, StringRef CommandName) { ArrayRef Args; - return new (Allocator) InlineCommandComment(CommandLocBegin, - CommandLocEnd, - CommandName, - Args); + return new (Allocator) InlineCommandComment( + CommandLocBegin, + CommandLocEnd, + CommandName, + getInlineCommandRenderKind(CommandName), + Args); } InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, @@ -219,17 +221,22 @@ InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, ArgLocEnd), Arg); - return new (Allocator) InlineCommandComment(CommandLocBegin, - CommandLocEnd, - CommandName, - llvm::makeArrayRef(A, 1)); + return new (Allocator) InlineCommandComment( + CommandLocBegin, + CommandLocEnd, + CommandName, + getInlineCommandRenderKind(CommandName), + llvm::makeArrayRef(A, 1)); } InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Name) { ArrayRef Args; - return new (Allocator) InlineCommandComment(LocBegin, LocEnd, Name, Args); + return new (Allocator) InlineCommandComment( + LocBegin, LocEnd, Name, + InlineCommandComment::RenderNormal, + Args); } TextComment *Sema::actOnText(SourceLocation LocBegin, @@ -445,7 +452,7 @@ unsigned Sema::getBlockCommandNumArgs(StringRef Name) { .Default(0); } -bool Sema::isInlineCommand(StringRef Name) { +bool Sema::isInlineCommand(StringRef Name) const { return llvm::StringSwitch(Name) .Case("b", true) .Cases("c", "p", true) @@ -453,6 +460,17 @@ bool Sema::isInlineCommand(StringRef Name) { .Default(false); } +InlineCommandComment::RenderKind +Sema::getInlineCommandRenderKind(StringRef Name) const { + assert(isInlineCommand(Name)); + + return llvm::StringSwitch(Name) + .Case("b", InlineCommandComment::RenderBold) + .Cases("c", "p", InlineCommandComment::RenderMonospaced) + .Cases("a", "e", "em", InlineCommandComment::RenderEmphasized) + .Default(InlineCommandComment::RenderNormal); +} + bool Sema::isHTMLEndTagOptional(StringRef Name) { return llvm::StringSwitch(Name) .Case("p", true) diff --git a/test/Index/annotate-comments.cpp b/test/Index/annotate-comments.cpp index 872a9fa424..980f30bc50 100644 --- a/test/Index/annotate-comments.cpp +++ b/test/Index/annotate-comments.cpp @@ -572,25 +572,25 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) -// CHECK-NEXT: (CXComment_InlineCommand CommandName=[b] Arg[0]=Aaa)))] +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[b] RenderBold Arg[0]=Aaa)))] // CHECK: annotate-comments.cpp:307:6: FunctionDecl=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[

Aaa Bbb

] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) -// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] Arg[0]=Aaa) +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=Aaa) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) -// CHECK-NEXT: (CXComment_InlineCommand CommandName=[p] Arg[0]=Bbb)))] +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[p] RenderMonospaced Arg[0]=Bbb)))] // CHECK: annotate-comments.cpp:310:6: FunctionDecl=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[

Aaa Bbb Ccc

] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) -// CHECK-NEXT: (CXComment_InlineCommand CommandName=[a] Arg[0]=Aaa) +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[a] RenderEmphasized Arg[0]=Aaa) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) -// CHECK-NEXT: (CXComment_InlineCommand CommandName=[e] Arg[0]=Bbb) +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[e] RenderEmphasized Arg[0]=Bbb) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) -// CHECK-NEXT: (CXComment_InlineCommand CommandName=[em] Arg[0]=Ccc)))] +// CHECK-NEXT: (CXComment_InlineCommand CommandName=[em] RenderEmphasized Arg[0]=Ccc)))] // CHECK: annotate-comments.cpp:313:6: FunctionDecl=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[

\ @ & $ # < > % " . ::

] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 574c9f7383..df7c72a9d8 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -283,6 +283,20 @@ static void DumpCXCommentInternal(struct CommentASTDumpingContext *Ctx, PrintCXStringWithPrefixAndDispose( "CommandName", clang_InlineCommandComment_getCommandName(Comment)); + switch (clang_InlineCommandComment_getRenderKind(Comment)) { + case CXCommentInlineCommandRenderKind_Normal: + printf(" RenderNormal"); + break; + case CXCommentInlineCommandRenderKind_Bold: + printf(" RenderBold"); + break; + case CXCommentInlineCommandRenderKind_Monospaced: + printf(" RenderMonospaced"); + break; + case CXCommentInlineCommandRenderKind_Emphasized: + printf(" RenderEmphasized"); + break; + } for (i = 0, e = clang_InlineCommandComment_getNumArgs(Comment); i != e; ++i) { printf(" Arg[%u]=", i); diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp index b0ed9bcc00..6cd92356fd 100644 --- a/tools/libclang/CXComment.cpp +++ b/tools/libclang/CXComment.cpp @@ -126,6 +126,28 @@ CXString clang_InlineCommandComment_getCommandName(CXComment CXC) { return createCXString(ICC->getCommandName(), /*DupString=*/ false); } +enum CXCommentInlineCommandRenderKind +clang_InlineCommandComment_getRenderKind(CXComment CXC) { + const InlineCommandComment *ICC = getASTNodeAs(CXC); + if (!ICC) + return CXCommentInlineCommandRenderKind_Normal; + + switch (ICC->getRenderKind()) { + case InlineCommandComment::RenderNormal: + return CXCommentInlineCommandRenderKind_Normal; + + case InlineCommandComment::RenderBold: + return CXCommentInlineCommandRenderKind_Bold; + + case InlineCommandComment::RenderMonospaced: + return CXCommentInlineCommandRenderKind_Monospaced; + + case InlineCommandComment::RenderEmphasized: + return CXCommentInlineCommandRenderKind_Emphasized; + } + llvm_unreachable("unknown InlineCommandComment::RenderKind"); +} + unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) { const InlineCommandComment *ICC = getASTNodeAs(CXC); if (!ICC) @@ -344,34 +366,34 @@ void CommentASTToHTMLConverter::visitTextComment(const TextComment *C) { void CommentASTToHTMLConverter::visitInlineCommandComment( const InlineCommandComment *C) { - StringRef CommandName = C->getCommandName(); - bool HasArg0 = C->getNumArgs() > 0 && !C->getArgText(0).empty(); - StringRef Arg0; - if (HasArg0) - Arg0 = C->getArgText(0); + // Nothing to render if no arguments supplied. + if (C->getNumArgs() == 0) + return; - if (CommandName == "b") { - if (!HasArg0) - return; + // Nothing to render if argument is empty. + StringRef Arg0 = C->getArgText(0); + if (Arg0.empty()) + return; + + switch (C->getRenderKind()) { + case InlineCommandComment::RenderNormal: + for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) + Result << C->getArgText(i) << " "; + return; + + case InlineCommandComment::RenderBold: + assert(C->getNumArgs() == 1); Result << "" << Arg0 << ""; return; - } - if (CommandName == "c" || CommandName == "p") { - if (!HasArg0) - return; + case InlineCommandComment::RenderMonospaced: + assert(C->getNumArgs() == 1); Result << "" << Arg0 << ""; return; - } - if (CommandName == "a" || CommandName == "e" || CommandName == "em") { - if (!HasArg0) - return; + case InlineCommandComment::RenderEmphasized: + assert(C->getNumArgs() == 1); Result << "" << Arg0 << ""; return; } - - // We don't recognize this command, so just print its arguments. - for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) - Result << C->getArgText(i) << " "; } void CommentASTToHTMLConverter::visitHTMLStartTagComment( diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 7d3b2a9c5d..bc8c113fad 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -25,6 +25,7 @@ clang_Comment_isWhitespace clang_InlineContentComment_hasTrailingNewline clang_TextComment_getText clang_InlineCommandComment_getCommandName +clang_InlineCommandComment_getRenderKind clang_InlineCommandComment_getNumArgs clang_InlineCommandComment_getArgText clang_HTMLTagComment_getTagName