Comment.cpp revision bafe46fe35ff58cc10487ba8bdcbcccd6d3319e7
1b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o//===--- Comment.cpp - Comment AST node implementation --------------------===// 2b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o// 3b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o// The LLVM Compiler Infrastructure 4b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o// 5b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o// This file is distributed under the University of Illinois Open Source 6b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o// License. See LICENSE.TXT for details. 7b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o// 8b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o//===----------------------------------------------------------------------===// 9b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 10b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/ASTContext.h" 11b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/Comment.h" 12b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/Decl.h" 13b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/DeclObjC.h" 14b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/DeclTemplate.h" 15b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/Basic/CharInfo.h" 16b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "llvm/Support/ErrorHandling.h" 17b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "llvm/Support/raw_ostream.h" 18b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 19b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'onamespace clang { 20b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'onamespace comments { 21b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 22b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oconst char *Comment::getCommentKindName() const { 23b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o switch (getCommentKind()) { 24b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case NoCommentKind: return "NoCommentKind"; 25b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define ABSTRACT_COMMENT(COMMENT) 26b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define COMMENT(CLASS, PARENT) \ 27b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case CLASS##Kind: \ 28b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return #CLASS; 29b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/CommentNodes.inc" 30b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef COMMENT 31b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef ABSTRACT_COMMENT 32b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 33b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o llvm_unreachable("Unknown comment kind!"); 34b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 35b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 36b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'onamespace { 37b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostruct good {}; 38b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostruct bad {}; 39b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 40b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'otemplate <typename T> 41b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ogood implements_child_begin_end(Comment::child_iterator (T::*)() const) { 42b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return good(); 43b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 44b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 45b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oLLVM_ATTRIBUTE_UNUSED 46b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostatic inline bad implements_child_begin_end( 47b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Comment::child_iterator (Comment::*)() const) { 48b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return bad(); 49b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 50b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 51b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define ASSERT_IMPLEMENTS_child_begin(function) \ 52b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o (void) good(implements_child_begin_end(function)) 53b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 54b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oLLVM_ATTRIBUTE_UNUSED 55b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ostatic inline void CheckCommentASTNodes() { 56b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define ABSTRACT_COMMENT(COMMENT) 57b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define COMMENT(CLASS, PARENT) \ 58b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ASSERT_IMPLEMENTS_child_begin(&CLASS::child_begin); \ 59b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ASSERT_IMPLEMENTS_child_begin(&CLASS::child_end); 60b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/CommentNodes.inc" 61b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef COMMENT 62b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef ABSTRACT_COMMENT 63b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 64b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 65b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef ASSERT_IMPLEMENTS_child_begin 66b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 67b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} // end unnamed namespace 68b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 69b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oComment::child_iterator Comment::child_begin() const { 70b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o switch (getCommentKind()) { 71b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case NoCommentKind: llvm_unreachable("comment without a kind"); 72b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define ABSTRACT_COMMENT(COMMENT) 73b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define COMMENT(CLASS, PARENT) \ 74b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case CLASS##Kind: \ 75b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return static_cast<const CLASS *>(this)->child_begin(); 76b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/CommentNodes.inc" 77b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef COMMENT 78b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef ABSTRACT_COMMENT 79b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 80b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o llvm_unreachable("Unknown comment kind!"); 81b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 82b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 83b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oComment::child_iterator Comment::child_end() const { 84b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o switch (getCommentKind()) { 85b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case NoCommentKind: llvm_unreachable("comment without a kind"); 86b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define ABSTRACT_COMMENT(COMMENT) 87b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#define COMMENT(CLASS, PARENT) \ 88b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case CLASS##Kind: \ 89b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return static_cast<const CLASS *>(this)->child_end(); 90b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#include "clang/AST/CommentNodes.inc" 91b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef COMMENT 92b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o#undef ABSTRACT_COMMENT 93b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 94b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o llvm_unreachable("Unknown comment kind!"); 95b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 96b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 97b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'obool TextComment::isWhitespaceNoCache() const { 98b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o for (StringRef::const_iterator I = Text.begin(), E = Text.end(); 99b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o I != E; ++I) { 100b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (!clang::isWhitespace(*I)) 101b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return false; 102b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 103b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return true; 104b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 105b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 106b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'obool ParagraphComment::isWhitespaceNoCache() const { 107b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) { 108b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (const TextComment *TC = dyn_cast<TextComment>(*I)) { 109b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (!TC->isWhitespace()) 110b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return false; 111b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } else 112b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return false; 113b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 114b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return true; 115b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 116b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 117b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oconst char *ParamCommandComment::getDirectionAsString(PassDirection D) { 118b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o switch (D) { 119b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case ParamCommandComment::In: 120b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return "[in]"; 121b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case ParamCommandComment::Out: 122b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return "[out]"; 123b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case ParamCommandComment::InOut: 124b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return "[in,out]"; 125b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 126b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o llvm_unreachable("unknown PassDirection"); 127b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 128b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 129b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'ovoid DeclInfo::fill() { 130b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o assert(!IsFilled); 131b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 132b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // Set defaults. 133b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = OtherKind; 134b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = NotTemplate; 135b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsObjCMethod = false; 136b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsInstanceMethod = false; 137b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsClassMethod = false; 138b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ParamVars = None; 139b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateParameters = NULL; 140b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 141b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (!CommentDecl) { 142b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // If there is no declaration, the defaults is our only guess. 143b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsFilled = true; 144b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return; 145b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 146b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o CurrentDecl = CommentDecl; 147b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 148b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Decl::Kind K = CommentDecl->getKind(); 149b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o switch (K) { 150b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o default: 151b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // Defaults are should be good for declarations we don't handle explicitly. 152b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 153b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Function: 154b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::CXXMethod: 155b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::CXXConstructor: 156b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::CXXDestructor: 157b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::CXXConversion: { 158b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const FunctionDecl *FD = cast<FunctionDecl>(CommentDecl); 159b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = FunctionKind; 160b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(), 161b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o FD->getNumParams()); 162b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ResultType = FD->getResultType(); 163b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o unsigned NumLists = FD->getNumTemplateParameterLists(); 164b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (NumLists != 0) { 165b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = TemplateSpecialization; 166b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateParameters = 167b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o FD->getTemplateParameterList(NumLists - 1); 168b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 169b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 170b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (K == Decl::CXXMethod || K == Decl::CXXConstructor || 171b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o K == Decl::CXXDestructor || K == Decl::CXXConversion) { 172b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const CXXMethodDecl *MD = cast<CXXMethodDecl>(CommentDecl); 173b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsInstanceMethod = MD->isInstance(); 174b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsClassMethod = !IsInstanceMethod; 175b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 176b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 177b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 178b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::ObjCMethod: { 179b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(CommentDecl); 180b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = FunctionKind; 181b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(), 182b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o MD->param_size()); 183b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ResultType = MD->getResultType(); 184b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsObjCMethod = true; 185b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsInstanceMethod = MD->isInstanceMethod(); 186b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsClassMethod = !IsInstanceMethod; 187b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 188b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 189b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::FunctionTemplate: { 190b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(CommentDecl); 191b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = FunctionKind; 192b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = Template; 193b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const FunctionDecl *FD = FTD->getTemplatedDecl(); 194b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(), 195b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o FD->getNumParams()); 196b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ResultType = FD->getResultType(); 197b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateParameters = FTD->getTemplateParameters(); 198b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 199b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 200b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::ClassTemplate: { 201b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(CommentDecl); 202b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = ClassKind; 203b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = Template; 204b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateParameters = CTD->getTemplateParameters(); 205b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 206b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 207b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::ClassTemplatePartialSpecialization: { 208b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const ClassTemplatePartialSpecializationDecl *CTPSD = 209b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o cast<ClassTemplatePartialSpecializationDecl>(CommentDecl); 210b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = ClassKind; 211b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = TemplatePartialSpecialization; 212b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateParameters = CTPSD->getTemplateParameters(); 213b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 214b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 215b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::ClassTemplateSpecialization: 216b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = ClassKind; 217b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = TemplateSpecialization; 218b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 219b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Record: 220b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::CXXRecord: 221b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = ClassKind; 222b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 223b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Var: 224b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Field: 225b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::EnumConstant: 226b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::ObjCIvar: 227b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::ObjCAtDefsField: 228b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = VariableKind; 229b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 230b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Namespace: 231b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = NamespaceKind; 232b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 233b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Typedef: { 234b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = TypedefKind; 235b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // If this is a typedef to something we consider a function, extract 236b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // arguments and return type. 237b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const TypedefDecl *TD = cast<TypedefDecl>(CommentDecl); 238b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); 239b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (!TSI) 240b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 241b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc(); 242b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o while (true) { 243b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL = TL.IgnoreParens(); 244b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // Look through qualified types. 245b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { 246b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL = QualifiedTL.getUnqualifiedLoc(); 247b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o continue; 248b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 249b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // Look through pointer types. 250b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (PointerTypeLoc PointerTL = TL.getAs<PointerTypeLoc>()) { 251b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL = PointerTL.getPointeeLoc().getUnqualifiedLoc(); 252b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o continue; 253b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 254b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (BlockPointerTypeLoc BlockPointerTL = 255b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL.getAs<BlockPointerTypeLoc>()) { 256b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); 257b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o continue; 258b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 259b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (MemberPointerTypeLoc MemberPointerTL = 260b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL.getAs<MemberPointerTypeLoc>()) { 261b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc(); 262b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o continue; 263b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 264b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o // Is this a typedef for a function type? 265b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { 266b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = FunctionKind; 267b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ArrayRef<ParmVarDecl *> Params = FTL.getParams(); 268b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(), 269b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Params.size()); 270b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o ResultType = FTL.getResultLoc().getType(); 271b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 272b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 273b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 274b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 275b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 276b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 277b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::TypeAlias: 278b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = TypedefKind; 279b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 280b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::TypeAliasTemplate: { 281b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(CommentDecl); 282b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = TypedefKind; 283b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateKind = Template; 284b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TemplateParameters = TAT->getTemplateParameters(); 285b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 286b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 287b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o case Decl::Enum: 288b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o Kind = EnumKind; 289b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o break; 290b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 291b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 292b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o IsFilled = true; 293b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 294b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 295b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oStringRef ParamCommandComment::getParamName(const FullComment *FC) const { 296b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o assert(isParamIndexValid()); 297b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (isVarArgParam()) 298b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return "..."; 299b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return FC->getDeclInfo()->ParamVars[getParamIndex()]->getName(); 300b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 301b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 302b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'oStringRef TParamCommandComment::getParamName(const FullComment *FC) const { 303b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o assert(isPositionValid()); 304b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const TemplateParameterList *TPL = FC->getDeclInfo()->TemplateParameters; 305b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o for (unsigned i = 0, e = getDepth(); i != e; ++i) { 306b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (i == e-1) 307b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return TPL->getParam(getIndex(i))->getName(); 308b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o const NamedDecl *Param = TPL->getParam(getIndex(i)); 309b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o if (const TemplateTemplateParmDecl *TTP = 310b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o dyn_cast<TemplateTemplateParmDecl>(Param)) 311b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o TPL = TTP->getTemplateParameters(); 312b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o } 313b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o return ""; 314b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} 315b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 316b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} // end namespace comments 317b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o} // end namespace clang 318b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o 319b0cacab066000b940551d59aad3e4553d4bad268Theodore Ts'o