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