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