CXComment.cpp revision 4d0ddecbe7dbbfeb89e428ed6e19c3cf12325087
16d47bae50b63d47441321d6a367c37625e38d390Chris Lattner//===- CXComment.cpp - libclang APIs for manipulating CXComments ----------===// 2113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkov// 3e2fab734ade8a2e3e8679c11cac7236b920d567bJohn Criswell// The LLVM Compiler Infrastructure 4e2fab734ade8a2e3e8679c11cac7236b920d567bJohn Criswell// 551167848265a0fa006c32557caa4aeb3f482f45eChris Lattner// This file is distributed under the University of Illinois Open Source 651167848265a0fa006c32557caa4aeb3f482f45eChris Lattner// License. See LICENSE.TXT for details. 7113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkov// 8e2fab734ade8a2e3e8679c11cac7236b920d567bJohn Criswell//===----------------------------------------------------------------------===// 96d47bae50b63d47441321d6a367c37625e38d390Chris Lattner// 10698e9ce56864223fe73b1ebefaf19845daf0c3d7Chris Lattner// This file defines all libclang APIs related to walking comment AST. 110a26891ce9b6de840c087d73c04324729c3d1a8bMike Stump// 12e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi//===----------------------------------------------------------------------===// 13e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi 140a26891ce9b6de840c087d73c04324729c3d1a8bMike Stump#include "clang-c/Index.h" 15e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "CXComment.h" 16e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "CXCursor.h" 17e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "CXString.h" 18e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "clang/AST/Decl.h" 19e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "clang/Index/CommentToXML.h" 20e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "llvm/ADT/StringExtras.h" 210a26891ce9b6de840c087d73c04324729c3d1a8bMike Stump#include "llvm/ADT/StringSwitch.h" 22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Support/ErrorHandling.h" 23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <climits> 24cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 25ebccf0891a2f6b75c2ac8de97557ca0cf5ad61c3Stephen Wilsonusing namespace clang; 26113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkovusing namespace clang::comments; 27113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkovusing namespace clang::cxcomment; 2836a987eed00886f6508668942df140fa053256caReid Spencer 291cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachextern "C" { 30dd5d86d992eb129ecd0bb013d2db2d6a0e8d2605Chandler Carruth 31b6adb4216cbc466cae62eff75ec9b2b552ecf866Chandler Carruthenum CXCommentKind clang_Comment_getKind(CXComment CXC) { 32b6adb4216cbc466cae62eff75ec9b2b552ecf866Chandler Carruth const Comment *C = getASTNode(CXC); 33b6adb4216cbc466cae62eff75ec9b2b552ecf866Chandler Carruth if (!C) 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CXComment_Null; 35041b3f835682588cb63df7e609d726369dd6b7d3Bill Wendling 36b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor switch (C->getCommentKind()) { 37b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor case Comment::NoCommentKind: 38b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor return CXComment_Null; 39b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor 40b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor case Comment::TextCommentKind: 41069429062d15a020047a3e52680822709aeb6d51Chris Lattner return CXComment_Text; 42069429062d15a020047a3e52680822709aeb6d51Chris Lattner 43069429062d15a020047a3e52680822709aeb6d51Chris Lattner case Comment::InlineCommandCommentKind: 44ebccf0891a2f6b75c2ac8de97557ca0cf5ad61c3Stephen Wilson return CXComment_InlineCommand; 45ebccf0891a2f6b75c2ac8de97557ca0cf5ad61c3Stephen Wilson 46069429062d15a020047a3e52680822709aeb6d51Chris Lattner case Comment::HTMLStartTagCommentKind: 47069429062d15a020047a3e52680822709aeb6d51Chris Lattner return CXComment_HTMLStartTag; 4823e6d2b88a34e4a7aea9120446683c598da470d7Chris Lattner 4923e6d2b88a34e4a7aea9120446683c598da470d7Chris Lattner case Comment::HTMLEndTagCommentKind: 50b8810a38865974ed41420ce85f21495e77990a80Daniel Dunbar return CXComment_HTMLEndTag; 51e9742d2f6c21522afda3a5c79936b9469be3e6d3Nick Lewycky 52b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi case Comment::ParagraphCommentKind: 5388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return CXComment_Paragraph; 5488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 55b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi case Comment::BlockCommandCommentKind: 5688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return CXComment_BlockCommand; 57b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi 58847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case Comment::ParamCommandCommentKind: 59b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi return CXComment_ParamCommand; 60294492b25f9a953e9210e4e1a23465e1b599fef8Anton Korobeynikov 61ac28588def0093238a28c52952c37919190873f5Reid Spencer case Comment::TParamCommandCommentKind: 62baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser return CXComment_TParamCommand; 63baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser 64baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser case Comment::VerbatimBlockCommentKind: 65b8810a38865974ed41420ce85f21495e77990a80Daniel Dunbar return CXComment_VerbatimBlockCommand; 66baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser 67f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi case Comment::VerbatimBlockLineCommentKind: 68f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi return CXComment_VerbatimBlockLine; 690ae59f4c07a85ba8455c8119534c06c78a62614aNAKAMURA Takumi 70f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi case Comment::VerbatimLineCommentKind: 71f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi return CXComment_VerbatimLine; 72f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi 73f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi case Comment::FullCommentKind: 74f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi return CXComment_FullComment; 75cf8cb6d56445823a51965f00d54517594f36e0b6Chris Lattner } 76 llvm_unreachable("unknown CommentKind"); 77} 78 79unsigned clang_Comment_getNumChildren(CXComment CXC) { 80 const Comment *C = getASTNode(CXC); 81 if (!C) 82 return 0; 83 84 return C->child_count(); 85} 86 87CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) { 88 const Comment *C = getASTNode(CXC); 89 if (!C || ChildIdx >= C->child_count()) 90 return createCXComment(NULL, NULL); 91 92 return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit); 93} 94 95unsigned clang_Comment_isWhitespace(CXComment CXC) { 96 const Comment *C = getASTNode(CXC); 97 if (!C) 98 return false; 99 100 if (const TextComment *TC = dyn_cast<TextComment>(C)) 101 return TC->isWhitespace(); 102 103 if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C)) 104 return PC->isWhitespace(); 105 106 return false; 107} 108 109unsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) { 110 const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC); 111 if (!ICC) 112 return false; 113 114 return ICC->hasTrailingNewline(); 115} 116 117CXString clang_TextComment_getText(CXComment CXC) { 118 const TextComment *TC = getASTNodeAs<TextComment>(CXC); 119 if (!TC) 120 return cxstring::createNull(); 121 122 return cxstring::createRef(TC->getText()); 123} 124 125CXString clang_InlineCommandComment_getCommandName(CXComment CXC) { 126 const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC); 127 if (!ICC) 128 return cxstring::createNull(); 129 130 const CommandTraits &Traits = getCommandTraits(CXC); 131 return cxstring::createRef(ICC->getCommandName(Traits)); 132} 133 134enum CXCommentInlineCommandRenderKind 135clang_InlineCommandComment_getRenderKind(CXComment CXC) { 136 const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC); 137 if (!ICC) 138 return CXCommentInlineCommandRenderKind_Normal; 139 140 switch (ICC->getRenderKind()) { 141 case InlineCommandComment::RenderNormal: 142 return CXCommentInlineCommandRenderKind_Normal; 143 144 case InlineCommandComment::RenderBold: 145 return CXCommentInlineCommandRenderKind_Bold; 146 147 case InlineCommandComment::RenderMonospaced: 148 return CXCommentInlineCommandRenderKind_Monospaced; 149 150 case InlineCommandComment::RenderEmphasized: 151 return CXCommentInlineCommandRenderKind_Emphasized; 152 } 153 llvm_unreachable("unknown InlineCommandComment::RenderKind"); 154} 155 156unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) { 157 const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC); 158 if (!ICC) 159 return 0; 160 161 return ICC->getNumArgs(); 162} 163 164CXString clang_InlineCommandComment_getArgText(CXComment CXC, 165 unsigned ArgIdx) { 166 const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC); 167 if (!ICC || ArgIdx >= ICC->getNumArgs()) 168 return cxstring::createNull(); 169 170 return cxstring::createRef(ICC->getArgText(ArgIdx)); 171} 172 173CXString clang_HTMLTagComment_getTagName(CXComment CXC) { 174 const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC); 175 if (!HTC) 176 return cxstring::createNull(); 177 178 return cxstring::createRef(HTC->getTagName()); 179} 180 181unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) { 182 const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC); 183 if (!HST) 184 return false; 185 186 return HST->isSelfClosing(); 187} 188 189unsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) { 190 const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC); 191 if (!HST) 192 return 0; 193 194 return HST->getNumAttrs(); 195} 196 197CXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) { 198 const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC); 199 if (!HST || AttrIdx >= HST->getNumAttrs()) 200 return cxstring::createNull(); 201 202 return cxstring::createRef(HST->getAttr(AttrIdx).Name); 203} 204 205CXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) { 206 const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC); 207 if (!HST || AttrIdx >= HST->getNumAttrs()) 208 return cxstring::createNull(); 209 210 return cxstring::createRef(HST->getAttr(AttrIdx).Value); 211} 212 213CXString clang_BlockCommandComment_getCommandName(CXComment CXC) { 214 const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC); 215 if (!BCC) 216 return cxstring::createNull(); 217 218 const CommandTraits &Traits = getCommandTraits(CXC); 219 return cxstring::createRef(BCC->getCommandName(Traits)); 220} 221 222unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) { 223 const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC); 224 if (!BCC) 225 return 0; 226 227 return BCC->getNumArgs(); 228} 229 230CXString clang_BlockCommandComment_getArgText(CXComment CXC, 231 unsigned ArgIdx) { 232 const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC); 233 if (!BCC || ArgIdx >= BCC->getNumArgs()) 234 return cxstring::createNull(); 235 236 return cxstring::createRef(BCC->getArgText(ArgIdx)); 237} 238 239CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) { 240 const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC); 241 if (!BCC) 242 return createCXComment(NULL, NULL); 243 244 return createCXComment(BCC->getParagraph(), CXC.TranslationUnit); 245} 246 247CXString clang_ParamCommandComment_getParamName(CXComment CXC) { 248 const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC); 249 if (!PCC || !PCC->hasParamName()) 250 return cxstring::createNull(); 251 252 return cxstring::createRef(PCC->getParamNameAsWritten()); 253} 254 255unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) { 256 const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC); 257 if (!PCC) 258 return false; 259 260 return PCC->isParamIndexValid(); 261} 262 263unsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) { 264 const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC); 265 if (!PCC || !PCC->isParamIndexValid() || PCC->isVarArgParam()) 266 return ParamCommandComment::InvalidParamIndex; 267 268 return PCC->getParamIndex(); 269} 270 271unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) { 272 const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC); 273 if (!PCC) 274 return false; 275 276 return PCC->isDirectionExplicit(); 277} 278 279enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection( 280 CXComment CXC) { 281 const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC); 282 if (!PCC) 283 return CXCommentParamPassDirection_In; 284 285 switch (PCC->getDirection()) { 286 case ParamCommandComment::In: 287 return CXCommentParamPassDirection_In; 288 289 case ParamCommandComment::Out: 290 return CXCommentParamPassDirection_Out; 291 292 case ParamCommandComment::InOut: 293 return CXCommentParamPassDirection_InOut; 294 } 295 llvm_unreachable("unknown ParamCommandComment::PassDirection"); 296} 297 298CXString clang_TParamCommandComment_getParamName(CXComment CXC) { 299 const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC); 300 if (!TPCC || !TPCC->hasParamName()) 301 return cxstring::createNull(); 302 303 return cxstring::createRef(TPCC->getParamNameAsWritten()); 304} 305 306unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) { 307 const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC); 308 if (!TPCC) 309 return false; 310 311 return TPCC->isPositionValid(); 312} 313 314unsigned clang_TParamCommandComment_getDepth(CXComment CXC) { 315 const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC); 316 if (!TPCC || !TPCC->isPositionValid()) 317 return 0; 318 319 return TPCC->getDepth(); 320} 321 322unsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) { 323 const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC); 324 if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth()) 325 return 0; 326 327 return TPCC->getIndex(Depth); 328} 329 330CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) { 331 const VerbatimBlockLineComment *VBL = 332 getASTNodeAs<VerbatimBlockLineComment>(CXC); 333 if (!VBL) 334 return cxstring::createNull(); 335 336 return cxstring::createRef(VBL->getText()); 337} 338 339CXString clang_VerbatimLineComment_getText(CXComment CXC) { 340 const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC); 341 if (!VLC) 342 return cxstring::createNull(); 343 344 return cxstring::createRef(VLC->getText()); 345} 346 347//===----------------------------------------------------------------------===// 348// Converting comments to XML. 349//===----------------------------------------------------------------------===// 350 351CXString clang_HTMLTagComment_getAsString(CXComment CXC) { 352 const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC); 353 if (!HTC) 354 return cxstring::createNull(); 355 356 CXTranslationUnit TU = CXC.TranslationUnit; 357 if (!TU->CommentToXML) 358 TU->CommentToXML = new clang::index::CommentToXMLConverter(); 359 360 SmallString<128> Text; 361 TU->CommentToXML->convertHTMLTagNodeToText( 362 HTC, Text, cxtu::getASTUnit(TU)->getASTContext()); 363 return cxstring::createDup(Text.str()); 364} 365 366CXString clang_FullComment_getAsHTML(CXComment CXC) { 367 const FullComment *FC = getASTNodeAs<FullComment>(CXC); 368 if (!FC) 369 return cxstring::createNull(); 370 371 CXTranslationUnit TU = CXC.TranslationUnit; 372 if (!TU->CommentToXML) 373 TU->CommentToXML = new clang::index::CommentToXMLConverter(); 374 375 SmallString<1024> HTML; 376 TU->CommentToXML 377 ->convertCommentToHTML(FC, HTML, cxtu::getASTUnit(TU)->getASTContext()); 378 return cxstring::createDup(HTML.str()); 379} 380 381CXString clang_FullComment_getAsXML(CXComment CXC) { 382 const FullComment *FC = getASTNodeAs<FullComment>(CXC); 383 if (!FC) 384 return cxstring::createNull(); 385 386 CXTranslationUnit TU = CXC.TranslationUnit; 387 if (!TU->CommentToXML) 388 TU->CommentToXML = new clang::index::CommentToXMLConverter(); 389 390 SmallString<1024> XML; 391 TU->CommentToXML 392 ->convertCommentToXML(FC, XML, cxtu::getASTUnit(TU)->getASTContext()); 393 return cxstring::createDup(XML.str()); 394} 395 396} // end extern "C" 397 398