CommentToXML.cpp revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko//===--- CommentToXML.cpp - Convert comments to XML representation --------===// 286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko// 386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko// The LLVM Compiler Infrastructure 486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko// 586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko// This file is distributed under the University of Illinois Open Source 686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko// License. See LICENSE.TXT for details. 786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko// 886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko//===----------------------------------------------------------------------===// 986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 1086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/Index/CommentToXML.h" 1186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "SimpleFormatContext.h" 1286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/AST/ASTContext.h" 13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/Attr.h" 1486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/AST/Comment.h" 1586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/AST/CommentVisitor.h" 1686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/Format/Format.h" 1786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/Index/USRGeneration.h" 1886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "clang/Lex/Lexer.h" 1986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "llvm/ADT/StringExtras.h" 2086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "llvm/ADT/TinyPtrVector.h" 2186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko#include "llvm/Support/raw_ostream.h" 2286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 2386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkousing namespace clang; 2486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkousing namespace clang::comments; 2586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkousing namespace clang::index; 2686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 2786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkonamespace { 2886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 2986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// This comparison will sort parameters with valid index by index, then vararg 3086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// parameters, and invalid (unresolved) parameters last. 3186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkoclass ParamCommandCommentCompareIndex { 3286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkopublic: 3386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko bool operator()(const ParamCommandComment *LHS, 3486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParamCommandComment *RHS) const { 3586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned LHSIndex = UINT_MAX; 3686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned RHSIndex = UINT_MAX; 3786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 3886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (LHS->isParamIndexValid()) { 3986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (LHS->isVarArgParam()) 4086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko LHSIndex = UINT_MAX - 1; 4186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 4286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko LHSIndex = LHS->getParamIndex(); 4386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 4486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (RHS->isParamIndexValid()) { 4586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (RHS->isVarArgParam()) 4686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RHSIndex = UINT_MAX - 1; 4786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 4886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RHSIndex = RHS->getParamIndex(); 4986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 5086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return LHSIndex < RHSIndex; 5186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 5286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko}; 5386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 5486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// This comparison will sort template parameters in the following order: 5586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// \li real template parameters (depth = 1) in index order; 5686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// \li all other names (depth > 1); 5786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// \li unresolved names. 5886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkoclass TParamCommandCommentComparePosition { 5986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkopublic: 6086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko bool operator()(const TParamCommandComment *LHS, 6186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const TParamCommandComment *RHS) const { 6286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Sort unresolved names last. 6386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!LHS->isPositionValid()) 6486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return false; 6586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!RHS->isPositionValid()) 6686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return true; 6786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 6886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (LHS->getDepth() > 1) 6986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return false; 7086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (RHS->getDepth() > 1) 7186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return true; 7286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 7386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Sort template parameters in index order. 7486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (LHS->getDepth() == 1 && RHS->getDepth() == 1) 7586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return LHS->getIndex(0) < RHS->getIndex(0); 7686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 7786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Leave all other names in source order. 7886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return true; 7986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 8086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko}; 8186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 8286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko/// Separate parts of a FullComment. 8386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkostruct FullCommentParts { 8486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// Take a full comment apart and initialize members accordingly. 8586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FullCommentParts(const FullComment *C, 8686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandTraits &Traits); 8786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 8886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const BlockContentComment *Brief; 8986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const BlockContentComment *Headerfile; 9086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParagraphComment *FirstParagraph; 9186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVector<const BlockCommandComment *, 4> Returns; 9286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVector<const ParamCommandComment *, 8> Params; 9386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVector<const TParamCommandComment *, 4> TParams; 9486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm::TinyPtrVector<const BlockCommandComment *> Exceptions; 9586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVector<const BlockContentComment *, 8> MiscBlocks; 9686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko}; 9786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 9886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri GribenkoFullCommentParts::FullCommentParts(const FullComment *C, 9986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandTraits &Traits) : 1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Brief(nullptr), Headerfile(nullptr), FirstParagraph(nullptr) { 10186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 10286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko I != E; ++I) { 10386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const Comment *Child = *I; 10486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!Child) 10586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko continue; 10686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (Child->getCommentKind()) { 10786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::NoCommentKind: 10886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko continue; 10986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 11086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::ParagraphCommentKind: { 11186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParagraphComment *PC = cast<ParagraphComment>(Child); 11286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (PC->isWhitespace()) 11386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 11486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!FirstParagraph) 11586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FirstParagraph = PC; 11686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 11786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko MiscBlocks.push_back(PC); 11886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 11986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 12086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 12186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::BlockCommandCommentKind: { 12286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const BlockCommandComment *BCC = cast<BlockCommandComment>(Child); 12386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID()); 12486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!Brief && Info->IsBriefCommand) { 12586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Brief = BCC; 12686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 12786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 12886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!Headerfile && Info->IsHeaderfileCommand) { 12986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Headerfile = BCC; 13086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 13186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 13286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Info->IsReturnsCommand) { 13386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Returns.push_back(BCC); 13486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 13586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 13686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Info->IsThrowsCommand) { 13786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Exceptions.push_back(BCC); 13886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 13986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 14086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko MiscBlocks.push_back(BCC); 14186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 14286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 14386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 14486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::ParamCommandCommentKind: { 14586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParamCommandComment *PCC = cast<ParamCommandComment>(Child); 14686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!PCC->hasParamName()) 14786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 14886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 14986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph()) 15086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 15186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 15286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Params.push_back(PCC); 15386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 15486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 15586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 15686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::TParamCommandCommentKind: { 15786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child); 15886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!TPCC->hasParamName()) 15986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 16086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 16186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!TPCC->hasNonWhitespaceParagraph()) 16286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 16386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 16486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko TParams.push_back(TPCC); 16586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 16686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 16786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 16886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::VerbatimBlockCommentKind: 16986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko MiscBlocks.push_back(cast<BlockCommandComment>(Child)); 17086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 17186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 17286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::VerbatimLineCommentKind: { 17386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child); 17486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID()); 17586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!Info->IsDeclarationCommand) 17686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko MiscBlocks.push_back(VLC); 17786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 17886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 17986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 18086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::TextCommentKind: 18186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::InlineCommandCommentKind: 18286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::HTMLStartTagCommentKind: 18386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::HTMLEndTagCommentKind: 18486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::VerbatimBlockLineCommentKind: 18586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case Comment::FullCommentKind: 18686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm_unreachable("AST node of this kind can't be a child of " 18786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko "a FullComment"); 18886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 18986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 19086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 19186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Sort params in order they are declared in the function prototype. 19286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Unresolved parameters are put at the end of the list in the same order 19386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // they were seen in the comment. 19486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko std::stable_sort(Params.begin(), Params.end(), 19586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko ParamCommandCommentCompareIndex()); 19686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 19786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko std::stable_sort(TParams.begin(), TParams.end(), 19886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko TParamCommandCommentComparePosition()); 19986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 20086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 20186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid printHTMLStartTagComment(const HTMLStartTagComment *C, 20286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm::raw_svector_ostream &Result) { 20386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<" << C->getTagName(); 20486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 20586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->getNumAttrs() != 0) { 20686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) { 20786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " "; 20886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 20986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << Attr.Name; 21086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!Attr.Value.empty()) 21186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "=\"" << Attr.Value << "\""; 21286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 21386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 21486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 21586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!C->isSelfClosing()) 21686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << ">"; 21786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 21886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "/>"; 21986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 22086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 22186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkoclass CommentASTToHTMLConverter : 22286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko public ConstCommentVisitor<CommentASTToHTMLConverter> { 22386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkopublic: 22486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// \param Str accumulator for HTML. 22586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko CommentASTToHTMLConverter(const FullComment *FC, 22686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVectorImpl<char> &Str, 22786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandTraits &Traits) : 22886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FC(FC), Result(Str), Traits(Traits) 22986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko { } 23086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 23186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Inline content. 23286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitTextComment(const TextComment *C); 23386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitInlineCommandComment(const InlineCommandComment *C); 23486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitHTMLStartTagComment(const HTMLStartTagComment *C); 23586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitHTMLEndTagComment(const HTMLEndTagComment *C); 23686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 23786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Block content. 23886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitParagraphComment(const ParagraphComment *C); 23986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitBlockCommandComment(const BlockCommandComment *C); 24086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitParamCommandComment(const ParamCommandComment *C); 24186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitTParamCommandComment(const TParamCommandComment *C); 24286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitVerbatimBlockComment(const VerbatimBlockComment *C); 24386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); 24486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitVerbatimLineComment(const VerbatimLineComment *C); 24586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 24686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitFullComment(const FullComment *C); 24786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 24886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Helpers. 24986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 25086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// Convert a paragraph that is not a block by itself (an argument to some 25186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// command). 25286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitNonStandaloneParagraphComment(const ParagraphComment *C); 25386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 25486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void appendToResultWithHTMLEscaping(StringRef S); 25586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 25686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkoprivate: 25786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const FullComment *FC; 25886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// Output stream for HTML. 25986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm::raw_svector_ostream Result; 26086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 26186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandTraits &Traits; 26286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko}; 26386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} // end unnamed namespace 26486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 26586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitTextComment(const TextComment *C) { 26686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getText()); 26786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 26886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 26986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitInlineCommandComment( 27086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const InlineCommandComment *C) { 27186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Nothing to render if no arguments supplied. 27286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->getNumArgs() == 0) 27386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 27486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 27586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Nothing to render if argument is empty. 27686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef Arg0 = C->getArgText(0); 27786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Arg0.empty()) 27886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 27986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 28086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C->getRenderKind()) { 28186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderNormal: 28286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) { 28386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getArgText(i)); 28486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " "; 28586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 28686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 28786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 28886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderBold: 28986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko assert(C->getNumArgs() == 1); 29086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<b>"; 29186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(Arg0); 29286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</b>"; 29386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 29486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderMonospaced: 29586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko assert(C->getNumArgs() == 1); 29686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<tt>"; 29786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(Arg0); 29886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result<< "</tt>"; 29986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 30086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderEmphasized: 30186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko assert(C->getNumArgs() == 1); 30286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<em>"; 30386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(Arg0); 30486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</em>"; 30586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 30686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 30786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 30886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 30986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLStartTagComment( 31086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const HTMLStartTagComment *C) { 31186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko printHTMLStartTagComment(C, Result); 31286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 31386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 31486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLEndTagComment( 31586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const HTMLEndTagComment *C) { 31686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</" << C->getTagName() << ">"; 31786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 31886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 31986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitParagraphComment( 32086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParagraphComment *C) { 32186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isWhitespace()) 32286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 32386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 32486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<p>"; 32586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 32686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko I != E; ++I) { 32786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(*I); 32886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 32986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</p>"; 33086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 33186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 33286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitBlockCommandComment( 33386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const BlockCommandComment *C) { 33486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID()); 33586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Info->IsBriefCommand) { 33686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<p class=\"para-brief\">"; 33786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visitNonStandaloneParagraphComment(C->getParagraph()); 33886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</p>"; 33986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 34086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 34186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Info->IsReturnsCommand) { 34286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<p class=\"para-returns\">" 34386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko "<span class=\"word-returns\">Returns</span> "; 34486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visitNonStandaloneParagraphComment(C->getParagraph()); 34586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</p>"; 34686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 34786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 34886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // We don't know anything about this command. Just render the paragraph. 34986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(C->getParagraph()); 35086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 35186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 35286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitParamCommandComment( 35386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParamCommandComment *C) { 35486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isParamIndexValid()) { 35586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isVarArgParam()) { 35686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dt class=\"param-name-index-vararg\">"; 35786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getParamNameAsWritten()); 35886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else { 35986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dt class=\"param-name-index-" 36086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << C->getParamIndex() 36186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "\">"; 36286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getParamName(FC)); 36386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 36486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else { 36586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dt class=\"param-name-index-invalid\">"; 36686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getParamNameAsWritten()); 36786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 36886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</dt>"; 36986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 37086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isParamIndexValid()) { 37186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isVarArgParam()) 37286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dd class=\"param-descr-index-vararg\">"; 37386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 37486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dd class=\"param-descr-index-" 37586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << C->getParamIndex() 37686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "\">"; 37786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else 37886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dd class=\"param-descr-index-invalid\">"; 37986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 38086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visitNonStandaloneParagraphComment(C->getParagraph()); 38186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</dd>"; 38286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 38386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 38486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitTParamCommandComment( 38586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const TParamCommandComment *C) { 38686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isPositionValid()) { 38786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->getDepth() == 1) 38886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dt class=\"tparam-name-index-" 38986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << C->getIndex(0) 39086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "\">"; 39186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 39286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dt class=\"tparam-name-index-other\">"; 39386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getParamName(FC)); 39486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else { 39586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dt class=\"tparam-name-index-invalid\">"; 39686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getParamNameAsWritten()); 39786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 39886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 39986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</dt>"; 40086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 40186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isPositionValid()) { 40286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->getDepth() == 1) 40386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dd class=\"tparam-descr-index-" 40486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << C->getIndex(0) 40586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "\">"; 40686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 40786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dd class=\"tparam-descr-index-other\">"; 40886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else 40986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dd class=\"tparam-descr-index-invalid\">"; 41086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 41186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visitNonStandaloneParagraphComment(C->getParagraph()); 41286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</dd>"; 41386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 41486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 41586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockComment( 41686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimBlockComment *C) { 41786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned NumLines = C->getNumLines(); 41886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (NumLines == 0) 41986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 42086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 42186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<pre>"; 42286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0; i != NumLines; ++i) { 42386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getText(i)); 42486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (i + 1 != NumLines) 42586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << '\n'; 42686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 42786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</pre>"; 42886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 42986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 43086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockLineComment( 43186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimBlockLineComment *C) { 43286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm_unreachable("should not see this AST node"); 43386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 43486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 43586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimLineComment( 43686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimLineComment *C) { 43786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<pre>"; 43886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithHTMLEscaping(C->getText()); 43986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</pre>"; 44086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 44186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 44286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitFullComment(const FullComment *C) { 44386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FullCommentParts Parts(C, Traits); 44486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 44586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko bool FirstParagraphIsBrief = false; 44686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Headerfile) 44786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Headerfile); 44886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Brief) 44986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Brief); 45086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else if (Parts.FirstParagraph) { 45186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<p class=\"para-brief\">"; 45286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visitNonStandaloneParagraphComment(Parts.FirstParagraph); 45386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</p>"; 45486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FirstParagraphIsBrief = true; 45586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 45686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 45786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) { 45886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const Comment *C = Parts.MiscBlocks[i]; 45986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (FirstParagraphIsBrief && C == Parts.FirstParagraph) 46086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko continue; 46186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(C); 46286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 46386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 46486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.TParams.size() != 0) { 46586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dl>"; 46686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i) 46786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.TParams[i]); 46886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</dl>"; 46986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 47086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 47186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Params.size() != 0) { 47286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<dl>"; 47386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i) 47486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Params[i]); 47586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</dl>"; 47686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 47786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 47886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Returns.size() != 0) { 47986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<div class=\"result-discussion\">"; 48086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i) 48186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Returns[i]); 48286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</div>"; 48386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 48486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 48586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result.flush(); 48686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 48786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 48886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::visitNonStandaloneParagraphComment( 48986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParagraphComment *C) { 49086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!C) 49186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 49286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 49386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 49486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko I != E; ++I) { 49586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(*I); 49686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 49786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 49886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 49986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) { 50086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) { 50186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const char C = *I; 50286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C) { 50386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '&': 50486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "&"; 50586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 50686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '<': 50786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<"; 50886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 50986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '>': 51086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << ">"; 51186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 51286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '"': 51386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << """; 51486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 51586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '\'': 51686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "'"; 51786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 51886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '/': 51986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "/"; 52086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 52186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko default: 52286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << C; 52386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 52486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 52586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 52686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 52786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 52886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkonamespace { 52986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkoclass CommentASTToXMLConverter : 53086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko public ConstCommentVisitor<CommentASTToXMLConverter> { 53186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkopublic: 53286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// \param Str accumulator for XML. 53386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko CommentASTToXMLConverter(const FullComment *FC, 53486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVectorImpl<char> &Str, 53586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandTraits &Traits, 53686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const SourceManager &SM, 53786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SimpleFormatContext &SFC, 53886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned FUID) : 53986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FC(FC), Result(Str), Traits(Traits), SM(SM), 54086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FormatRewriterContext(SFC), 54186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FormatInMemoryUniqueId(FUID) { } 54286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 54386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Inline content. 54486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitTextComment(const TextComment *C); 54586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitInlineCommandComment(const InlineCommandComment *C); 54686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitHTMLStartTagComment(const HTMLStartTagComment *C); 54786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitHTMLEndTagComment(const HTMLEndTagComment *C); 54886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 54986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Block content. 55086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitParagraphComment(const ParagraphComment *C); 55186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 55286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void appendParagraphCommentWithKind(const ParagraphComment *C, 55386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef Kind); 55486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 55586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitBlockCommandComment(const BlockCommandComment *C); 55686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitParamCommandComment(const ParamCommandComment *C); 55786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitTParamCommandComment(const TParamCommandComment *C); 55886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitVerbatimBlockComment(const VerbatimBlockComment *C); 55986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); 56086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitVerbatimLineComment(const VerbatimLineComment *C); 56186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 56286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void visitFullComment(const FullComment *C); 56386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 56486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Helpers. 56586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void appendToResultWithXMLEscaping(StringRef S); 5666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void appendToResultWithCDATAEscaping(StringRef S); 56786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 56886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko void formatTextOfDeclaration(const DeclInfo *DI, 56986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallString<128> &Declaration); 57086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 57186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkoprivate: 57286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const FullComment *FC; 57386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 57486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /// Output stream for XML. 57586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm::raw_svector_ostream Result; 57686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 57786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const CommandTraits &Traits; 57886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const SourceManager &SM; 57986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SimpleFormatContext &FormatRewriterContext; 58086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned FormatInMemoryUniqueId; 58186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko}; 58286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 58386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid getSourceTextOfDeclaration(const DeclInfo *ThisDecl, 58486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVectorImpl<char> &Str) { 58586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko ASTContext &Context = ThisDecl->CurrentDecl->getASTContext(); 58686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const LangOptions &LangOpts = Context.getLangOpts(); 58786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm::raw_svector_ostream OS(Str); 58886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko PrintingPolicy PPolicy(LangOpts); 58986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko PPolicy.PolishForDeclaration = true; 59086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko PPolicy.TerseOutput = true; 59186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko ThisDecl->CurrentDecl->print(OS, PPolicy, 59286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko /*Indentation*/0, /*PrintInstantiation*/false); 59386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 59486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 59586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::formatTextOfDeclaration( 59686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const DeclInfo *DI, SmallString<128> &Declaration) { 59786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // FIXME. formatting API expects null terminated input string. 59886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // There might be more efficient way of doing this. 59986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko std::string StringDecl = Declaration.str(); 60086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 60186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Formatter specific code. 60286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Form a unique in memory buffer name. 60386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallString<128> filename; 60486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko filename += "xmldecl"; 60586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko filename += llvm::utostr(FormatInMemoryUniqueId); 60686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko filename += ".xd"; 60786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FileID ID = FormatRewriterContext.createInMemoryFile(filename, StringDecl); 60886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SourceLocation Start = FormatRewriterContext.Sources.getLocForStartOfFile(ID) 60986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko .getLocWithOffset(0); 61086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned Length = Declaration.size(); 61186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 61286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko std::vector<CharSourceRange> Ranges( 61386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 1, CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length))); 61486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko ASTContext &Context = DI->CurrentDecl->getASTContext(); 61586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const LangOptions &LangOpts = Context.getLangOpts(); 61686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Lexer Lex(ID, FormatRewriterContext.Sources.getBuffer(ID), 61786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FormatRewriterContext.Sources, LangOpts); 61886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko tooling::Replacements Replace = reformat( 61986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko format::getLLVMStyle(), Lex, FormatRewriterContext.Sources, Ranges); 62086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko applyAllReplacements(Replace, FormatRewriterContext.Rewrite); 62186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Declaration = FormatRewriterContext.getRewrittenText(ID); 62286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 62386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 62486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} // end unnamed namespace 62586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 62686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitTextComment(const TextComment *C) { 62786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(C->getText()); 62886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 62986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 63086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitInlineCommandComment( 63186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const InlineCommandComment *C) { 63286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Nothing to render if no arguments supplied. 63386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->getNumArgs() == 0) 63486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 63586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 63686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Nothing to render if argument is empty. 63786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef Arg0 = C->getArgText(0); 63886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Arg0.empty()) 63986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 64086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 64186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C->getRenderKind()) { 64286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderNormal: 64386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) { 64486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(C->getArgText(i)); 64586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " "; 64686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 64786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 64886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderBold: 64986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko assert(C->getNumArgs() == 1); 65086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<bold>"; 65186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(Arg0); 65286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</bold>"; 65386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 65486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderMonospaced: 65586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko assert(C->getNumArgs() == 1); 65686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<monospaced>"; 65786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(Arg0); 65886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</monospaced>"; 65986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 66086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case InlineCommandComment::RenderEmphasized: 66186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko assert(C->getNumArgs() == 1); 66286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<emphasized>"; 66386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(Arg0); 66486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</emphasized>"; 66586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 66686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 66786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 66886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 66986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitHTMLStartTagComment( 67086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const HTMLStartTagComment *C) { 6716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "<rawHTML"; 6726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (C->isMalformed()) 6736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << " isMalformed=\"1\""; 6746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << ">"; 6756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines { 6766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallString<32> Tag; 6776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines { 6786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::raw_svector_ostream TagOS(Tag); 6796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printHTMLStartTagComment(C, TagOS); 6806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines appendToResultWithCDATAEscaping(Tag); 6826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "</rawHTML>"; 68486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 68586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 68686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid 68786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri GribenkoCommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 6886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "<rawHTML"; 6896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (C->isMalformed()) 6906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << " isMalformed=\"1\""; 6916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "></" << C->getTagName() << "></rawHTML>"; 69286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 69386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 69486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid 69586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri GribenkoCommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) { 69686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendParagraphCommentWithKind(C, StringRef()); 69786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 69886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 69986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::appendParagraphCommentWithKind( 70086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParagraphComment *C, 70186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef ParagraphKind) { 70286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isWhitespace()) 70386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 70486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 70586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (ParagraphKind.empty()) 70686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Para>"; 70786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 70886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Para kind=\"" << ParagraphKind << "\">"; 70986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 71086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 71186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko I != E; ++I) { 71286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(*I); 71386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 71486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Para>"; 71586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 71686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 71786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitBlockCommandComment( 71886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const BlockCommandComment *C) { 71986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef ParagraphKind; 72086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 72186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C->getCommandID()) { 72286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_attention: 72386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_author: 72486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_authors: 72586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_bug: 72686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_copyright: 72786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_date: 72886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_invariant: 72986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_note: 73086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_post: 73186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_pre: 73286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_remark: 73386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_remarks: 73486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_sa: 73586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_see: 73686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_since: 73786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_todo: 73886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_version: 73986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_warning: 74086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko ParagraphKind = C->getCommandName(Traits); 74186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko default: 74286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 74386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 74486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 74586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind); 74686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 74786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 74886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitParamCommandComment( 74986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ParamCommandComment *C) { 75086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Parameter><Name>"; 75186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(C->isParamIndexValid() 75286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko ? C->getParamName(FC) 75386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko : C->getParamNameAsWritten()); 75486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Name>"; 75586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 75686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isParamIndexValid()) { 75786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isVarArgParam()) 75886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<IsVarArg />"; 75986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else 76086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Index>" << C->getParamIndex() << "</Index>"; 76186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 76286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 76386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">"; 76486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C->getDirection()) { 76586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case ParamCommandComment::In: 76686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "in"; 76786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 76886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case ParamCommandComment::Out: 76986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "out"; 77086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 77186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case ParamCommandComment::InOut: 77286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "in,out"; 77386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 77486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 77586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Direction><Discussion>"; 77686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(C->getParagraph()); 77786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Discussion></Parameter>"; 77886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 77986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 78086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitTParamCommandComment( 78186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const TParamCommandComment *C) { 78286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Parameter><Name>"; 78386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(C->isPositionValid() ? C->getParamName(FC) 78486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko : C->getParamNameAsWritten()); 78586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Name>"; 78686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 78786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (C->isPositionValid() && C->getDepth() == 1) { 78886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Index>" << C->getIndex(0) << "</Index>"; 78986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 79086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 79186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Discussion>"; 79286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(C->getParagraph()); 79386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Discussion></Parameter>"; 79486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 79586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 79686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimBlockComment( 79786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimBlockComment *C) { 79886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned NumLines = C->getNumLines(); 79986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (NumLines == 0) 80086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko return; 80186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 80286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C->getCommandID()) { 80386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case CommandTraits::KCI_code: 80486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Verbatim xml:space=\"preserve\" kind=\"code\">"; 80586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 80686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko default: 80786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">"; 80886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 80986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 81086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0; i != NumLines; ++i) { 81186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(C->getText(i)); 81286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (i + 1 != NumLines) 81386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << '\n'; 81486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 81586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Verbatim>"; 81686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 81786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 81886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimBlockLineComment( 81986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimBlockLineComment *C) { 82086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm_unreachable("should not see this AST node"); 82186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 82286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 82386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimLineComment( 82486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const VerbatimLineComment *C) { 82586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">"; 82686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(C->getText()); 82786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Verbatim>"; 82886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 82986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 83086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::visitFullComment(const FullComment *C) { 83186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FullCommentParts Parts(C, Traits); 83286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 83386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const DeclInfo *DI = C->getDeclInfo(); 83486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef RootEndTag; 83586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (DI) { 83686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (DI->getKind()) { 83786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::OtherKind: 83886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Other>"; 83986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Other"; 84086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 84186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::FunctionKind: 84286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Function>"; 84386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Function"; 84486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (DI->TemplateKind) { 84586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::NotTemplate: 84686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 84786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::Template: 84886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " templateKind=\"template\""; 84986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 85086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::TemplateSpecialization: 85186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " templateKind=\"specialization\""; 85286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 85386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::TemplatePartialSpecialization: 85486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko llvm_unreachable("partial specializations of functions " 85586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko "are not allowed in C++"); 85686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 85786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (DI->IsInstanceMethod) 85886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " isInstanceMethod=\"1\""; 85986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (DI->IsClassMethod) 86086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " isClassMethod=\"1\""; 86186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 86286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::ClassKind: 86386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Class>"; 86486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Class"; 86586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (DI->TemplateKind) { 86686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::NotTemplate: 86786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 86886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::Template: 86986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " templateKind=\"template\""; 87086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 87186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::TemplateSpecialization: 87286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " templateKind=\"specialization\""; 87386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 87486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::TemplatePartialSpecialization: 87586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " templateKind=\"partialSpecialization\""; 87686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 87786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 87886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 87986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::VariableKind: 88086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Variable>"; 88186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Variable"; 88286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 88386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::NamespaceKind: 88486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Namespace>"; 88586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Namespace"; 88686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 88786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::TypedefKind: 88886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Typedef>"; 88986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Typedef"; 89086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 89186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case DeclInfo::EnumKind: 89286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Enum>"; 89386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Enum"; 89486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 89586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 89686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 89786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko { 89886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Print line and column number. 89986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SourceLocation Loc = DI->CurrentDecl->getLocation(); 90086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); 90186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FileID FID = LocInfo.first; 90286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko unsigned FileOffset = LocInfo.second; 90386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 90486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!FID.isInvalid()) { 90586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (const FileEntry *FE = SM.getFileEntryForID(FID)) { 90686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " file=\""; 90786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(FE->getName()); 90886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "\""; 90986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 91086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " line=\"" << SM.getLineNumber(FID, FileOffset) 91186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "\" column=\"" << SM.getColumnNumber(FID, FileOffset) 91286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "\""; 91386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 91486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 91586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 91686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Finish the root tag. 91786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << ">"; 91886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 91986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko bool FoundName = false; 92086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) { 92186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (DeclarationName DeclName = ND->getDeclName()) { 92286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Name>"; 92386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko std::string Name = DeclName.getAsString(); 92486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(Name); 92586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FoundName = true; 92686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Name>"; 92786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 92886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 92986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!FoundName) 93086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Name><anonymous></Name>"; 93186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 93286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko { 93386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Print USR. 93486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallString<128> USR; 93586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko generateUSRForDecl(DI->CommentDecl, USR); 93686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!USR.empty()) { 93786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<USR>"; 93886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(USR); 93986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</USR>"; 94086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 94186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 94286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else { 94386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // No DeclInfo -- just emit some root tag and name tag. 94486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko RootEndTag = "</Other>"; 94586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Other><Name>unknown</Name>"; 94686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 94786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 94886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Headerfile) { 94986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Headerfile>"; 95086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Headerfile); 95186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Headerfile>"; 95286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 95386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 95486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko { 95586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // Pretty-print the declaration. 95686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Declaration>"; 95786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallString<128> Declaration; 95886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko getSourceTextOfDeclaration(DI, Declaration); 95986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko formatTextOfDeclaration(DI, Declaration); 96086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(Declaration); 96186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Declaration>"; 96286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 96386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 96486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko bool FirstParagraphIsBrief = false; 96586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Brief) { 96686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Abstract>"; 96786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Brief); 96886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Abstract>"; 96986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } else if (Parts.FirstParagraph) { 97086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Abstract>"; 97186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.FirstParagraph); 97286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Abstract>"; 97386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FirstParagraphIsBrief = true; 97486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 97586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 97686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.TParams.size() != 0) { 97786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<TemplateParameters>"; 97886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i) 97986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.TParams[i]); 98086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</TemplateParameters>"; 98186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 98286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 98386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Params.size() != 0) { 98486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Parameters>"; 98586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i) 98686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Params[i]); 98786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Parameters>"; 98886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 98986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 99086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Exceptions.size() != 0) { 99186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Exceptions>"; 99286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.Exceptions.size(); i != e; ++i) 99386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Exceptions[i]); 99486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Exceptions>"; 99586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 99686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 99786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Parts.Returns.size() != 0) { 99886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<ResultDiscussion>"; 99986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i) 100086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(Parts.Returns[i]); 100186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</ResultDiscussion>"; 100286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 100386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 100486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (DI->CommentDecl->hasAttrs()) { 100586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const AttrVec &Attrs = DI->CommentDecl->getAttrs(); 100686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Attrs.size(); i != e; i++) { 100786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]); 100886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!AA) { 100986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (const DeprecatedAttr *DA = dyn_cast<DeprecatedAttr>(Attrs[i])) { 101086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (DA->getMessage().empty()) 101186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Deprecated/>"; 101286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else { 101386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Deprecated>"; 101486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(DA->getMessage()); 101586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Deprecated>"; 101686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 101786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 101886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else if (const UnavailableAttr *UA = dyn_cast<UnavailableAttr>(Attrs[i])) { 101986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (UA->getMessage().empty()) 102086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Unavailable/>"; 102186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko else { 102286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Unavailable>"; 102386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(UA->getMessage()); 102486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Unavailable>"; 102586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 102686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 102786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko continue; 102886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 102986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 103086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko // 'availability' attribute. 103186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Availability"; 103286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef Distribution; 103386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (AA->getPlatform()) { 103486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Distribution = AvailabilityAttr::getPrettyPlatformName( 103586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko AA->getPlatform()->getName()); 103686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (Distribution.empty()) 103786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Distribution = AA->getPlatform()->getName(); 103886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 103986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << " distribution=\"" << Distribution << "\">"; 104086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko VersionTuple IntroducedInVersion = AA->getIntroduced(); 104186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!IntroducedInVersion.empty()) { 104286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<IntroducedInVersion>" 104386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << IntroducedInVersion.getAsString() 104486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "</IntroducedInVersion>"; 104586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 104686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko VersionTuple DeprecatedInVersion = AA->getDeprecated(); 104786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!DeprecatedInVersion.empty()) { 104886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<DeprecatedInVersion>" 104986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << DeprecatedInVersion.getAsString() 105086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "</DeprecatedInVersion>"; 105186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 105286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko VersionTuple RemovedAfterVersion = AA->getObsoleted(); 105386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!RemovedAfterVersion.empty()) { 105486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<RemovedAfterVersion>" 105586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << RemovedAfterVersion.getAsString() 105686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko << "</RemovedAfterVersion>"; 105786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 105886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StringRef DeprecationSummary = AA->getMessage(); 105986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!DeprecationSummary.empty()) { 106086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<DeprecationSummary>"; 106186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko appendToResultWithXMLEscaping(DeprecationSummary); 106286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</DeprecationSummary>"; 106386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 106486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (AA->getUnavailable()) 106586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Unavailable/>"; 106686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Availability>"; 106786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 106886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 106986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 107086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko { 107186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko bool StartTagEmitted = false; 107286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) { 107386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const Comment *C = Parts.MiscBlocks[i]; 107486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (FirstParagraphIsBrief && C == Parts.FirstParagraph) 107586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko continue; 107686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (!StartTagEmitted) { 107786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<Discussion>"; 107886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko StartTagEmitted = true; 107986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 108086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko visit(C); 108186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 108286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko if (StartTagEmitted) 108386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "</Discussion>"; 108486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 108586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 108686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << RootEndTag; 108786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 108886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result.flush(); 108986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 109086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 109186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) { 109286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) { 109386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const char C = *I; 109486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko switch (C) { 109586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '&': 109686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "&"; 109786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 109886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '<': 109986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "<"; 110086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 110186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '>': 110286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << ">"; 110386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 110486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '"': 110586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << """; 110686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 110786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko case '\'': 110886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << "'"; 110986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 111086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko default: 111186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Result << C; 111286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko break; 111386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 111486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 111586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 111686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 11176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid CommentASTToXMLConverter::appendToResultWithCDATAEscaping(StringRef S) { 11186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (S.empty()) 11196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 11206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 11216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "<![CDATA["; 11226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines while (!S.empty()) { 11236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines size_t Pos = S.find("]]>"); 11246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Pos == 0) { 11256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "]]]]><![CDATA[>"; 11266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S = S.drop_front(3); 11276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 11286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 11296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Pos == StringRef::npos) 11306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Pos = S.size(); 11316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 11326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << S.substr(0, Pos); 11336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 11346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S = S.drop_front(Pos); 11356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 11366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result << "]]>"; 11376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 11386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 11396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCommentToXMLConverter::CommentToXMLConverter() : FormatInMemoryUniqueId(0) {} 11406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCommentToXMLConverter::~CommentToXMLConverter() {} 11416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 114286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentToXMLConverter::convertCommentToHTML(const FullComment *FC, 114386cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVectorImpl<char> &HTML, 114486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ASTContext &Context) { 114586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko CommentASTToHTMLConverter Converter(FC, HTML, 114686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Context.getCommentCommandTraits()); 114786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Converter.visit(FC); 114886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 114986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 115086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentToXMLConverter::convertHTMLTagNodeToText( 115186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const comments::HTMLTagComment *HTC, SmallVectorImpl<char> &Text, 115286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ASTContext &Context) { 11536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CommentASTToHTMLConverter Converter(nullptr, Text, 115486cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Context.getCommentCommandTraits()); 115586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Converter.visit(HTC); 115686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 115786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 115886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenkovoid CommentToXMLConverter::convertCommentToXML(const FullComment *FC, 115986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko SmallVectorImpl<char> &XML, 116086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko const ASTContext &Context) { 11616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!FormatContext || (FormatInMemoryUniqueId % 1000) == 0) { 11626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Create a new format context, or re-create it after some number of 11636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // iterations, so the buffers don't grow too large. 11646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FormatContext.reset(new SimpleFormatContext(Context.getLangOpts())); 116586cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko } 116686cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 116786cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(), 116886cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Context.getSourceManager(), *FormatContext, 116986cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko FormatInMemoryUniqueId++); 117086cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko Converter.visit(FC); 117186cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko} 117286cfda2fcccc84e92fb7f27e85b58312440ca8deDmitri Gribenko 1173