18d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko//===--- Comment.cpp - Comment AST node implementation --------------------===// 28d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 38d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// The LLVM Compiler Infrastructure 48d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 58d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// This file is distributed under the University of Illinois Open Source 68d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// License. See LICENSE.TXT for details. 78d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 88d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko//===----------------------------------------------------------------------===// 98d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 10e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko#include "clang/AST/ASTContext.h" 118d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/Comment.h" 121ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko#include "clang/AST/Decl.h" 131ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko#include "clang/AST/DeclObjC.h" 141ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko#include "clang/AST/DeclTemplate.h" 153520868fcffb6e3405014cd47973bfa757487a40Dmitri Gribenko#include "clang/Basic/CharInfo.h" 168d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "llvm/Support/ErrorHandling.h" 17fb3643a7509dcde7fb0fb7290e4b3b42b317700cDmitri Gribenko#include "llvm/Support/raw_ostream.h" 188d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 198d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace clang { 208d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace comments { 218d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 228d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkoconst char *Comment::getCommentKindName() const { 238d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko switch (getCommentKind()) { 248d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko case NoCommentKind: return "NoCommentKind"; 258d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define ABSTRACT_COMMENT(COMMENT) 268d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define COMMENT(CLASS, PARENT) \ 278d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko case CLASS##Kind: \ 288d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return #CLASS; 298d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/CommentNodes.inc" 308d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef COMMENT 318d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef ABSTRACT_COMMENT 328d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } 338d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko llvm_unreachable("Unknown comment kind!"); 348d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 358d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 368d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace { 378d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkostruct good {}; 388d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkostruct bad {}; 398d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 408d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkotemplate <typename T> 418d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkogood implements_child_begin_end(Comment::child_iterator (T::*)() const) { 428d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return good(); 438d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 45bafe46fe35ff58cc10487ba8bdcbcccd6d3319e7Eli FriedmanLLVM_ATTRIBUTE_UNUSED 468d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkostatic inline bad implements_child_begin_end( 478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Comment::child_iterator (Comment::*)() const) { 488d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return bad(); 498d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 508d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 518d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define ASSERT_IMPLEMENTS_child_begin(function) \ 52bafe46fe35ff58cc10487ba8bdcbcccd6d3319e7Eli Friedman (void) good(implements_child_begin_end(function)) 538d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 54bafe46fe35ff58cc10487ba8bdcbcccd6d3319e7Eli FriedmanLLVM_ATTRIBUTE_UNUSED 558d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkostatic inline void CheckCommentASTNodes() { 568d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define ABSTRACT_COMMENT(COMMENT) 578d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define COMMENT(CLASS, PARENT) \ 588d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ASSERT_IMPLEMENTS_child_begin(&CLASS::child_begin); \ 598d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ASSERT_IMPLEMENTS_child_begin(&CLASS::child_end); 608d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/CommentNodes.inc" 618d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef COMMENT 628d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef ABSTRACT_COMMENT 638d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 658d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef ASSERT_IMPLEMENTS_child_begin 668d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 678d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end unnamed namespace 688d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 698d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoComment::child_iterator Comment::child_begin() const { 708d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko switch (getCommentKind()) { 718d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko case NoCommentKind: llvm_unreachable("comment without a kind"); 728d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define ABSTRACT_COMMENT(COMMENT) 738d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define COMMENT(CLASS, PARENT) \ 748d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko case CLASS##Kind: \ 758d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return static_cast<const CLASS *>(this)->child_begin(); 768d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/CommentNodes.inc" 778d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef COMMENT 788d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef ABSTRACT_COMMENT 798d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } 804d48b5c1d58c381e6e0c719701ef433b530e0e1aMatt Beaumont-Gay llvm_unreachable("Unknown comment kind!"); 818d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 828d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 838d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoComment::child_iterator Comment::child_end() const { 848d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko switch (getCommentKind()) { 858d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko case NoCommentKind: llvm_unreachable("comment without a kind"); 868d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define ABSTRACT_COMMENT(COMMENT) 878d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#define COMMENT(CLASS, PARENT) \ 888d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko case CLASS##Kind: \ 898d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return static_cast<const CLASS *>(this)->child_end(); 908d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/CommentNodes.inc" 918d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef COMMENT 928d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#undef ABSTRACT_COMMENT 938d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } 944d48b5c1d58c381e6e0c719701ef433b530e0e1aMatt Beaumont-Gay llvm_unreachable("Unknown comment kind!"); 958d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 968d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 970f7f10bd0ea08abf56c69fea9316275a1ee0e40cDmitri Gribenkobool TextComment::isWhitespaceNoCache() const { 98a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko for (StringRef::const_iterator I = Text.begin(), E = Text.end(); 99a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko I != E; ++I) { 1003520868fcffb6e3405014cd47973bfa757487a40Dmitri Gribenko if (!clang::isWhitespace(*I)) 101a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return false; 102a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 103a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return true; 104a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 105a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 1060f7f10bd0ea08abf56c69fea9316275a1ee0e40cDmitri Gribenkobool ParagraphComment::isWhitespaceNoCache() const { 107a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) { 108a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (const TextComment *TC = dyn_cast<TextComment>(*I)) { 109a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!TC->isWhitespace()) 110a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return false; 111858e69fe1305bdffb76a200c0f498685f11e65aeDmitri Gribenko } else 112858e69fe1305bdffb76a200c0f498685f11e65aeDmitri Gribenko return false; 113a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 114a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return true; 115a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 116a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 117a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkoconst char *ParamCommandComment::getDirectionAsString(PassDirection D) { 118a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko switch (D) { 119a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko case ParamCommandComment::In: 120a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return "[in]"; 121a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko case ParamCommandComment::Out: 122a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return "[out]"; 123a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko case ParamCommandComment::InOut: 124a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return "[in,out]"; 125a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 126a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko llvm_unreachable("unknown PassDirection"); 127a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 1288d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 1291ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenkovoid DeclInfo::fill() { 1301ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko assert(!IsFilled); 1311ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko 1321ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko // Set defaults. 13389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko Kind = OtherKind; 13404bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = NotTemplate; 13588815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko IsObjCMethod = false; 1361ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsInstanceMethod = false; 1371ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsClassMethod = false; 1385543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko ParamVars = None; 1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TemplateParameters = nullptr; 1401ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko 141bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian if (!CommentDecl) { 1425b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko // If there is no declaration, the defaults is our only guess. 1435b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko IsFilled = true; 1445b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko return; 1455b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 1461bfb00dabf83d8c8b95b7276b4c0ae3fd64832c8Fariborz Jahanian CurrentDecl = CommentDecl; 14788d285cc0fc4ecdbc88d1779dcd2da968aa8b191Fariborz Jahanian 148bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian Decl::Kind K = CommentDecl->getKind(); 1495b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko switch (K) { 1505b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko default: 1515b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko // Defaults are should be good for declarations we don't handle explicitly. 1525b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 1535b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::Function: 1545b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::CXXMethod: 1555b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::CXXConstructor: 1565b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::CXXDestructor: 1575b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::CXXConversion: { 158bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const FunctionDecl *FD = cast<FunctionDecl>(CommentDecl); 159af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = FunctionKind; 1601ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(), 1611ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko FD->getNumParams()); 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnType = FD->getReturnType(); 1631ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko unsigned NumLists = FD->getNumTemplateParameterLists(); 1641ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (NumLists != 0) { 16504bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = TemplateSpecialization; 1661ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko TemplateParameters = 1671ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko FD->getTemplateParameterList(NumLists - 1); 1681ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko } 1691ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko 17089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko if (K == Decl::CXXMethod || K == Decl::CXXConstructor || 17189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko K == Decl::CXXDestructor || K == Decl::CXXConversion) { 172bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const CXXMethodDecl *MD = cast<CXXMethodDecl>(CommentDecl); 1731ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsInstanceMethod = MD->isInstance(); 1741ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsClassMethod = !IsInstanceMethod; 1751ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko } 1765b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 1775b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 1785b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::ObjCMethod: { 179bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(CommentDecl); 180af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = FunctionKind; 1811ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(), 1821ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko MD->param_size()); 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnType = MD->getReturnType(); 18488815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko IsObjCMethod = true; 1851ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsInstanceMethod = MD->isInstanceMethod(); 1861ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsClassMethod = !IsInstanceMethod; 1875b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 1885b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 1895b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::FunctionTemplate: { 190bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(CommentDecl); 191af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = FunctionKind; 19204bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = Template; 1931ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko const FunctionDecl *FD = FTD->getTemplatedDecl(); 1941ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(), 1951ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko FD->getNumParams()); 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnType = FD->getReturnType(); 1971ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko TemplateParameters = FTD->getTemplateParameters(); 1985b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 1995b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 2005b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::ClassTemplate: { 201bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(CommentDecl); 202af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = ClassKind; 20304bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = Template; 2041ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko TemplateParameters = CTD->getTemplateParameters(); 2055b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 2065b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 2075b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::ClassTemplatePartialSpecialization: { 2085b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko const ClassTemplatePartialSpecializationDecl *CTPSD = 209bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian cast<ClassTemplatePartialSpecializationDecl>(CommentDecl); 210af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = ClassKind; 21104bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = TemplatePartialSpecialization; 2121ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko TemplateParameters = CTPSD->getTemplateParameters(); 2135b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 2145b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 2155b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::ClassTemplateSpecialization: 216af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = ClassKind; 21704bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = TemplateSpecialization; 2185b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 2195b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::Record: 22089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko case Decl::CXXRecord: 221af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = ClassKind; 2225b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 2235b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::Var: 2245b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::Field: 225dd7b803e6ce5b8e61cf3b14af2c57199e5e991d9Dmitri Gribenko case Decl::EnumConstant: 2265b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::ObjCIvar: 2275b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::ObjCAtDefsField: 228af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = VariableKind; 2295b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 2305b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::Namespace: 231af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = NamespaceKind; 2325b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 23370ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko case Decl::Typedef: { 23470ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko Kind = TypedefKind; 23570ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko // If this is a typedef to something we consider a function, extract 23670ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko // arguments and return type. 237bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const TypedefDecl *TD = cast<TypedefDecl>(CommentDecl); 23870ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); 23970ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko if (!TSI) 24070ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko break; 24170ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc(); 24270ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko while (true) { 24370ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko TL = TL.IgnoreParens(); 24470ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko // Look through qualified types. 24539e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { 24639e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie TL = QualifiedTL.getUnqualifiedLoc(); 24770ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko continue; 24870ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 24970ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko // Look through pointer types. 25039e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie if (PointerTypeLoc PointerTL = TL.getAs<PointerTypeLoc>()) { 25139e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie TL = PointerTL.getPointeeLoc().getUnqualifiedLoc(); 25270ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko continue; 25370ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Look through reference types. 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>()) { 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TL = ReferenceTL.getPointeeLoc().getUnqualifiedLoc(); 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Look through adjusted types. 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) { 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TL = ATL.getOriginalLoc(); 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 26439e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie if (BlockPointerTypeLoc BlockPointerTL = 26539e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie TL.getAs<BlockPointerTypeLoc>()) { 26639e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); 26770ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko continue; 26870ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 26939e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie if (MemberPointerTypeLoc MemberPointerTL = 27039e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie TL.getAs<MemberPointerTypeLoc>()) { 27139e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc(); 27270ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko continue; 27370ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>()) { 275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TL = ETL.getNamedTypeLoc(); 276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 27870ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko // Is this a typedef for a function type? 27939e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { 28070ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko Kind = FunctionKind; 28139e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie ArrayRef<ParmVarDecl *> Params = FTL.getParams(); 28270ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(), 28370ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko Params.size()); 284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnType = FTL.getReturnLoc().getType(); 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (TemplateSpecializationTypeLoc STL = 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TL.getAs<TemplateSpecializationTypeLoc>()) { 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If we have a typedef to a template specialization with exactly one 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // template argument of a function type, this looks like std::function, 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // boost::function, or other function wrapper. Treat these typedefs as 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // functions. 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (STL.getNumArgs() != 1) 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0); 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type) 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo(); 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc(); 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kind = FunctionKind; 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParmVarDecl *> Params = FTL.getParams(); 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(), 304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Params.size()); 305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnType = FTL.getReturnLoc().getType(); 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 30770ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko break; 30870ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 30970ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko break; 31070ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 31170ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko break; 31270ff1091315c60fed68d7197c637ec8c588e67a1Dmitri Gribenko } 3135b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::TypeAlias: 314af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = TypedefKind; 3155b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 3165b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko case Decl::TypeAliasTemplate: { 317bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(CommentDecl); 318af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko Kind = TypedefKind; 31904bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko TemplateKind = Template; 320967e5d7ebb775a93f9c200d19d557d18bf945f10Dmitri Gribenko TemplateParameters = TAT->getTemplateParameters(); 3215b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko break; 3221ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko } 323cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko case Decl::Enum: 324cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko Kind = EnumKind; 325cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko break; 3265b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko } 3275b32a08abe5530e9294b7b373cc70199b9e2fca4Dmitri Gribenko 3281ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko IsFilled = true; 3291ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko} 3301ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko 3318cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri GribenkoStringRef ParamCommandComment::getParamName(const FullComment *FC) const { 332262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian assert(isParamIndexValid()); 333c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (isVarArgParam()) 334c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return "..."; 335eb9c55fdfa25d97f61c04f4f06fd499d988045c0Fariborz Jahanian return FC->getDeclInfo()->ParamVars[getParamIndex()]->getName(); 336749ace614b6ea1ae11d194a60b18e1e43e1db243Fariborz Jahanian} 337749ace614b6ea1ae11d194a60b18e1e43e1db243Fariborz Jahanian 3388cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri GribenkoStringRef TParamCommandComment::getParamName(const FullComment *FC) const { 339262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian assert(isPositionValid()); 340eb9c55fdfa25d97f61c04f4f06fd499d988045c0Fariborz Jahanian const TemplateParameterList *TPL = FC->getDeclInfo()->TemplateParameters; 341262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian for (unsigned i = 0, e = getDepth(); i != e; ++i) { 342262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian if (i == e-1) 343262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian return TPL->getParam(getIndex(i))->getName(); 344262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian const NamedDecl *Param = TPL->getParam(getIndex(i)); 345262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian if (const TemplateTemplateParmDecl *TTP = 3466553c686cb419b22b4c79d05a422fb1e96f6e122Fariborz Jahanian dyn_cast<TemplateTemplateParmDecl>(Param)) 347262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian TPL = TTP->getTemplateParameters(); 3486553c686cb419b22b4c79d05a422fb1e96f6e122Fariborz Jahanian } 349262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian return ""; 3506553c686cb419b22b4c79d05a422fb1e96f6e122Fariborz Jahanian} 3518cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko 3528d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end namespace comments 3538d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end namespace clang 354af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko 355