annotate clang-tools-extra/clang-doc/Serialize.cpp @ 266:00f31e85ec16 default tip

Added tag current for changeset 31d058e83c98
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 14 Oct 2023 10:13:55 +0900
parents 1f2b6ac9f198
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===-- Serialize.cpp - ClangDoc Serializer ---------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "Serialize.h"
anatofuz
parents:
diff changeset
10 #include "BitcodeWriter.h"
anatofuz
parents:
diff changeset
11 #include "clang/AST/Comment.h"
anatofuz
parents:
diff changeset
12 #include "clang/Index/USRGeneration.h"
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
13 #include "clang/Lex/Lexer.h"
150
anatofuz
parents:
diff changeset
14 #include "llvm/ADT/Hashing.h"
anatofuz
parents:
diff changeset
15 #include "llvm/ADT/StringExtras.h"
anatofuz
parents:
diff changeset
16 #include "llvm/Support/SHA1.h"
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 using clang::comments::FullComment;
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 namespace clang {
anatofuz
parents:
diff changeset
21 namespace doc {
anatofuz
parents:
diff changeset
22 namespace serialize {
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 SymbolID hashUSR(llvm::StringRef USR) {
anatofuz
parents:
diff changeset
25 return llvm::SHA1::hash(arrayRefFromStringRef(USR));
anatofuz
parents:
diff changeset
26 }
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 template <typename T>
anatofuz
parents:
diff changeset
29 static void
anatofuz
parents:
diff changeset
30 populateParentNamespaces(llvm::SmallVector<Reference, 4> &Namespaces,
anatofuz
parents:
diff changeset
31 const T *D, bool &IsAnonymousNamespace);
anatofuz
parents:
diff changeset
32
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
33 static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
34
150
anatofuz
parents:
diff changeset
35 // A function to extract the appropriate relative path for a given info's
anatofuz
parents:
diff changeset
36 // documentation. The path returned is a composite of the parent namespaces.
anatofuz
parents:
diff changeset
37 //
anatofuz
parents:
diff changeset
38 // Example: Given the below, the directory path for class C info will be
anatofuz
parents:
diff changeset
39 // <root>/A/B
anatofuz
parents:
diff changeset
40 //
anatofuz
parents:
diff changeset
41 // namespace A {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
42 // namespace B {
150
anatofuz
parents:
diff changeset
43 //
anatofuz
parents:
diff changeset
44 // class C {};
anatofuz
parents:
diff changeset
45 //
anatofuz
parents:
diff changeset
46 // }
anatofuz
parents:
diff changeset
47 // }
anatofuz
parents:
diff changeset
48 llvm::SmallString<128>
anatofuz
parents:
diff changeset
49 getInfoRelativePath(const llvm::SmallVectorImpl<doc::Reference> &Namespaces) {
anatofuz
parents:
diff changeset
50 llvm::SmallString<128> Path;
anatofuz
parents:
diff changeset
51 for (auto R = Namespaces.rbegin(), E = Namespaces.rend(); R != E; ++R)
anatofuz
parents:
diff changeset
52 llvm::sys::path::append(Path, R->Name);
anatofuz
parents:
diff changeset
53 return Path;
anatofuz
parents:
diff changeset
54 }
anatofuz
parents:
diff changeset
55
anatofuz
parents:
diff changeset
56 llvm::SmallString<128> getInfoRelativePath(const Decl *D) {
anatofuz
parents:
diff changeset
57 llvm::SmallVector<Reference, 4> Namespaces;
anatofuz
parents:
diff changeset
58 // The third arg in populateParentNamespaces is a boolean passed by reference,
anatofuz
parents:
diff changeset
59 // its value is not relevant in here so it's not used anywhere besides the
anatofuz
parents:
diff changeset
60 // function call
anatofuz
parents:
diff changeset
61 bool B = true;
anatofuz
parents:
diff changeset
62 populateParentNamespaces(Namespaces, D, B);
anatofuz
parents:
diff changeset
63 return getInfoRelativePath(Namespaces);
anatofuz
parents:
diff changeset
64 }
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 class ClangDocCommentVisitor
anatofuz
parents:
diff changeset
67 : public ConstCommentVisitor<ClangDocCommentVisitor> {
anatofuz
parents:
diff changeset
68 public:
anatofuz
parents:
diff changeset
69 ClangDocCommentVisitor(CommentInfo &CI) : CurrentCI(CI) {}
anatofuz
parents:
diff changeset
70
anatofuz
parents:
diff changeset
71 void parseComment(const comments::Comment *C);
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 void visitTextComment(const TextComment *C);
anatofuz
parents:
diff changeset
74 void visitInlineCommandComment(const InlineCommandComment *C);
anatofuz
parents:
diff changeset
75 void visitHTMLStartTagComment(const HTMLStartTagComment *C);
anatofuz
parents:
diff changeset
76 void visitHTMLEndTagComment(const HTMLEndTagComment *C);
anatofuz
parents:
diff changeset
77 void visitBlockCommandComment(const BlockCommandComment *C);
anatofuz
parents:
diff changeset
78 void visitParamCommandComment(const ParamCommandComment *C);
anatofuz
parents:
diff changeset
79 void visitTParamCommandComment(const TParamCommandComment *C);
anatofuz
parents:
diff changeset
80 void visitVerbatimBlockComment(const VerbatimBlockComment *C);
anatofuz
parents:
diff changeset
81 void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
anatofuz
parents:
diff changeset
82 void visitVerbatimLineComment(const VerbatimLineComment *C);
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 private:
anatofuz
parents:
diff changeset
85 std::string getCommandName(unsigned CommandID) const;
anatofuz
parents:
diff changeset
86 bool isWhitespaceOnly(StringRef S) const;
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 CommentInfo &CurrentCI;
anatofuz
parents:
diff changeset
89 };
anatofuz
parents:
diff changeset
90
anatofuz
parents:
diff changeset
91 void ClangDocCommentVisitor::parseComment(const comments::Comment *C) {
anatofuz
parents:
diff changeset
92 CurrentCI.Kind = C->getCommentKindName();
anatofuz
parents:
diff changeset
93 ConstCommentVisitor<ClangDocCommentVisitor>::visit(C);
anatofuz
parents:
diff changeset
94 for (comments::Comment *Child :
anatofuz
parents:
diff changeset
95 llvm::make_range(C->child_begin(), C->child_end())) {
anatofuz
parents:
diff changeset
96 CurrentCI.Children.emplace_back(std::make_unique<CommentInfo>());
anatofuz
parents:
diff changeset
97 ClangDocCommentVisitor Visitor(*CurrentCI.Children.back());
anatofuz
parents:
diff changeset
98 Visitor.parseComment(Child);
anatofuz
parents:
diff changeset
99 }
anatofuz
parents:
diff changeset
100 }
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 void ClangDocCommentVisitor::visitTextComment(const TextComment *C) {
anatofuz
parents:
diff changeset
103 if (!isWhitespaceOnly(C->getText()))
anatofuz
parents:
diff changeset
104 CurrentCI.Text = C->getText();
anatofuz
parents:
diff changeset
105 }
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 void ClangDocCommentVisitor::visitInlineCommandComment(
anatofuz
parents:
diff changeset
108 const InlineCommandComment *C) {
anatofuz
parents:
diff changeset
109 CurrentCI.Name = getCommandName(C->getCommandID());
anatofuz
parents:
diff changeset
110 for (unsigned I = 0, E = C->getNumArgs(); I != E; ++I)
anatofuz
parents:
diff changeset
111 CurrentCI.Args.push_back(C->getArgText(I));
anatofuz
parents:
diff changeset
112 }
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 void ClangDocCommentVisitor::visitHTMLStartTagComment(
anatofuz
parents:
diff changeset
115 const HTMLStartTagComment *C) {
anatofuz
parents:
diff changeset
116 CurrentCI.Name = C->getTagName();
anatofuz
parents:
diff changeset
117 CurrentCI.SelfClosing = C->isSelfClosing();
anatofuz
parents:
diff changeset
118 for (unsigned I = 0, E = C->getNumAttrs(); I < E; ++I) {
anatofuz
parents:
diff changeset
119 const HTMLStartTagComment::Attribute &Attr = C->getAttr(I);
anatofuz
parents:
diff changeset
120 CurrentCI.AttrKeys.push_back(Attr.Name);
anatofuz
parents:
diff changeset
121 CurrentCI.AttrValues.push_back(Attr.Value);
anatofuz
parents:
diff changeset
122 }
anatofuz
parents:
diff changeset
123 }
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 void ClangDocCommentVisitor::visitHTMLEndTagComment(
anatofuz
parents:
diff changeset
126 const HTMLEndTagComment *C) {
anatofuz
parents:
diff changeset
127 CurrentCI.Name = C->getTagName();
anatofuz
parents:
diff changeset
128 CurrentCI.SelfClosing = true;
anatofuz
parents:
diff changeset
129 }
anatofuz
parents:
diff changeset
130
anatofuz
parents:
diff changeset
131 void ClangDocCommentVisitor::visitBlockCommandComment(
anatofuz
parents:
diff changeset
132 const BlockCommandComment *C) {
anatofuz
parents:
diff changeset
133 CurrentCI.Name = getCommandName(C->getCommandID());
anatofuz
parents:
diff changeset
134 for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
anatofuz
parents:
diff changeset
135 CurrentCI.Args.push_back(C->getArgText(I));
anatofuz
parents:
diff changeset
136 }
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 void ClangDocCommentVisitor::visitParamCommandComment(
anatofuz
parents:
diff changeset
139 const ParamCommandComment *C) {
anatofuz
parents:
diff changeset
140 CurrentCI.Direction =
anatofuz
parents:
diff changeset
141 ParamCommandComment::getDirectionAsString(C->getDirection());
anatofuz
parents:
diff changeset
142 CurrentCI.Explicit = C->isDirectionExplicit();
anatofuz
parents:
diff changeset
143 if (C->hasParamName())
anatofuz
parents:
diff changeset
144 CurrentCI.ParamName = C->getParamNameAsWritten();
anatofuz
parents:
diff changeset
145 }
anatofuz
parents:
diff changeset
146
anatofuz
parents:
diff changeset
147 void ClangDocCommentVisitor::visitTParamCommandComment(
anatofuz
parents:
diff changeset
148 const TParamCommandComment *C) {
anatofuz
parents:
diff changeset
149 if (C->hasParamName())
anatofuz
parents:
diff changeset
150 CurrentCI.ParamName = C->getParamNameAsWritten();
anatofuz
parents:
diff changeset
151 }
anatofuz
parents:
diff changeset
152
anatofuz
parents:
diff changeset
153 void ClangDocCommentVisitor::visitVerbatimBlockComment(
anatofuz
parents:
diff changeset
154 const VerbatimBlockComment *C) {
anatofuz
parents:
diff changeset
155 CurrentCI.Name = getCommandName(C->getCommandID());
anatofuz
parents:
diff changeset
156 CurrentCI.CloseName = C->getCloseName();
anatofuz
parents:
diff changeset
157 }
anatofuz
parents:
diff changeset
158
anatofuz
parents:
diff changeset
159 void ClangDocCommentVisitor::visitVerbatimBlockLineComment(
anatofuz
parents:
diff changeset
160 const VerbatimBlockLineComment *C) {
anatofuz
parents:
diff changeset
161 if (!isWhitespaceOnly(C->getText()))
anatofuz
parents:
diff changeset
162 CurrentCI.Text = C->getText();
anatofuz
parents:
diff changeset
163 }
anatofuz
parents:
diff changeset
164
anatofuz
parents:
diff changeset
165 void ClangDocCommentVisitor::visitVerbatimLineComment(
anatofuz
parents:
diff changeset
166 const VerbatimLineComment *C) {
anatofuz
parents:
diff changeset
167 if (!isWhitespaceOnly(C->getText()))
anatofuz
parents:
diff changeset
168 CurrentCI.Text = C->getText();
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 bool ClangDocCommentVisitor::isWhitespaceOnly(llvm::StringRef S) const {
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
172 return llvm::all_of(S, isspace);
150
anatofuz
parents:
diff changeset
173 }
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 std::string ClangDocCommentVisitor::getCommandName(unsigned CommandID) const {
anatofuz
parents:
diff changeset
176 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
anatofuz
parents:
diff changeset
177 if (Info)
anatofuz
parents:
diff changeset
178 return Info->Name;
anatofuz
parents:
diff changeset
179 // TODO: Add parsing for \file command.
anatofuz
parents:
diff changeset
180 return "<not a builtin command>";
anatofuz
parents:
diff changeset
181 }
anatofuz
parents:
diff changeset
182
anatofuz
parents:
diff changeset
183 // Serializing functions.
anatofuz
parents:
diff changeset
184
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
185 std::string getSourceCode(const Decl *D, const SourceRange &R) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
186 return Lexer::getSourceText(CharSourceRange::getTokenRange(R),
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
187 D->getASTContext().getSourceManager(),
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
188 D->getASTContext().getLangOpts())
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
189 .str();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
190 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
191
150
anatofuz
parents:
diff changeset
192 template <typename T> static std::string serialize(T &I) {
anatofuz
parents:
diff changeset
193 SmallString<2048> Buffer;
anatofuz
parents:
diff changeset
194 llvm::BitstreamWriter Stream(Buffer);
anatofuz
parents:
diff changeset
195 ClangDocBitcodeWriter Writer(Stream);
anatofuz
parents:
diff changeset
196 Writer.emitBlock(I);
anatofuz
parents:
diff changeset
197 return Buffer.str().str();
anatofuz
parents:
diff changeset
198 }
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 std::string serialize(std::unique_ptr<Info> &I) {
anatofuz
parents:
diff changeset
201 switch (I->IT) {
anatofuz
parents:
diff changeset
202 case InfoType::IT_namespace:
anatofuz
parents:
diff changeset
203 return serialize(*static_cast<NamespaceInfo *>(I.get()));
anatofuz
parents:
diff changeset
204 case InfoType::IT_record:
anatofuz
parents:
diff changeset
205 return serialize(*static_cast<RecordInfo *>(I.get()));
anatofuz
parents:
diff changeset
206 case InfoType::IT_enum:
anatofuz
parents:
diff changeset
207 return serialize(*static_cast<EnumInfo *>(I.get()));
anatofuz
parents:
diff changeset
208 case InfoType::IT_function:
anatofuz
parents:
diff changeset
209 return serialize(*static_cast<FunctionInfo *>(I.get()));
anatofuz
parents:
diff changeset
210 default:
anatofuz
parents:
diff changeset
211 return "";
anatofuz
parents:
diff changeset
212 }
anatofuz
parents:
diff changeset
213 }
anatofuz
parents:
diff changeset
214
anatofuz
parents:
diff changeset
215 static void parseFullComment(const FullComment *C, CommentInfo &CI) {
anatofuz
parents:
diff changeset
216 ClangDocCommentVisitor Visitor(CI);
anatofuz
parents:
diff changeset
217 Visitor.parseComment(C);
anatofuz
parents:
diff changeset
218 }
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 static SymbolID getUSRForDecl(const Decl *D) {
anatofuz
parents:
diff changeset
221 llvm::SmallString<128> USR;
anatofuz
parents:
diff changeset
222 if (index::generateUSRForDecl(D, USR))
anatofuz
parents:
diff changeset
223 return SymbolID();
anatofuz
parents:
diff changeset
224 return hashUSR(USR);
anatofuz
parents:
diff changeset
225 }
anatofuz
parents:
diff changeset
226
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
227 static TagDecl *getTagDeclForType(const QualType &T) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
228 if (const TagDecl *D = T->getAsTagDecl())
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
229 return D->getDefinition();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
230 return nullptr;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
231 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
232
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
233 static RecordDecl *getRecordDeclForType(const QualType &T) {
150
anatofuz
parents:
diff changeset
234 if (const RecordDecl *D = T->getAsRecordDecl())
anatofuz
parents:
diff changeset
235 return D->getDefinition();
anatofuz
parents:
diff changeset
236 return nullptr;
anatofuz
parents:
diff changeset
237 }
anatofuz
parents:
diff changeset
238
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
239 TypeInfo getTypeInfoForType(const QualType &T) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
240 const TagDecl *TD = getTagDeclForType(T);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
241 if (!TD)
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
242 return TypeInfo(Reference(SymbolID(), T.getAsString()));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
243
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
244 InfoType IT;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
245 if (dyn_cast<EnumDecl>(TD)) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
246 IT = InfoType::IT_enum;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
247 } else if (dyn_cast<RecordDecl>(TD)) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
248 IT = InfoType::IT_record;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
249 } else {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
250 IT = InfoType::IT_default;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
251 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
252 return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
253 T.getAsString(), getInfoRelativePath(TD)));
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
254 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
255
150
anatofuz
parents:
diff changeset
256 static bool isPublic(const clang::AccessSpecifier AS,
anatofuz
parents:
diff changeset
257 const clang::Linkage Link) {
anatofuz
parents:
diff changeset
258 if (AS == clang::AccessSpecifier::AS_private)
anatofuz
parents:
diff changeset
259 return false;
anatofuz
parents:
diff changeset
260 else if ((Link == clang::Linkage::ModuleLinkage) ||
anatofuz
parents:
diff changeset
261 (Link == clang::Linkage::ExternalLinkage))
anatofuz
parents:
diff changeset
262 return true;
anatofuz
parents:
diff changeset
263 return false; // otherwise, linkage is some form of internal linkage
anatofuz
parents:
diff changeset
264 }
anatofuz
parents:
diff changeset
265
anatofuz
parents:
diff changeset
266 static bool shouldSerializeInfo(bool PublicOnly, bool IsInAnonymousNamespace,
anatofuz
parents:
diff changeset
267 const NamedDecl *D) {
anatofuz
parents:
diff changeset
268 bool IsAnonymousNamespace = false;
anatofuz
parents:
diff changeset
269 if (const auto *N = dyn_cast<NamespaceDecl>(D))
anatofuz
parents:
diff changeset
270 IsAnonymousNamespace = N->isAnonymousNamespace();
anatofuz
parents:
diff changeset
271 return !PublicOnly ||
anatofuz
parents:
diff changeset
272 (!IsInAnonymousNamespace && !IsAnonymousNamespace &&
anatofuz
parents:
diff changeset
273 isPublic(D->getAccessUnsafe(), D->getLinkageInternal()));
anatofuz
parents:
diff changeset
274 }
anatofuz
parents:
diff changeset
275
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
276 // The InsertChild functions insert the given info into the given scope using
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
277 // the method appropriate for that type. Some types are moved into the
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
278 // appropriate vector, while other types have Reference objects generated to
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
279 // refer to them.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
280 //
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
281 // See MakeAndInsertIntoParent().
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
282 static void InsertChild(ScopeChildren &Scope, const NamespaceInfo &Info) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
283 Scope.Namespaces.emplace_back(Info.USR, Info.Name, InfoType::IT_namespace,
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
284 Info.Name, getInfoRelativePath(Info.Namespace));
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
285 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
286
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
287 static void InsertChild(ScopeChildren &Scope, const RecordInfo &Info) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
288 Scope.Records.emplace_back(Info.USR, Info.Name, InfoType::IT_record,
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
289 Info.Name, getInfoRelativePath(Info.Namespace));
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
290 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
291
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
292 static void InsertChild(ScopeChildren &Scope, EnumInfo Info) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
293 Scope.Enums.push_back(std::move(Info));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
294 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
295
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
296 static void InsertChild(ScopeChildren &Scope, FunctionInfo Info) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
297 Scope.Functions.push_back(std::move(Info));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
298 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
299
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
300 static void InsertChild(ScopeChildren &Scope, TypedefInfo Info) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
301 Scope.Typedefs.push_back(std::move(Info));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
302 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
303
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
304 // Creates a parent of the correct type for the given child and inserts it into
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
305 // that parent.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
306 //
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
307 // This is complicated by the fact that namespaces and records are inserted by
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
308 // reference (constructing a "Reference" object with that namespace/record's
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
309 // info), while everything else is inserted by moving it directly into the child
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
310 // vectors.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
311 //
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
312 // For namespaces and records, explicitly specify a const& template parameter
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
313 // when invoking this function:
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
314 // MakeAndInsertIntoParent<const Record&>(...);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
315 // Otherwise, specify an rvalue reference <EnumInfo&&> and move into the
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
316 // parameter. Since each variant is used once, it's not worth having a more
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
317 // elaborate system to automatically deduce this information.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
318 template <typename ChildType>
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
319 std::unique_ptr<Info> MakeAndInsertIntoParent(ChildType Child) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
320 if (Child.Namespace.empty()) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
321 // Insert into unnamed parent namespace.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
322 auto ParentNS = std::make_unique<NamespaceInfo>();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
323 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
324 return ParentNS;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
325 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
326
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
327 switch (Child.Namespace[0].RefType) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
328 case InfoType::IT_namespace: {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
329 auto ParentNS = std::make_unique<NamespaceInfo>();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
330 ParentNS->USR = Child.Namespace[0].USR;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
331 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
332 return ParentNS;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
333 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
334 case InfoType::IT_record: {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
335 auto ParentRec = std::make_unique<RecordInfo>();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
336 ParentRec->USR = Child.Namespace[0].USR;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
337 InsertChild(ParentRec->Children, std::forward<ChildType>(Child));
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
338 return ParentRec;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
339 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
340 default:
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
341 llvm_unreachable("Invalid reference type for parent namespace");
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
342 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
343 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
344
150
anatofuz
parents:
diff changeset
345 // There are two uses for this function.
anatofuz
parents:
diff changeset
346 // 1) Getting the resulting mode of inheritance of a record.
anatofuz
parents:
diff changeset
347 // Example: class A {}; class B : private A {}; class C : public B {};
anatofuz
parents:
diff changeset
348 // It's explicit that C is publicly inherited from C and B is privately
anatofuz
parents:
diff changeset
349 // inherited from A. It's not explicit but C is also privately inherited from
anatofuz
parents:
diff changeset
350 // A. This is the AS that this function calculates. FirstAS is the
anatofuz
parents:
diff changeset
351 // inheritance mode of `class C : B` and SecondAS is the inheritance mode of
anatofuz
parents:
diff changeset
352 // `class B : A`.
anatofuz
parents:
diff changeset
353 // 2) Getting the inheritance mode of an inherited attribute / method.
anatofuz
parents:
diff changeset
354 // Example : class A { public: int M; }; class B : private A {};
anatofuz
parents:
diff changeset
355 // Class B is inherited from class A, which has a public attribute. This
anatofuz
parents:
diff changeset
356 // attribute is now part of the derived class B but it's not public. This
anatofuz
parents:
diff changeset
357 // will be private because the inheritance is private. This is the AS that
anatofuz
parents:
diff changeset
358 // this function calculates. FirstAS is the inheritance mode and SecondAS is
anatofuz
parents:
diff changeset
359 // the AS of the attribute / method.
anatofuz
parents:
diff changeset
360 static AccessSpecifier getFinalAccessSpecifier(AccessSpecifier FirstAS,
anatofuz
parents:
diff changeset
361 AccessSpecifier SecondAS) {
anatofuz
parents:
diff changeset
362 if (FirstAS == AccessSpecifier::AS_none ||
anatofuz
parents:
diff changeset
363 SecondAS == AccessSpecifier::AS_none)
anatofuz
parents:
diff changeset
364 return AccessSpecifier::AS_none;
anatofuz
parents:
diff changeset
365 if (FirstAS == AccessSpecifier::AS_private ||
anatofuz
parents:
diff changeset
366 SecondAS == AccessSpecifier::AS_private)
anatofuz
parents:
diff changeset
367 return AccessSpecifier::AS_private;
anatofuz
parents:
diff changeset
368 if (FirstAS == AccessSpecifier::AS_protected ||
anatofuz
parents:
diff changeset
369 SecondAS == AccessSpecifier::AS_protected)
anatofuz
parents:
diff changeset
370 return AccessSpecifier::AS_protected;
anatofuz
parents:
diff changeset
371 return AccessSpecifier::AS_public;
anatofuz
parents:
diff changeset
372 }
anatofuz
parents:
diff changeset
373
anatofuz
parents:
diff changeset
374 // The Access parameter is only provided when parsing the field of an inherited
anatofuz
parents:
diff changeset
375 // record, the access specification of the field depends on the inheritance mode
anatofuz
parents:
diff changeset
376 static void parseFields(RecordInfo &I, const RecordDecl *D, bool PublicOnly,
anatofuz
parents:
diff changeset
377 AccessSpecifier Access = AccessSpecifier::AS_public) {
anatofuz
parents:
diff changeset
378 for (const FieldDecl *F : D->fields()) {
anatofuz
parents:
diff changeset
379 if (!shouldSerializeInfo(PublicOnly, /*IsInAnonymousNamespace=*/false, F))
anatofuz
parents:
diff changeset
380 continue;
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
381
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
382 // Use getAccessUnsafe so that we just get the default AS_none if it's not
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
383 // valid, as opposed to an assert.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
384 MemberTypeInfo &NewMember = I.Members.emplace_back(
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
385 getTypeInfoForType(F->getTypeSourceInfo()->getType()),
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
386 F->getNameAsString(),
150
anatofuz
parents:
diff changeset
387 getFinalAccessSpecifier(Access, F->getAccessUnsafe()));
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
388 populateMemberTypeInfo(NewMember, F);
150
anatofuz
parents:
diff changeset
389 }
anatofuz
parents:
diff changeset
390 }
anatofuz
parents:
diff changeset
391
anatofuz
parents:
diff changeset
392 static void parseEnumerators(EnumInfo &I, const EnumDecl *D) {
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
393 for (const EnumConstantDecl *E : D->enumerators()) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
394 std::string ValueExpr;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
395 if (const Expr *InitExpr = E->getInitExpr())
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
396 ValueExpr = getSourceCode(D, InitExpr->getSourceRange());
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
397
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
398 SmallString<16> ValueStr;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
399 E->getInitVal().toString(ValueStr);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
400 I.Members.emplace_back(E->getNameAsString(), ValueStr, ValueExpr);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
401 }
150
anatofuz
parents:
diff changeset
402 }
anatofuz
parents:
diff changeset
403
anatofuz
parents:
diff changeset
404 static void parseParameters(FunctionInfo &I, const FunctionDecl *D) {
anatofuz
parents:
diff changeset
405 for (const ParmVarDecl *P : D->parameters()) {
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
406 FieldTypeInfo &FieldInfo = I.Params.emplace_back(
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
407 getTypeInfoForType(P->getOriginalType()), P->getNameAsString());
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
408 FieldInfo.DefaultValue = getSourceCode(D, P->getDefaultArgRange());
150
anatofuz
parents:
diff changeset
409 }
anatofuz
parents:
diff changeset
410 }
anatofuz
parents:
diff changeset
411
anatofuz
parents:
diff changeset
412 // TODO: Remove the serialization of Parents and VirtualParents, this
anatofuz
parents:
diff changeset
413 // information is also extracted in the other definition of parseBases.
anatofuz
parents:
diff changeset
414 static void parseBases(RecordInfo &I, const CXXRecordDecl *D) {
anatofuz
parents:
diff changeset
415 // Don't parse bases if this isn't a definition.
anatofuz
parents:
diff changeset
416 if (!D->isThisDeclarationADefinition())
anatofuz
parents:
diff changeset
417 return;
anatofuz
parents:
diff changeset
418 for (const CXXBaseSpecifier &B : D->bases()) {
anatofuz
parents:
diff changeset
419 if (B.isVirtual())
anatofuz
parents:
diff changeset
420 continue;
anatofuz
parents:
diff changeset
421 if (const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
anatofuz
parents:
diff changeset
422 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
anatofuz
parents:
diff changeset
423 I.Parents.emplace_back(getUSRForDecl(D), B.getType().getAsString(),
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
424 InfoType::IT_record, B.getType().getAsString());
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
425 } else if (const RecordDecl *P = getRecordDeclForType(B.getType()))
150
anatofuz
parents:
diff changeset
426 I.Parents.emplace_back(getUSRForDecl(P), P->getNameAsString(),
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
427 InfoType::IT_record, P->getQualifiedNameAsString(),
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
428 getInfoRelativePath(P));
150
anatofuz
parents:
diff changeset
429 else
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
430 I.Parents.emplace_back(SymbolID(), B.getType().getAsString());
150
anatofuz
parents:
diff changeset
431 }
anatofuz
parents:
diff changeset
432 for (const CXXBaseSpecifier &B : D->vbases()) {
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
433 if (const RecordDecl *P = getRecordDeclForType(B.getType()))
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
434 I.VirtualParents.emplace_back(
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
435 getUSRForDecl(P), P->getNameAsString(), InfoType::IT_record,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
436 P->getQualifiedNameAsString(), getInfoRelativePath(P));
150
anatofuz
parents:
diff changeset
437 else
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
438 I.VirtualParents.emplace_back(SymbolID(), B.getType().getAsString());
150
anatofuz
parents:
diff changeset
439 }
anatofuz
parents:
diff changeset
440 }
anatofuz
parents:
diff changeset
441
anatofuz
parents:
diff changeset
442 template <typename T>
anatofuz
parents:
diff changeset
443 static void
anatofuz
parents:
diff changeset
444 populateParentNamespaces(llvm::SmallVector<Reference, 4> &Namespaces,
anatofuz
parents:
diff changeset
445 const T *D, bool &IsInAnonymousNamespace) {
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
446 const DeclContext *DC = D->getDeclContext();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
447 do {
150
anatofuz
parents:
diff changeset
448 if (const auto *N = dyn_cast<NamespaceDecl>(DC)) {
anatofuz
parents:
diff changeset
449 std::string Namespace;
anatofuz
parents:
diff changeset
450 if (N->isAnonymousNamespace()) {
anatofuz
parents:
diff changeset
451 Namespace = "@nonymous_namespace";
anatofuz
parents:
diff changeset
452 IsInAnonymousNamespace = true;
anatofuz
parents:
diff changeset
453 } else
anatofuz
parents:
diff changeset
454 Namespace = N->getNameAsString();
anatofuz
parents:
diff changeset
455 Namespaces.emplace_back(getUSRForDecl(N), Namespace,
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
456 InfoType::IT_namespace,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
457 N->getQualifiedNameAsString());
150
anatofuz
parents:
diff changeset
458 } else if (const auto *N = dyn_cast<RecordDecl>(DC))
anatofuz
parents:
diff changeset
459 Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(),
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
460 InfoType::IT_record,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
461 N->getQualifiedNameAsString());
150
anatofuz
parents:
diff changeset
462 else if (const auto *N = dyn_cast<FunctionDecl>(DC))
anatofuz
parents:
diff changeset
463 Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(),
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
464 InfoType::IT_function,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
465 N->getQualifiedNameAsString());
150
anatofuz
parents:
diff changeset
466 else if (const auto *N = dyn_cast<EnumDecl>(DC))
anatofuz
parents:
diff changeset
467 Namespaces.emplace_back(getUSRForDecl(N), N->getNameAsString(),
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
468 InfoType::IT_enum, N->getQualifiedNameAsString());
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
469 } while ((DC = DC->getParent()));
150
anatofuz
parents:
diff changeset
470 // The global namespace should be added to the list of namespaces if the decl
anatofuz
parents:
diff changeset
471 // corresponds to a Record and if it doesn't have any namespace (because this
anatofuz
parents:
diff changeset
472 // means it's in the global namespace). Also if its outermost namespace is a
anatofuz
parents:
diff changeset
473 // record because that record matches the previous condition mentioned.
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
474 if ((Namespaces.empty() && isa<RecordDecl>(D)) ||
150
anatofuz
parents:
diff changeset
475 (!Namespaces.empty() && Namespaces.back().RefType == InfoType::IT_record))
anatofuz
parents:
diff changeset
476 Namespaces.emplace_back(SymbolID(), "GlobalNamespace",
anatofuz
parents:
diff changeset
477 InfoType::IT_namespace);
anatofuz
parents:
diff changeset
478 }
anatofuz
parents:
diff changeset
479
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
480 void PopulateTemplateParameters(std::optional<TemplateInfo> &TemplateInfo,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
481 const clang::Decl *D) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
482 if (const TemplateParameterList *ParamList =
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
483 D->getDescribedTemplateParams()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
484 if (!TemplateInfo) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
485 TemplateInfo.emplace();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
486 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
487 for (const NamedDecl *ND : *ParamList) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
488 TemplateInfo->Params.emplace_back(
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
489 getSourceCode(ND, ND->getSourceRange()));
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
490 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
491 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
492 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
493
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
494 TemplateParamInfo TemplateArgumentToInfo(const clang::Decl *D,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
495 const TemplateArgument &Arg) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
496 // The TemplateArgument's pretty printing handles all the normal cases
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
497 // well enough for our requirements.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
498 std::string Str;
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
499 llvm::raw_string_ostream Stream(Str);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
500 Arg.print(PrintingPolicy(D->getLangOpts()), Stream, false);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
501 return TemplateParamInfo(Str);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
502 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
503
150
anatofuz
parents:
diff changeset
504 template <typename T>
anatofuz
parents:
diff changeset
505 static void populateInfo(Info &I, const T *D, const FullComment *C,
anatofuz
parents:
diff changeset
506 bool &IsInAnonymousNamespace) {
anatofuz
parents:
diff changeset
507 I.USR = getUSRForDecl(D);
anatofuz
parents:
diff changeset
508 I.Name = D->getNameAsString();
anatofuz
parents:
diff changeset
509 populateParentNamespaces(I.Namespace, D, IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
510 if (C) {
anatofuz
parents:
diff changeset
511 I.Description.emplace_back();
anatofuz
parents:
diff changeset
512 parseFullComment(C, I.Description.back());
anatofuz
parents:
diff changeset
513 }
anatofuz
parents:
diff changeset
514 }
anatofuz
parents:
diff changeset
515
anatofuz
parents:
diff changeset
516 template <typename T>
anatofuz
parents:
diff changeset
517 static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
anatofuz
parents:
diff changeset
518 int LineNumber, StringRef Filename,
anatofuz
parents:
diff changeset
519 bool IsFileInRootDir,
anatofuz
parents:
diff changeset
520 bool &IsInAnonymousNamespace) {
anatofuz
parents:
diff changeset
521 populateInfo(I, D, C, IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
522 if (D->isThisDeclarationADefinition())
anatofuz
parents:
diff changeset
523 I.DefLoc.emplace(LineNumber, Filename, IsFileInRootDir);
anatofuz
parents:
diff changeset
524 else
anatofuz
parents:
diff changeset
525 I.Loc.emplace_back(LineNumber, Filename, IsFileInRootDir);
anatofuz
parents:
diff changeset
526 }
anatofuz
parents:
diff changeset
527
anatofuz
parents:
diff changeset
528 static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
anatofuz
parents:
diff changeset
529 const FullComment *FC, int LineNumber,
anatofuz
parents:
diff changeset
530 StringRef Filename, bool IsFileInRootDir,
anatofuz
parents:
diff changeset
531 bool &IsInAnonymousNamespace) {
anatofuz
parents:
diff changeset
532 populateSymbolInfo(I, D, FC, LineNumber, Filename, IsFileInRootDir,
anatofuz
parents:
diff changeset
533 IsInAnonymousNamespace);
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
534 I.ReturnType = getTypeInfoForType(D->getReturnType());
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
535 parseParameters(I, D);
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
536
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
537 PopulateTemplateParameters(I.Template, D);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
538
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
539 // Handle function template specializations.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
540 if (const FunctionTemplateSpecializationInfo *FTSI =
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
541 D->getTemplateSpecializationInfo()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
542 if (!I.Template)
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
543 I.Template.emplace();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
544 I.Template->Specialization.emplace();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
545 auto &Specialization = *I.Template->Specialization;
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
546
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
547 Specialization.SpecializationOf = getUSRForDecl(FTSI->getTemplate());
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
548
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
549 // Template parameters to the specialization.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
550 if (FTSI->TemplateArguments) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
551 for (const TemplateArgument &Arg : FTSI->TemplateArguments->asArray()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
552 Specialization.Params.push_back(TemplateArgumentToInfo(D, Arg));
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
553 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
554 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
555 }
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
556 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
557
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
558 static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
559 assert(D && "Expect non-null FieldDecl in populateMemberTypeInfo");
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
560
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
561 ASTContext& Context = D->getASTContext();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
562 // TODO investigate whether we can use ASTContext::getCommentForDecl instead
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
563 // of this logic. See also similar code in Mapper.cpp.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
564 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
565 if (!Comment)
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
566 return;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
567
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
568 Comment->setAttached();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
569 if (comments::FullComment* fc = Comment->parse(Context, nullptr, D)) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
570 I.Description.emplace_back();
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
571 parseFullComment(fc, I.Description.back());
150
anatofuz
parents:
diff changeset
572 }
anatofuz
parents:
diff changeset
573 }
anatofuz
parents:
diff changeset
574
anatofuz
parents:
diff changeset
575 static void
anatofuz
parents:
diff changeset
576 parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
anatofuz
parents:
diff changeset
577 bool PublicOnly, bool IsParent,
anatofuz
parents:
diff changeset
578 AccessSpecifier ParentAccess = AccessSpecifier::AS_public) {
anatofuz
parents:
diff changeset
579 // Don't parse bases if this isn't a definition.
anatofuz
parents:
diff changeset
580 if (!D->isThisDeclarationADefinition())
anatofuz
parents:
diff changeset
581 return;
anatofuz
parents:
diff changeset
582 for (const CXXBaseSpecifier &B : D->bases()) {
anatofuz
parents:
diff changeset
583 if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
anatofuz
parents:
diff changeset
584 if (const CXXRecordDecl *Base =
anatofuz
parents:
diff changeset
585 cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition())) {
anatofuz
parents:
diff changeset
586 // Initialized without USR and name, this will be set in the following
anatofuz
parents:
diff changeset
587 // if-else stmt.
anatofuz
parents:
diff changeset
588 BaseRecordInfo BI(
anatofuz
parents:
diff changeset
589 {}, "", getInfoRelativePath(Base), B.isVirtual(),
anatofuz
parents:
diff changeset
590 getFinalAccessSpecifier(ParentAccess, B.getAccessSpecifier()),
anatofuz
parents:
diff changeset
591 IsParent);
anatofuz
parents:
diff changeset
592 if (const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
anatofuz
parents:
diff changeset
593 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
anatofuz
parents:
diff changeset
594 BI.USR = getUSRForDecl(D);
anatofuz
parents:
diff changeset
595 BI.Name = B.getType().getAsString();
anatofuz
parents:
diff changeset
596 } else {
anatofuz
parents:
diff changeset
597 BI.USR = getUSRForDecl(Base);
anatofuz
parents:
diff changeset
598 BI.Name = Base->getNameAsString();
anatofuz
parents:
diff changeset
599 }
anatofuz
parents:
diff changeset
600 parseFields(BI, Base, PublicOnly, BI.Access);
anatofuz
parents:
diff changeset
601 for (const auto &Decl : Base->decls())
anatofuz
parents:
diff changeset
602 if (const auto *MD = dyn_cast<CXXMethodDecl>(Decl)) {
anatofuz
parents:
diff changeset
603 // Don't serialize private methods
anatofuz
parents:
diff changeset
604 if (MD->getAccessUnsafe() == AccessSpecifier::AS_private ||
anatofuz
parents:
diff changeset
605 !MD->isUserProvided())
anatofuz
parents:
diff changeset
606 continue;
anatofuz
parents:
diff changeset
607 FunctionInfo FI;
anatofuz
parents:
diff changeset
608 FI.IsMethod = true;
anatofuz
parents:
diff changeset
609 // The seventh arg in populateFunctionInfo is a boolean passed by
anatofuz
parents:
diff changeset
610 // reference, its value is not relevant in here so it's not used
anatofuz
parents:
diff changeset
611 // anywhere besides the function call.
anatofuz
parents:
diff changeset
612 bool IsInAnonymousNamespace;
anatofuz
parents:
diff changeset
613 populateFunctionInfo(FI, MD, /*FullComment=*/{}, /*LineNumber=*/{},
anatofuz
parents:
diff changeset
614 /*FileName=*/{}, IsFileInRootDir,
anatofuz
parents:
diff changeset
615 IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
616 FI.Access =
anatofuz
parents:
diff changeset
617 getFinalAccessSpecifier(BI.Access, MD->getAccessUnsafe());
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
618 BI.Children.Functions.emplace_back(std::move(FI));
150
anatofuz
parents:
diff changeset
619 }
anatofuz
parents:
diff changeset
620 I.Bases.emplace_back(std::move(BI));
anatofuz
parents:
diff changeset
621 // Call this function recursively to get the inherited classes of
anatofuz
parents:
diff changeset
622 // this base; these new bases will also get stored in the original
anatofuz
parents:
diff changeset
623 // RecordInfo: I.
anatofuz
parents:
diff changeset
624 parseBases(I, Base, IsFileInRootDir, PublicOnly, false,
anatofuz
parents:
diff changeset
625 I.Bases.back().Access);
anatofuz
parents:
diff changeset
626 }
anatofuz
parents:
diff changeset
627 }
anatofuz
parents:
diff changeset
628 }
anatofuz
parents:
diff changeset
629 }
anatofuz
parents:
diff changeset
630
anatofuz
parents:
diff changeset
631 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
anatofuz
parents:
diff changeset
632 emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
anatofuz
parents:
diff changeset
633 llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
anatofuz
parents:
diff changeset
634 auto I = std::make_unique<NamespaceInfo>();
anatofuz
parents:
diff changeset
635 bool IsInAnonymousNamespace = false;
anatofuz
parents:
diff changeset
636 populateInfo(*I, D, FC, IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
637 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
anatofuz
parents:
diff changeset
638 return {};
anatofuz
parents:
diff changeset
639
anatofuz
parents:
diff changeset
640 I->Name = D->isAnonymousNamespace()
anatofuz
parents:
diff changeset
641 ? llvm::SmallString<16>("@nonymous_namespace")
anatofuz
parents:
diff changeset
642 : I->Name;
anatofuz
parents:
diff changeset
643 I->Path = getInfoRelativePath(I->Namespace);
anatofuz
parents:
diff changeset
644 if (I->Namespace.empty() && I->USR == SymbolID())
anatofuz
parents:
diff changeset
645 return {std::unique_ptr<Info>{std::move(I)}, nullptr};
anatofuz
parents:
diff changeset
646
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
647 // Namespaces are inserted into the parent by reference, so we need to return
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
648 // both the parent and the record itself.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
649 return {std::move(I), MakeAndInsertIntoParent<const NamespaceInfo &>(*I)};
150
anatofuz
parents:
diff changeset
650 }
anatofuz
parents:
diff changeset
651
anatofuz
parents:
diff changeset
652 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
anatofuz
parents:
diff changeset
653 emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
anatofuz
parents:
diff changeset
654 llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
anatofuz
parents:
diff changeset
655 auto I = std::make_unique<RecordInfo>();
anatofuz
parents:
diff changeset
656 bool IsInAnonymousNamespace = false;
anatofuz
parents:
diff changeset
657 populateSymbolInfo(*I, D, FC, LineNumber, File, IsFileInRootDir,
anatofuz
parents:
diff changeset
658 IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
659 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
anatofuz
parents:
diff changeset
660 return {};
anatofuz
parents:
diff changeset
661
anatofuz
parents:
diff changeset
662 I->TagType = D->getTagKind();
anatofuz
parents:
diff changeset
663 parseFields(*I, D, PublicOnly);
anatofuz
parents:
diff changeset
664 if (const auto *C = dyn_cast<CXXRecordDecl>(D)) {
anatofuz
parents:
diff changeset
665 if (const TypedefNameDecl *TD = C->getTypedefNameForAnonDecl()) {
anatofuz
parents:
diff changeset
666 I->Name = TD->getNameAsString();
anatofuz
parents:
diff changeset
667 I->IsTypeDef = true;
anatofuz
parents:
diff changeset
668 }
anatofuz
parents:
diff changeset
669 // TODO: remove first call to parseBases, that function should be deleted
anatofuz
parents:
diff changeset
670 parseBases(*I, C);
anatofuz
parents:
diff changeset
671 parseBases(*I, C, IsFileInRootDir, PublicOnly, true);
anatofuz
parents:
diff changeset
672 }
anatofuz
parents:
diff changeset
673 I->Path = getInfoRelativePath(I->Namespace);
anatofuz
parents:
diff changeset
674
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
675 PopulateTemplateParameters(I->Template, D);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
676
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
677 // Full and partial specializations.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
678 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
679 if (!I->Template)
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
680 I->Template.emplace();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
681 I->Template->Specialization.emplace();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
682 auto &Specialization = *I->Template->Specialization;
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
683
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
684 // What this is a specialization of.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
685 auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
686 if (SpecOf.is<ClassTemplateDecl *>()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
687 Specialization.SpecializationOf =
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
688 getUSRForDecl(SpecOf.get<ClassTemplateDecl *>());
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
689 } else if (SpecOf.is<ClassTemplatePartialSpecializationDecl *>()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
690 Specialization.SpecializationOf =
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
691 getUSRForDecl(SpecOf.get<ClassTemplatePartialSpecializationDecl *>());
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
692 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
693
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
694 // Parameters to the specilization. For partial specializations, get the
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
695 // parameters "as written" from the ClassTemplatePartialSpecializationDecl
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
696 // because the non-explicit template parameters will have generated internal
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
697 // placeholder names rather than the names the user typed that match the
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
698 // template parameters.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
699 if (const ClassTemplatePartialSpecializationDecl *CTPSD =
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
700 dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
701 if (const ASTTemplateArgumentListInfo *AsWritten =
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
702 CTPSD->getTemplateArgsAsWritten()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
703 for (unsigned i = 0; i < AsWritten->getNumTemplateArgs(); i++) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
704 Specialization.Params.emplace_back(
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
705 getSourceCode(D, (*AsWritten)[i].getSourceRange()));
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
706 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
707 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
708 } else {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
709 for (const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
710 Specialization.Params.push_back(TemplateArgumentToInfo(D, Arg));
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
711 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
712 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
713 }
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
714
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
715 // Records are inserted into the parent by reference, so we need to return
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
716 // both the parent and the record itself.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
717 auto Parent = MakeAndInsertIntoParent<const RecordInfo &>(*I);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
718 return {std::move(I), std::move(Parent)};
150
anatofuz
parents:
diff changeset
719 }
anatofuz
parents:
diff changeset
720
anatofuz
parents:
diff changeset
721 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
anatofuz
parents:
diff changeset
722 emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
anatofuz
parents:
diff changeset
723 llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
anatofuz
parents:
diff changeset
724 FunctionInfo Func;
anatofuz
parents:
diff changeset
725 bool IsInAnonymousNamespace = false;
anatofuz
parents:
diff changeset
726 populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
anatofuz
parents:
diff changeset
727 IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
728 Func.Access = clang::AccessSpecifier::AS_none;
anatofuz
parents:
diff changeset
729 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
anatofuz
parents:
diff changeset
730 return {};
anatofuz
parents:
diff changeset
731
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
732 // Info is wrapped in its parent scope so is returned in the second position.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
733 return {nullptr, MakeAndInsertIntoParent<FunctionInfo &&>(std::move(Func))};
150
anatofuz
parents:
diff changeset
734 }
anatofuz
parents:
diff changeset
735
anatofuz
parents:
diff changeset
736 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
anatofuz
parents:
diff changeset
737 emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
anatofuz
parents:
diff changeset
738 llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
anatofuz
parents:
diff changeset
739 FunctionInfo Func;
anatofuz
parents:
diff changeset
740 bool IsInAnonymousNamespace = false;
anatofuz
parents:
diff changeset
741 populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
anatofuz
parents:
diff changeset
742 IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
743 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
anatofuz
parents:
diff changeset
744 return {};
anatofuz
parents:
diff changeset
745
anatofuz
parents:
diff changeset
746 Func.IsMethod = true;
anatofuz
parents:
diff changeset
747
anatofuz
parents:
diff changeset
748 const NamedDecl *Parent = nullptr;
anatofuz
parents:
diff changeset
749 if (const auto *SD =
anatofuz
parents:
diff changeset
750 dyn_cast<ClassTemplateSpecializationDecl>(D->getParent()))
anatofuz
parents:
diff changeset
751 Parent = SD->getSpecializedTemplate();
anatofuz
parents:
diff changeset
752 else
anatofuz
parents:
diff changeset
753 Parent = D->getParent();
anatofuz
parents:
diff changeset
754
anatofuz
parents:
diff changeset
755 SymbolID ParentUSR = getUSRForDecl(Parent);
anatofuz
parents:
diff changeset
756 Func.Parent =
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
757 Reference{ParentUSR, Parent->getNameAsString(), InfoType::IT_record,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
758 Parent->getQualifiedNameAsString()};
150
anatofuz
parents:
diff changeset
759 Func.Access = D->getAccess();
anatofuz
parents:
diff changeset
760
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
761 // Info is wrapped in its parent scope so is returned in the second position.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
762 return {nullptr, MakeAndInsertIntoParent<FunctionInfo &&>(std::move(Func))};
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
763 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
764
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
765 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
766 emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
767 StringRef File, bool IsFileInRootDir, bool PublicOnly) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
768 TypedefInfo Info;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
769
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
770 bool IsInAnonymousNamespace = false;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
771 populateInfo(Info, D, FC, IsInAnonymousNamespace);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
772 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
773 return {};
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
774
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
775 Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
776 Info.Underlying = getTypeInfoForType(D->getUnderlyingType());
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
777 if (Info.Underlying.Type.Name.empty()) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
778 // Typedef for an unnamed type. This is like "typedef struct { } Foo;"
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
779 // The record serializer explicitly checks for this syntax and constructs
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
780 // a record with that name, so we don't want to emit a duplicate here.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
781 return {};
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
782 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
783 Info.IsUsing = false;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
784
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
785 // Info is wrapped in its parent scope so is returned in the second position.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
786 return {nullptr, MakeAndInsertIntoParent<TypedefInfo &&>(std::move(Info))};
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
787 }
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
788
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
789 // A type alias is a C++ "using" declaration for a type. It gets mapped to a
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
790 // TypedefInfo with the IsUsing flag set.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
791 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
792 emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
793 StringRef File, bool IsFileInRootDir, bool PublicOnly) {
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
794 TypedefInfo Info;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
795
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
796 bool IsInAnonymousNamespace = false;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
797 populateInfo(Info, D, FC, IsInAnonymousNamespace);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
798 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
799 return {};
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
800
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
801 Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
802 Info.Underlying = getTypeInfoForType(D->getUnderlyingType());
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
803 Info.IsUsing = true;
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
804
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
805 // Info is wrapped in its parent scope so is returned in the second position.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
806 return {nullptr, MakeAndInsertIntoParent<TypedefInfo &&>(std::move(Info))};
150
anatofuz
parents:
diff changeset
807 }
anatofuz
parents:
diff changeset
808
anatofuz
parents:
diff changeset
809 std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
anatofuz
parents:
diff changeset
810 emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
anatofuz
parents:
diff changeset
811 llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
anatofuz
parents:
diff changeset
812 EnumInfo Enum;
anatofuz
parents:
diff changeset
813 bool IsInAnonymousNamespace = false;
anatofuz
parents:
diff changeset
814 populateSymbolInfo(Enum, D, FC, LineNumber, File, IsFileInRootDir,
anatofuz
parents:
diff changeset
815 IsInAnonymousNamespace);
anatofuz
parents:
diff changeset
816 if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
anatofuz
parents:
diff changeset
817 return {};
anatofuz
parents:
diff changeset
818
anatofuz
parents:
diff changeset
819 Enum.Scoped = D->isScoped();
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
820 if (D->isFixed()) {
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
821 auto Name = D->getIntegerType().getAsString();
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
822 Enum.BaseType = TypeInfo(Name, Name);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
823 }
150
anatofuz
parents:
diff changeset
824 parseEnumerators(Enum, D);
anatofuz
parents:
diff changeset
825
236
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
826 // Info is wrapped in its parent scope so is returned in the second position.
c4bab56944e8 LLVM 16
kono
parents: 173
diff changeset
827 return {nullptr, MakeAndInsertIntoParent<EnumInfo &&>(std::move(Enum))};
150
anatofuz
parents:
diff changeset
828 }
anatofuz
parents:
diff changeset
829
anatofuz
parents:
diff changeset
830 } // namespace serialize
anatofuz
parents:
diff changeset
831 } // namespace doc
anatofuz
parents:
diff changeset
832 } // namespace clang