1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "clang/AST/ASTContext.h" |
14 | #include "clang/AST/Attr.h" |
15 | #include "clang/AST/Decl.h" |
16 | #include "clang/AST/DeclCXX.h" |
17 | #include "clang/AST/DeclObjC.h" |
18 | #include "clang/AST/DeclVisitor.h" |
19 | #include "clang/AST/Expr.h" |
20 | #include "clang/AST/ExprCXX.h" |
21 | #include "clang/AST/PrettyPrinter.h" |
22 | #include "clang/Basic/Module.h" |
23 | #include "llvm/Support/raw_ostream.h" |
24 | using namespace clang; |
25 | |
26 | namespace { |
27 | class DeclPrinter : public DeclVisitor<DeclPrinter> { |
28 | raw_ostream &Out; |
29 | PrintingPolicy Policy; |
30 | const ASTContext &Context; |
31 | unsigned Indentation; |
32 | bool PrintInstantiation; |
33 | |
34 | raw_ostream& Indent() { return Indent(Indentation); } |
35 | raw_ostream& Indent(unsigned Indentation); |
36 | void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls); |
37 | |
38 | void Print(AccessSpecifier AS); |
39 | void PrintConstructorInitializers(CXXConstructorDecl *CDecl, |
40 | std::string &Proto); |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | void PrintObjCMethodType(ASTContext &Ctx, Decl::ObjCDeclQualifier Quals, |
47 | QualType T); |
48 | |
49 | void PrintObjCTypeParams(ObjCTypeParamList *Params); |
50 | |
51 | public: |
52 | DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy, |
53 | const ASTContext &Context, unsigned Indentation = 0, |
54 | bool PrintInstantiation = false) |
55 | : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation), |
56 | PrintInstantiation(PrintInstantiation) {} |
57 | |
58 | void VisitDeclContext(DeclContext *DC, bool Indent = true); |
59 | |
60 | void VisitTranslationUnitDecl(TranslationUnitDecl *D); |
61 | void VisitTypedefDecl(TypedefDecl *D); |
62 | void VisitTypeAliasDecl(TypeAliasDecl *D); |
63 | void VisitEnumDecl(EnumDecl *D); |
64 | void VisitRecordDecl(RecordDecl *D); |
65 | void VisitEnumConstantDecl(EnumConstantDecl *D); |
66 | void VisitEmptyDecl(EmptyDecl *D); |
67 | void VisitFunctionDecl(FunctionDecl *D); |
68 | void VisitFriendDecl(FriendDecl *D); |
69 | void VisitFieldDecl(FieldDecl *D); |
70 | void VisitVarDecl(VarDecl *D); |
71 | void VisitLabelDecl(LabelDecl *D); |
72 | void VisitParmVarDecl(ParmVarDecl *D); |
73 | void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); |
74 | void VisitImportDecl(ImportDecl *D); |
75 | void VisitStaticAssertDecl(StaticAssertDecl *D); |
76 | void VisitNamespaceDecl(NamespaceDecl *D); |
77 | void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); |
78 | void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); |
79 | void VisitCXXRecordDecl(CXXRecordDecl *D); |
80 | void VisitLinkageSpecDecl(LinkageSpecDecl *D); |
81 | void VisitTemplateDecl(const TemplateDecl *D); |
82 | void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); |
83 | void VisitClassTemplateDecl(ClassTemplateDecl *D); |
84 | void VisitClassTemplateSpecializationDecl( |
85 | ClassTemplateSpecializationDecl *D); |
86 | void VisitClassTemplatePartialSpecializationDecl( |
87 | ClassTemplatePartialSpecializationDecl *D); |
88 | void VisitObjCMethodDecl(ObjCMethodDecl *D); |
89 | void VisitObjCImplementationDecl(ObjCImplementationDecl *D); |
90 | void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); |
91 | void VisitObjCProtocolDecl(ObjCProtocolDecl *D); |
92 | void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); |
93 | void VisitObjCCategoryDecl(ObjCCategoryDecl *D); |
94 | void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D); |
95 | void VisitObjCPropertyDecl(ObjCPropertyDecl *D); |
96 | void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); |
97 | void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); |
98 | void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); |
99 | void VisitUsingDecl(UsingDecl *D); |
100 | void VisitUsingShadowDecl(UsingShadowDecl *D); |
101 | void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); |
102 | void VisitOMPAllocateDecl(OMPAllocateDecl *D); |
103 | void VisitOMPRequiresDecl(OMPRequiresDecl *D); |
104 | void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); |
105 | void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); |
106 | void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); |
107 | |
108 | void printTemplateParameters(const TemplateParameterList *Params); |
109 | void printTemplateArguments(const TemplateArgumentList &Args, |
110 | const TemplateParameterList *Params = nullptr); |
111 | void prettyPrintAttributes(Decl *D); |
112 | void prettyPrintPragmas(Decl *D); |
113 | void printDeclType(QualType T, StringRef DeclName, bool Pack = false); |
114 | }; |
115 | } |
116 | |
117 | void Decl::print(raw_ostream &Out, unsigned Indentation, |
118 | bool PrintInstantiation) const { |
119 | print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation); |
120 | } |
121 | |
122 | void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy, |
123 | unsigned Indentation, bool PrintInstantiation) const { |
124 | DeclPrinter Printer(Out, Policy, getASTContext(), Indentation, |
125 | PrintInstantiation); |
126 | Printer.Visit(const_cast<Decl*>(this)); |
127 | } |
128 | |
129 | static QualType GetBaseType(QualType T) { |
130 | |
131 | QualType BaseType = T; |
132 | while (!BaseType->isSpecifierType()) { |
133 | if (const PointerType *PTy = BaseType->getAs<PointerType>()) |
134 | BaseType = PTy->getPointeeType(); |
135 | else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>()) |
136 | BaseType = BPy->getPointeeType(); |
137 | else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType)) |
138 | BaseType = ATy->getElementType(); |
139 | else if (const FunctionType* FTy = BaseType->getAs<FunctionType>()) |
140 | BaseType = FTy->getReturnType(); |
141 | else if (const VectorType *VTy = BaseType->getAs<VectorType>()) |
142 | BaseType = VTy->getElementType(); |
143 | else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>()) |
144 | BaseType = RTy->getPointeeType(); |
145 | else if (const AutoType *ATy = BaseType->getAs<AutoType>()) |
146 | BaseType = ATy->getDeducedType(); |
147 | else if (const ParenType *PTy = BaseType->getAs<ParenType>()) |
148 | BaseType = PTy->desugar(); |
149 | else |
150 | |
151 | break; |
152 | } |
153 | return BaseType; |
154 | } |
155 | |
156 | static QualType getDeclType(Decl* D) { |
157 | if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D)) |
158 | return TDD->getUnderlyingType(); |
159 | if (ValueDecl* VD = dyn_cast<ValueDecl>(D)) |
160 | return VD->getType(); |
161 | return QualType(); |
162 | } |
163 | |
164 | void Decl::printGroup(Decl** Begin, unsigned NumDecls, |
165 | raw_ostream &Out, const PrintingPolicy &Policy, |
166 | unsigned Indentation) { |
167 | if (NumDecls == 1) { |
168 | (*Begin)->print(Out, Policy, Indentation); |
169 | return; |
170 | } |
171 | |
172 | Decl** End = Begin + NumDecls; |
173 | TagDecl* TD = dyn_cast<TagDecl>(*Begin); |
174 | if (TD) |
175 | ++Begin; |
176 | |
177 | PrintingPolicy SubPolicy(Policy); |
178 | |
179 | bool isFirst = true; |
180 | for ( ; Begin != End; ++Begin) { |
181 | if (isFirst) { |
182 | if(TD) |
183 | SubPolicy.IncludeTagDefinition = true; |
184 | SubPolicy.SuppressSpecifiers = false; |
185 | isFirst = false; |
186 | } else { |
187 | if (!isFirst) Out << ", "; |
188 | SubPolicy.IncludeTagDefinition = false; |
189 | SubPolicy.SuppressSpecifiers = true; |
190 | } |
191 | |
192 | (*Begin)->print(Out, SubPolicy, Indentation); |
193 | } |
194 | } |
195 | |
196 | LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const { |
197 | |
198 | const DeclContext *DC = this; |
199 | while (!DC->isTranslationUnit()) |
200 | DC = DC->getParent(); |
201 | |
202 | ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); |
203 | DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0); |
204 | Printer.VisitDeclContext(const_cast<DeclContext *>(this), ); |
205 | } |
206 | |
207 | raw_ostream& DeclPrinter::Indent(unsigned Indentation) { |
208 | for (unsigned i = 0; i != Indentation; ++i) |
209 | Out << " "; |
210 | return Out; |
211 | } |
212 | |
213 | void DeclPrinter::prettyPrintAttributes(Decl *D) { |
214 | if (Policy.PolishForDeclaration) |
215 | return; |
216 | |
217 | if (D->hasAttrs()) { |
218 | AttrVec &Attrs = D->getAttrs(); |
219 | for (auto *A : Attrs) { |
220 | if (A->isInherited() || A->isImplicit()) |
221 | continue; |
222 | switch (A->getKind()) { |
223 | #define ATTR(X) |
224 | #define PRAGMA_SPELLING_ATTR(X) case attr::X: |
225 | #include "clang/Basic/AttrList.inc" |
226 | break; |
227 | default: |
228 | A->printPretty(Out, Policy); |
229 | break; |
230 | } |
231 | } |
232 | } |
233 | } |
234 | |
235 | void DeclPrinter::prettyPrintPragmas(Decl *D) { |
236 | if (Policy.PolishForDeclaration) |
237 | return; |
238 | |
239 | if (D->hasAttrs()) { |
240 | AttrVec &Attrs = D->getAttrs(); |
241 | for (auto *A : Attrs) { |
242 | switch (A->getKind()) { |
243 | #define ATTR(X) |
244 | #define PRAGMA_SPELLING_ATTR(X) case attr::X: |
245 | #include "clang/Basic/AttrList.inc" |
246 | A->printPretty(Out, Policy); |
247 | Indent(); |
248 | break; |
249 | default: |
250 | break; |
251 | } |
252 | } |
253 | } |
254 | } |
255 | |
256 | void DeclPrinter::printDeclType(QualType T, StringRef DeclName, bool Pack) { |
257 | |
258 | |
259 | |
260 | if (auto *PET = T->getAs<PackExpansionType>()) { |
261 | Pack = true; |
262 | T = PET->getPattern(); |
263 | } |
264 | T.print(Out, Policy, (Pack ? "..." : "") + DeclName, Indentation); |
265 | } |
266 | |
267 | void DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) { |
268 | this->Indent(); |
269 | Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation); |
270 | Out << ";\n"; |
271 | Decls.clear(); |
272 | |
273 | } |
274 | |
275 | void DeclPrinter::Print(AccessSpecifier AS) { |
276 | switch(AS) { |
277 | case AS_none: llvm_unreachable("No access specifier!"); |
278 | case AS_public: Out << "public"; break; |
279 | case AS_protected: Out << "protected"; break; |
280 | case AS_private: Out << "private"; break; |
281 | } |
282 | } |
283 | |
284 | void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl, |
285 | std::string &Proto) { |
286 | bool HasInitializerList = false; |
287 | for (const auto *BMInitializer : CDecl->inits()) { |
288 | if (BMInitializer->isInClassMemberInitializer()) |
289 | continue; |
290 | |
291 | if (!HasInitializerList) { |
292 | Proto += " : "; |
293 | Out << Proto; |
294 | Proto.clear(); |
295 | HasInitializerList = true; |
296 | } else |
297 | Out << ", "; |
298 | |
299 | if (BMInitializer->isAnyMemberInitializer()) { |
300 | FieldDecl *FD = BMInitializer->getAnyMember(); |
301 | Out << *FD; |
302 | } else { |
303 | Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy); |
304 | } |
305 | |
306 | Out << "("; |
307 | if (!BMInitializer->getInit()) { |
308 | |
309 | } else { |
310 | Expr *Init = BMInitializer->getInit(); |
311 | if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init)) |
312 | Init = Tmp->getSubExpr(); |
313 | |
314 | Init = Init->IgnoreParens(); |
315 | |
316 | Expr *SimpleInit = nullptr; |
317 | Expr **Args = nullptr; |
318 | unsigned NumArgs = 0; |
319 | if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { |
320 | Args = ParenList->getExprs(); |
321 | NumArgs = ParenList->getNumExprs(); |
322 | } else if (CXXConstructExpr *Construct = |
323 | dyn_cast<CXXConstructExpr>(Init)) { |
324 | Args = Construct->getArgs(); |
325 | NumArgs = Construct->getNumArgs(); |
326 | } else |
327 | SimpleInit = Init; |
328 | |
329 | if (SimpleInit) |
330 | SimpleInit->printPretty(Out, nullptr, Policy, Indentation); |
331 | else { |
332 | for (unsigned I = 0; I != NumArgs; ++I) { |
333 | (0) . __assert_fail ("Args[I] != nullptr && \"Expected non-null Expr\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/DeclPrinter.cpp", 333, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Args[I] != nullptr && "Expected non-null Expr"); |
334 | if (isa<CXXDefaultArgExpr>(Args[I])) |
335 | break; |
336 | |
337 | if (I) |
338 | Out << ", "; |
339 | Args[I]->printPretty(Out, nullptr, Policy, Indentation); |
340 | } |
341 | } |
342 | } |
343 | Out << ")"; |
344 | if (BMInitializer->isPackExpansion()) |
345 | Out << "..."; |
346 | } |
347 | } |
348 | |
349 | |
350 | |
351 | |
352 | |
353 | void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { |
354 | if (Policy.TerseOutput) |
355 | return; |
356 | |
357 | if (Indent) |
358 | Indentation += Policy.Indentation; |
359 | |
360 | SmallVector<Decl*, 2> Decls; |
361 | for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); |
362 | D != DEnd; ++D) { |
363 | |
364 | |
365 | |
366 | if (isa<ObjCIvarDecl>(*D)) |
367 | continue; |
368 | |
369 | |
370 | if (D->isImplicit()) |
371 | continue; |
372 | |
373 | |
374 | |
375 | if (auto FD = dyn_cast<FunctionDecl>(*D)) |
376 | if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation && |
377 | !isa<ClassTemplateSpecializationDecl>(DC)) |
378 | continue; |
379 | |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | |
392 | QualType CurDeclType = getDeclType(*D); |
393 | if (!Decls.empty() && !CurDeclType.isNull()) { |
394 | QualType BaseType = GetBaseType(CurDeclType); |
395 | if (!BaseType.isNull() && isa<ElaboratedType>(BaseType) && |
396 | cast<ElaboratedType>(BaseType)->getOwnedTagDecl() == Decls[0]) { |
397 | Decls.push_back(*D); |
398 | continue; |
399 | } |
400 | } |
401 | |
402 | |
403 | if (!Decls.empty()) |
404 | ProcessDeclGroup(Decls); |
405 | |
406 | |
407 | |
408 | if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->isFreeStanding()) { |
409 | Decls.push_back(*D); |
410 | continue; |
411 | } |
412 | |
413 | if (isa<AccessSpecDecl>(*D)) { |
414 | Indentation -= Policy.Indentation; |
415 | this->Indent(); |
416 | Print(D->getAccess()); |
417 | Out << ":\n"; |
418 | Indentation += Policy.Indentation; |
419 | continue; |
420 | } |
421 | |
422 | this->Indent(); |
423 | Visit(*D); |
424 | |
425 | |
426 | const char *Terminator = nullptr; |
427 | if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) || |
428 | isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D) || |
429 | isa<OMPAllocateDecl>(*D)) |
430 | Terminator = nullptr; |
431 | else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody()) |
432 | Terminator = nullptr; |
433 | else if (auto FD = dyn_cast<FunctionDecl>(*D)) { |
434 | if (FD->isThisDeclarationADefinition()) |
435 | Terminator = nullptr; |
436 | else |
437 | Terminator = ";"; |
438 | } else if (auto TD = dyn_cast<FunctionTemplateDecl>(*D)) { |
439 | if (TD->getTemplatedDecl()->isThisDeclarationADefinition()) |
440 | Terminator = nullptr; |
441 | else |
442 | Terminator = ";"; |
443 | } else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) || |
444 | isa<ObjCImplementationDecl>(*D) || |
445 | isa<ObjCInterfaceDecl>(*D) || |
446 | isa<ObjCProtocolDecl>(*D) || |
447 | isa<ObjCCategoryImplDecl>(*D) || |
448 | isa<ObjCCategoryDecl>(*D)) |
449 | Terminator = nullptr; |
450 | else if (isa<EnumConstantDecl>(*D)) { |
451 | DeclContext::decl_iterator Next = D; |
452 | ++Next; |
453 | if (Next != DEnd) |
454 | Terminator = ","; |
455 | } else |
456 | Terminator = ";"; |
457 | |
458 | if (Terminator) |
459 | Out << Terminator; |
460 | if (!Policy.TerseOutput && |
461 | ((isa<FunctionDecl>(*D) && |
462 | cast<FunctionDecl>(*D)->doesThisDeclarationHaveABody()) || |
463 | (isa<FunctionTemplateDecl>(*D) && |
464 | cast<FunctionTemplateDecl>(*D)->getTemplatedDecl()->doesThisDeclarationHaveABody()))) |
465 | ; |
466 | else |
467 | Out << "\n"; |
468 | |
469 | |
470 | |
471 | if (D->hasAttr<OMPDeclareTargetDeclAttr>()) |
472 | Out << "#pragma omp end declare target\n"; |
473 | } |
474 | |
475 | if (!Decls.empty()) |
476 | ProcessDeclGroup(Decls); |
477 | |
478 | if (Indent) |
479 | Indentation -= Policy.Indentation; |
480 | } |
481 | |
482 | void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { |
483 | VisitDeclContext(D, false); |
484 | } |
485 | |
486 | void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) { |
487 | if (!Policy.SuppressSpecifiers) { |
488 | Out << "typedef "; |
489 | |
490 | if (D->isModulePrivate()) |
491 | Out << "__module_private__ "; |
492 | } |
493 | QualType Ty = D->getTypeSourceInfo()->getType(); |
494 | Ty.print(Out, Policy, D->getName(), Indentation); |
495 | prettyPrintAttributes(D); |
496 | } |
497 | |
498 | void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) { |
499 | Out << "using " << *D; |
500 | prettyPrintAttributes(D); |
501 | Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy); |
502 | } |
503 | |
504 | void DeclPrinter::VisitEnumDecl(EnumDecl *D) { |
505 | if (!Policy.SuppressSpecifiers && D->isModulePrivate()) |
506 | Out << "__module_private__ "; |
507 | Out << "enum"; |
508 | if (D->isScoped()) { |
509 | if (D->isScopedUsingClassTag()) |
510 | Out << " class"; |
511 | else |
512 | Out << " struct"; |
513 | } |
514 | |
515 | prettyPrintAttributes(D); |
516 | |
517 | Out << ' ' << *D; |
518 | |
519 | if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11) |
520 | Out << " : " << D->getIntegerType().stream(Policy); |
521 | |
522 | if (D->isCompleteDefinition()) { |
523 | Out << " {\n"; |
524 | VisitDeclContext(D); |
525 | Indent() << "}"; |
526 | } |
527 | } |
528 | |
529 | void DeclPrinter::VisitRecordDecl(RecordDecl *D) { |
530 | if (!Policy.SuppressSpecifiers && D->isModulePrivate()) |
531 | Out << "__module_private__ "; |
532 | Out << D->getKindName(); |
533 | |
534 | prettyPrintAttributes(D); |
535 | |
536 | if (D->getIdentifier()) |
537 | Out << ' ' << *D; |
538 | |
539 | if (D->isCompleteDefinition()) { |
540 | Out << " {\n"; |
541 | VisitDeclContext(D); |
542 | Indent() << "}"; |
543 | } |
544 | } |
545 | |
546 | void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) { |
547 | Out << *D; |
548 | prettyPrintAttributes(D); |
549 | if (Expr *Init = D->getInitExpr()) { |
550 | Out << " = "; |
551 | Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context); |
552 | } |
553 | } |
554 | |
555 | void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { |
556 | if (!D->getDescribedFunctionTemplate() && |
557 | !D->isFunctionTemplateSpecialization()) |
558 | prettyPrintPragmas(D); |
559 | |
560 | if (D->isFunctionTemplateSpecialization()) |
561 | Out << "template<> "; |
562 | else if (!D->getDescribedFunctionTemplate()) { |
563 | for (unsigned I = 0, NumTemplateParams = D->getNumTemplateParameterLists(); |
564 | I < NumTemplateParams; ++I) |
565 | printTemplateParameters(D->getTemplateParameterList(I)); |
566 | } |
567 | |
568 | CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D); |
569 | CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D); |
570 | CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D); |
571 | if (!Policy.SuppressSpecifiers) { |
572 | switch (D->getStorageClass()) { |
573 | case SC_None: break; |
574 | case SC_Extern: Out << "extern "; break; |
575 | case SC_Static: Out << "static "; break; |
576 | case SC_PrivateExtern: Out << "__private_extern__ "; break; |
577 | case SC_Auto: case SC_Register: |
578 | llvm_unreachable("invalid for functions"); |
579 | } |
580 | |
581 | if (D->isInlineSpecified()) Out << "inline "; |
582 | if (D->isVirtualAsWritten()) Out << "virtual "; |
583 | if (D->isModulePrivate()) Out << "__module_private__ "; |
584 | if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr "; |
585 | if ((CDecl && CDecl->isExplicitSpecified()) || |
586 | (ConversionDecl && ConversionDecl->isExplicitSpecified()) || |
587 | (GuideDecl && GuideDecl->isExplicitSpecified())) |
588 | Out << "explicit "; |
589 | } |
590 | |
591 | PrintingPolicy SubPolicy(Policy); |
592 | SubPolicy.SuppressSpecifiers = false; |
593 | std::string Proto; |
594 | |
595 | if (Policy.FullyQualifiedName) { |
596 | Proto += D->getQualifiedNameAsString(); |
597 | } else { |
598 | if (!Policy.SuppressScope) { |
599 | if (const NestedNameSpecifier *NS = D->getQualifier()) { |
600 | llvm::raw_string_ostream OS(Proto); |
601 | NS->print(OS, Policy); |
602 | } |
603 | } |
604 | Proto += D->getNameInfo().getAsString(); |
605 | } |
606 | |
607 | if (GuideDecl) |
608 | Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString(); |
609 | if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) { |
610 | llvm::raw_string_ostream POut(Proto); |
611 | DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation); |
612 | TArgPrinter.printTemplateArguments(*TArgs); |
613 | } |
614 | |
615 | QualType Ty = D->getType(); |
616 | while (const ParenType *PT = dyn_cast<ParenType>(Ty)) { |
617 | Proto = '(' + Proto + ')'; |
618 | Ty = PT->getInnerType(); |
619 | } |
620 | |
621 | if (const FunctionType *AFT = Ty->getAs<FunctionType>()) { |
622 | const FunctionProtoType *FT = nullptr; |
623 | if (D->hasWrittenPrototype()) |
624 | FT = dyn_cast<FunctionProtoType>(AFT); |
625 | |
626 | Proto += "("; |
627 | if (FT) { |
628 | llvm::raw_string_ostream POut(Proto); |
629 | DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation); |
630 | for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { |
631 | if (i) POut << ", "; |
632 | ParamPrinter.VisitParmVarDecl(D->getParamDecl(i)); |
633 | } |
634 | |
635 | if (FT->isVariadic()) { |
636 | if (D->getNumParams()) POut << ", "; |
637 | POut << "..."; |
638 | } |
639 | } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) { |
640 | for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { |
641 | if (i) |
642 | Proto += ", "; |
643 | Proto += D->getParamDecl(i)->getNameAsString(); |
644 | } |
645 | } |
646 | |
647 | Proto += ")"; |
648 | |
649 | if (FT) { |
650 | if (FT->isConst()) |
651 | Proto += " const"; |
652 | if (FT->isVolatile()) |
653 | Proto += " volatile"; |
654 | if (FT->isRestrict()) |
655 | Proto += " restrict"; |
656 | |
657 | switch (FT->getRefQualifier()) { |
658 | case RQ_None: |
659 | break; |
660 | case RQ_LValue: |
661 | Proto += " &"; |
662 | break; |
663 | case RQ_RValue: |
664 | Proto += " &&"; |
665 | break; |
666 | } |
667 | } |
668 | |
669 | if (FT && FT->hasDynamicExceptionSpec()) { |
670 | Proto += " throw("; |
671 | if (FT->getExceptionSpecType() == EST_MSAny) |
672 | Proto += "..."; |
673 | else |
674 | for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) { |
675 | if (I) |
676 | Proto += ", "; |
677 | |
678 | Proto += FT->getExceptionType(I).getAsString(SubPolicy); |
679 | } |
680 | Proto += ")"; |
681 | } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) { |
682 | Proto += " noexcept"; |
683 | if (isComputedNoexcept(FT->getExceptionSpecType())) { |
684 | Proto += "("; |
685 | llvm::raw_string_ostream EOut(Proto); |
686 | FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy, |
687 | Indentation); |
688 | EOut.flush(); |
689 | Proto += EOut.str(); |
690 | Proto += ")"; |
691 | } |
692 | } |
693 | |
694 | if (CDecl) { |
695 | if (!Policy.TerseOutput) |
696 | PrintConstructorInitializers(CDecl, Proto); |
697 | } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) { |
698 | if (FT && FT->hasTrailingReturn()) { |
699 | if (!GuideDecl) |
700 | Out << "auto "; |
701 | Out << Proto << " -> "; |
702 | Proto.clear(); |
703 | } |
704 | AFT->getReturnType().print(Out, Policy, Proto); |
705 | Proto.clear(); |
706 | } |
707 | Out << Proto; |
708 | } else { |
709 | Ty.print(Out, Policy, Proto); |
710 | } |
711 | |
712 | prettyPrintAttributes(D); |
713 | |
714 | if (D->isPure()) |
715 | Out << " = 0"; |
716 | else if (D->isDeletedAsWritten()) |
717 | Out << " = delete"; |
718 | else if (D->isExplicitlyDefaulted()) |
719 | Out << " = default"; |
720 | else if (D->doesThisDeclarationHaveABody()) { |
721 | if (!Policy.TerseOutput) { |
722 | if (!D->hasPrototype() && D->getNumParams()) { |
723 | |
724 | |
725 | Out << '\n'; |
726 | DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation); |
727 | Indentation += Policy.Indentation; |
728 | for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { |
729 | Indent(); |
730 | ParamPrinter.VisitParmVarDecl(D->getParamDecl(i)); |
731 | Out << ";\n"; |
732 | } |
733 | Indentation -= Policy.Indentation; |
734 | } else |
735 | Out << ' '; |
736 | |
737 | if (D->getBody()) |
738 | D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation); |
739 | } else { |
740 | if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D)) |
741 | Out << " {}"; |
742 | } |
743 | } |
744 | } |
745 | |
746 | void DeclPrinter::VisitFriendDecl(FriendDecl *D) { |
747 | if (TypeSourceInfo *TSI = D->getFriendType()) { |
748 | unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists(); |
749 | for (unsigned i = 0; i < NumTPLists; ++i) |
750 | printTemplateParameters(D->getFriendTypeTemplateParameterList(i)); |
751 | Out << "friend "; |
752 | Out << " " << TSI->getType().getAsString(Policy); |
753 | } |
754 | else if (FunctionDecl *FD = |
755 | dyn_cast<FunctionDecl>(D->getFriendDecl())) { |
756 | Out << "friend "; |
757 | VisitFunctionDecl(FD); |
758 | } |
759 | else if (FunctionTemplateDecl *FTD = |
760 | dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) { |
761 | Out << "friend "; |
762 | VisitFunctionTemplateDecl(FTD); |
763 | } |
764 | else if (ClassTemplateDecl *CTD = |
765 | dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) { |
766 | Out << "friend "; |
767 | VisitRedeclarableTemplateDecl(CTD); |
768 | } |
769 | } |
770 | |
771 | void DeclPrinter::VisitFieldDecl(FieldDecl *D) { |
772 | |
773 | if (!Policy.SuppressSpecifiers && D->isMutable()) |
774 | Out << "mutable "; |
775 | if (!Policy.SuppressSpecifiers && D->isModulePrivate()) |
776 | Out << "__module_private__ "; |
777 | |
778 | Out << D->getASTContext().getUnqualifiedObjCPointerType(D->getType()). |
779 | stream(Policy, D->getName(), Indentation); |
780 | |
781 | if (D->isBitField()) { |
782 | Out << " : "; |
783 | D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation); |
784 | } |
785 | |
786 | Expr *Init = D->getInClassInitializer(); |
787 | if (!Policy.SuppressInitializers && Init) { |
788 | if (D->getInClassInitStyle() == ICIS_ListInit) |
789 | Out << " "; |
790 | else |
791 | Out << " = "; |
792 | Init->printPretty(Out, nullptr, Policy, Indentation); |
793 | } |
794 | prettyPrintAttributes(D); |
795 | } |
796 | |
797 | void DeclPrinter::VisitLabelDecl(LabelDecl *D) { |
798 | Out << *D << ":"; |
799 | } |
800 | |
801 | void DeclPrinter::VisitVarDecl(VarDecl *D) { |
802 | prettyPrintPragmas(D); |
803 | |
804 | QualType T = D->getTypeSourceInfo() |
805 | ? D->getTypeSourceInfo()->getType() |
806 | : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); |
807 | |
808 | if (!Policy.SuppressSpecifiers) { |
809 | StorageClass SC = D->getStorageClass(); |
810 | if (SC != SC_None) |
811 | Out << VarDecl::getStorageClassSpecifierString(SC) << " "; |
812 | |
813 | switch (D->getTSCSpec()) { |
814 | case TSCS_unspecified: |
815 | break; |
816 | case TSCS___thread: |
817 | Out << "__thread "; |
818 | break; |
819 | case TSCS__Thread_local: |
820 | Out << "_Thread_local "; |
821 | break; |
822 | case TSCS_thread_local: |
823 | Out << "thread_local "; |
824 | break; |
825 | } |
826 | |
827 | if (D->isModulePrivate()) |
828 | Out << "__module_private__ "; |
829 | |
830 | if (D->isConstexpr()) { |
831 | Out << "constexpr "; |
832 | T.removeLocalConst(); |
833 | } |
834 | } |
835 | |
836 | printDeclType(T, D->getName()); |
837 | Expr *Init = D->getInit(); |
838 | if (!Policy.SuppressInitializers && Init) { |
839 | bool ImplicitInit = false; |
840 | if (CXXConstructExpr *Construct = |
841 | dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) { |
842 | if (D->getInitStyle() == VarDecl::CallInit && |
843 | !Construct->isListInitialization()) { |
844 | ImplicitInit = Construct->getNumArgs() == 0 || |
845 | Construct->getArg(0)->isDefaultArgument(); |
846 | } |
847 | } |
848 | if (!ImplicitInit) { |
849 | if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init)) |
850 | Out << "("; |
851 | else if (D->getInitStyle() == VarDecl::CInit) { |
852 | Out << " = "; |
853 | } |
854 | PrintingPolicy SubPolicy(Policy); |
855 | SubPolicy.SuppressSpecifiers = false; |
856 | SubPolicy.IncludeTagDefinition = false; |
857 | Init->printPretty(Out, nullptr, SubPolicy, Indentation); |
858 | if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init)) |
859 | Out << ")"; |
860 | } |
861 | } |
862 | prettyPrintAttributes(D); |
863 | } |
864 | |
865 | void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { |
866 | VisitVarDecl(D); |
867 | } |
868 | |
869 | void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { |
870 | Out << "__asm ("; |
871 | D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation); |
872 | Out << ")"; |
873 | } |
874 | |
875 | void DeclPrinter::VisitImportDecl(ImportDecl *D) { |
876 | Out << "@import " << D->getImportedModule()->getFullModuleName() |
877 | << ";\n"; |
878 | } |
879 | |
880 | void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) { |
881 | Out << "static_assert("; |
882 | D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation); |
883 | if (StringLiteral *SL = D->getMessage()) { |
884 | Out << ", "; |
885 | SL->printPretty(Out, nullptr, Policy, Indentation); |
886 | } |
887 | Out << ")"; |
888 | } |
889 | |
890 | |
891 | |
892 | |
893 | void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) { |
894 | if (D->isInline()) |
895 | Out << "inline "; |
896 | Out << "namespace " << *D << " {\n"; |
897 | VisitDeclContext(D); |
898 | Indent() << "}"; |
899 | } |
900 | |
901 | void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { |
902 | Out << "using namespace "; |
903 | if (D->getQualifier()) |
904 | D->getQualifier()->print(Out, Policy); |
905 | Out << *D->getNominatedNamespaceAsWritten(); |
906 | } |
907 | |
908 | void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { |
909 | Out << "namespace " << *D << " = "; |
910 | if (D->getQualifier()) |
911 | D->getQualifier()->print(Out, Policy); |
912 | Out << *D->getAliasedNamespace(); |
913 | } |
914 | |
915 | void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) { |
916 | prettyPrintAttributes(D); |
917 | } |
918 | |
919 | void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { |
920 | |
921 | if (!Policy.SuppressSpecifiers && D->isModulePrivate()) |
922 | Out << "__module_private__ "; |
923 | Out << D->getKindName(); |
924 | |
925 | prettyPrintAttributes(D); |
926 | |
927 | if (D->getIdentifier()) { |
928 | Out << ' ' << *D; |
929 | |
930 | if (auto S = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) |
931 | printTemplateArguments(S->getTemplateArgs(), S->getTemplateParameters()); |
932 | else if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) |
933 | printTemplateArguments(S->getTemplateArgs()); |
934 | } |
935 | |
936 | if (D->isCompleteDefinition()) { |
937 | |
938 | if (D->getNumBases()) { |
939 | Out << " : "; |
940 | for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(), |
941 | BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) { |
942 | if (Base != D->bases_begin()) |
943 | Out << ", "; |
944 | |
945 | if (Base->isVirtual()) |
946 | Out << "virtual "; |
947 | |
948 | AccessSpecifier AS = Base->getAccessSpecifierAsWritten(); |
949 | if (AS != AS_none) { |
950 | Print(AS); |
951 | Out << " "; |
952 | } |
953 | Out << Base->getType().getAsString(Policy); |
954 | |
955 | if (Base->isPackExpansion()) |
956 | Out << "..."; |
957 | } |
958 | } |
959 | |
960 | |
961 | |
962 | if (Policy.TerseOutput) { |
963 | Out << " {}"; |
964 | } else { |
965 | Out << " {\n"; |
966 | VisitDeclContext(D); |
967 | Indent() << "}"; |
968 | } |
969 | } |
970 | } |
971 | |
972 | void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { |
973 | const char *l; |
974 | if (D->getLanguage() == LinkageSpecDecl::lang_c) |
975 | l = "C"; |
976 | else { |
977 | (0) . __assert_fail ("D->getLanguage() == LinkageSpecDecl..lang_cxx && \"unknown language in linkage specification\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/DeclPrinter.cpp", 978, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(D->getLanguage() == LinkageSpecDecl::lang_cxx && |
978 | (0) . __assert_fail ("D->getLanguage() == LinkageSpecDecl..lang_cxx && \"unknown language in linkage specification\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/DeclPrinter.cpp", 978, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "unknown language in linkage specification"); |
979 | l = "C++"; |
980 | } |
981 | |
982 | Out << "extern \"" << l << "\" "; |
983 | if (D->hasBraces()) { |
984 | Out << "{\n"; |
985 | VisitDeclContext(D); |
986 | Indent() << "}"; |
987 | } else |
988 | Visit(*D->decls_begin()); |
989 | } |
990 | |
991 | void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params) { |
992 | assert(Params); |
993 | |
994 | Out << "template <"; |
995 | |
996 | for (unsigned i = 0, e = Params->size(); i != e; ++i) { |
997 | if (i != 0) |
998 | Out << ", "; |
999 | |
1000 | const Decl *Param = Params->getParam(i); |
1001 | if (auto TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { |
1002 | |
1003 | if (TTP->wasDeclaredWithTypename()) |
1004 | Out << "typename "; |
1005 | else |
1006 | Out << "class "; |
1007 | |
1008 | if (TTP->isParameterPack()) |
1009 | Out << "..."; |
1010 | |
1011 | Out << *TTP; |
1012 | |
1013 | if (TTP->hasDefaultArgument()) { |
1014 | Out << " = "; |
1015 | Out << TTP->getDefaultArgument().getAsString(Policy); |
1016 | }; |
1017 | } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) { |
1018 | StringRef Name; |
1019 | if (IdentifierInfo *II = NTTP->getIdentifier()) |
1020 | Name = II->getName(); |
1021 | printDeclType(NTTP->getType(), Name, NTTP->isParameterPack()); |
1022 | |
1023 | if (NTTP->hasDefaultArgument()) { |
1024 | Out << " = "; |
1025 | NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy, |
1026 | Indentation); |
1027 | } |
1028 | } else if (auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) { |
1029 | VisitTemplateDecl(TTPD); |
1030 | |
1031 | } |
1032 | } |
1033 | |
1034 | Out << "> "; |
1035 | } |
1036 | |
1037 | void DeclPrinter::printTemplateArguments(const TemplateArgumentList &Args, |
1038 | const TemplateParameterList *Params) { |
1039 | Out << "<"; |
1040 | for (size_t I = 0, E = Args.size(); I < E; ++I) { |
1041 | const TemplateArgument &A = Args[I]; |
1042 | if (I) |
1043 | Out << ", "; |
1044 | if (Params) { |
1045 | if (A.getKind() == TemplateArgument::Type) |
1046 | if (auto T = A.getAsType()->getAs<TemplateTypeParmType>()) { |
1047 | auto P = cast<TemplateTypeParmDecl>(Params->getParam(T->getIndex())); |
1048 | Out << *P; |
1049 | continue; |
1050 | } |
1051 | if (A.getKind() == TemplateArgument::Template) { |
1052 | if (auto T = A.getAsTemplate().getAsTemplateDecl()) |
1053 | if (auto TD = dyn_cast<TemplateTemplateParmDecl>(T)) { |
1054 | auto P = cast<TemplateTemplateParmDecl>( |
1055 | Params->getParam(TD->getIndex())); |
1056 | Out << *P; |
1057 | continue; |
1058 | } |
1059 | } |
1060 | if (A.getKind() == TemplateArgument::Expression) { |
1061 | if (auto E = dyn_cast<DeclRefExpr>(A.getAsExpr())) |
1062 | if (auto N = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) { |
1063 | auto P = cast<NonTypeTemplateParmDecl>( |
1064 | Params->getParam(N->getIndex())); |
1065 | Out << *P; |
1066 | continue; |
1067 | } |
1068 | } |
1069 | } |
1070 | A.print(Policy, Out); |
1071 | } |
1072 | Out << ">"; |
1073 | } |
1074 | |
1075 | void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) { |
1076 | printTemplateParameters(D->getTemplateParameters()); |
1077 | |
1078 | if (const TemplateTemplateParmDecl *TTP = |
1079 | dyn_cast<TemplateTemplateParmDecl>(D)) { |
1080 | Out << "class "; |
1081 | if (TTP->isParameterPack()) |
1082 | Out << "..."; |
1083 | Out << D->getName(); |
1084 | } else { |
1085 | Visit(D->getTemplatedDecl()); |
1086 | } |
1087 | } |
1088 | |
1089 | void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { |
1090 | prettyPrintPragmas(D->getTemplatedDecl()); |
1091 | |
1092 | if (const FunctionDecl *FD = D->getTemplatedDecl()) { |
1093 | for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists(); |
1094 | I < NumTemplateParams; ++I) |
1095 | printTemplateParameters(FD->getTemplateParameterList(I)); |
1096 | } |
1097 | VisitRedeclarableTemplateDecl(D); |
1098 | |
1099 | |
1100 | if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>()) |
1101 | Out << "#pragma omp end declare target\n"; |
1102 | |
1103 | |
1104 | |
1105 | if (PrintInstantiation && |
1106 | !isa<CXXDeductionGuideDecl>(D->getTemplatedDecl())) { |
1107 | FunctionDecl *PrevDecl = D->getTemplatedDecl(); |
1108 | const FunctionDecl *Def; |
1109 | if (PrevDecl->isDefined(Def) && Def != PrevDecl) |
1110 | return; |
1111 | for (auto *I : D->specializations()) |
1112 | if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) { |
1113 | if (!PrevDecl->isThisDeclarationADefinition()) |
1114 | Out << ";\n"; |
1115 | Indent(); |
1116 | prettyPrintPragmas(I); |
1117 | Visit(I); |
1118 | } |
1119 | } |
1120 | } |
1121 | |
1122 | void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) { |
1123 | VisitRedeclarableTemplateDecl(D); |
1124 | |
1125 | if (PrintInstantiation) { |
1126 | for (auto *I : D->specializations()) |
1127 | if (I->getSpecializationKind() == TSK_ImplicitInstantiation) { |
1128 | if (D->isThisDeclarationADefinition()) |
1129 | Out << ";"; |
1130 | Out << "\n"; |
1131 | Visit(I); |
1132 | } |
1133 | } |
1134 | } |
1135 | |
1136 | void DeclPrinter::VisitClassTemplateSpecializationDecl( |
1137 | ClassTemplateSpecializationDecl *D) { |
1138 | Out << "template<> "; |
1139 | VisitCXXRecordDecl(D); |
1140 | } |
1141 | |
1142 | void DeclPrinter::VisitClassTemplatePartialSpecializationDecl( |
1143 | ClassTemplatePartialSpecializationDecl *D) { |
1144 | printTemplateParameters(D->getTemplateParameters()); |
1145 | VisitCXXRecordDecl(D); |
1146 | } |
1147 | |
1148 | |
1149 | |
1150 | |
1151 | |
1152 | void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx, |
1153 | Decl::ObjCDeclQualifier Quals, |
1154 | QualType T) { |
1155 | Out << '('; |
1156 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_In) |
1157 | Out << "in "; |
1158 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Inout) |
1159 | Out << "inout "; |
1160 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Out) |
1161 | Out << "out "; |
1162 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Bycopy) |
1163 | Out << "bycopy "; |
1164 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Byref) |
1165 | Out << "byref "; |
1166 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Oneway) |
1167 | Out << "oneway "; |
1168 | if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_CSNullability) { |
1169 | if (auto nullability = AttributedType::stripOuterNullability(T)) |
1170 | Out << getNullabilitySpelling(*nullability, true) << ' '; |
1171 | } |
1172 | |
1173 | Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy); |
1174 | Out << ')'; |
1175 | } |
1176 | |
1177 | void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) { |
1178 | Out << "<"; |
1179 | unsigned First = true; |
1180 | for (auto *Param : *Params) { |
1181 | if (First) { |
1182 | First = false; |
1183 | } else { |
1184 | Out << ", "; |
1185 | } |
1186 | |
1187 | switch (Param->getVariance()) { |
1188 | case ObjCTypeParamVariance::Invariant: |
1189 | break; |
1190 | |
1191 | case ObjCTypeParamVariance::Covariant: |
1192 | Out << "__covariant "; |
1193 | break; |
1194 | |
1195 | case ObjCTypeParamVariance::Contravariant: |
1196 | Out << "__contravariant "; |
1197 | break; |
1198 | } |
1199 | |
1200 | Out << Param->getDeclName().getAsString(); |
1201 | |
1202 | if (Param->hasExplicitBound()) { |
1203 | Out << " : " << Param->getUnderlyingType().getAsString(Policy); |
1204 | } |
1205 | } |
1206 | Out << ">"; |
1207 | } |
1208 | |
1209 | void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { |
1210 | if (OMD->isInstanceMethod()) |
1211 | Out << "- "; |
1212 | else |
1213 | Out << "+ "; |
1214 | if (!OMD->getReturnType().isNull()) { |
1215 | PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(), |
1216 | OMD->getReturnType()); |
1217 | } |
1218 | |
1219 | std::string name = OMD->getSelector().getAsString(); |
1220 | std::string::size_type pos, lastPos = 0; |
1221 | for (const auto *PI : OMD->parameters()) { |
1222 | |
1223 | pos = name.find_first_of(':', lastPos); |
1224 | if (lastPos != 0) |
1225 | Out << " "; |
1226 | Out << name.substr(lastPos, pos - lastPos) << ':'; |
1227 | PrintObjCMethodType(OMD->getASTContext(), |
1228 | PI->getObjCDeclQualifier(), |
1229 | PI->getType()); |
1230 | Out << *PI; |
1231 | lastPos = pos + 1; |
1232 | } |
1233 | |
1234 | if (OMD->param_begin() == OMD->param_end()) |
1235 | Out << name; |
1236 | |
1237 | if (OMD->isVariadic()) |
1238 | Out << ", ..."; |
1239 | |
1240 | prettyPrintAttributes(OMD); |
1241 | |
1242 | if (OMD->getBody() && !Policy.TerseOutput) { |
1243 | Out << ' '; |
1244 | OMD->getBody()->printPretty(Out, nullptr, Policy); |
1245 | } |
1246 | else if (Policy.PolishForDeclaration) |
1247 | Out << ';'; |
1248 | } |
1249 | |
1250 | void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { |
1251 | std::string I = OID->getNameAsString(); |
1252 | ObjCInterfaceDecl *SID = OID->getSuperClass(); |
1253 | |
1254 | bool eolnOut = false; |
1255 | if (SID) |
1256 | Out << "@implementation " << I << " : " << *SID; |
1257 | else |
1258 | Out << "@implementation " << I; |
1259 | |
1260 | if (OID->ivar_size() > 0) { |
1261 | Out << "{\n"; |
1262 | eolnOut = true; |
1263 | Indentation += Policy.Indentation; |
1264 | for (const auto *I : OID->ivars()) { |
1265 | Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()). |
1266 | getAsString(Policy) << ' ' << *I << ";\n"; |
1267 | } |
1268 | Indentation -= Policy.Indentation; |
1269 | Out << "}\n"; |
1270 | } |
1271 | else if (SID || (OID->decls_begin() != OID->decls_end())) { |
1272 | Out << "\n"; |
1273 | eolnOut = true; |
1274 | } |
1275 | VisitDeclContext(OID, false); |
1276 | if (!eolnOut) |
1277 | Out << "\n"; |
1278 | Out << "@end"; |
1279 | } |
1280 | |
1281 | void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { |
1282 | std::string I = OID->getNameAsString(); |
1283 | ObjCInterfaceDecl *SID = OID->getSuperClass(); |
1284 | |
1285 | if (!OID->isThisDeclarationADefinition()) { |
1286 | Out << "@class " << I; |
1287 | |
1288 | if (auto TypeParams = OID->getTypeParamListAsWritten()) { |
1289 | PrintObjCTypeParams(TypeParams); |
1290 | } |
1291 | |
1292 | Out << ";"; |
1293 | return; |
1294 | } |
1295 | bool eolnOut = false; |
1296 | Out << "@interface " << I; |
1297 | |
1298 | if (auto TypeParams = OID->getTypeParamListAsWritten()) { |
1299 | PrintObjCTypeParams(TypeParams); |
1300 | } |
1301 | |
1302 | if (SID) |
1303 | Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy); |
1304 | |
1305 | |
1306 | const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols(); |
1307 | if (!Protocols.empty()) { |
1308 | for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), |
1309 | E = Protocols.end(); I != E; ++I) |
1310 | Out << (I == Protocols.begin() ? '<' : ',') << **I; |
1311 | Out << "> "; |
1312 | } |
1313 | |
1314 | if (OID->ivar_size() > 0) { |
1315 | Out << "{\n"; |
1316 | eolnOut = true; |
1317 | Indentation += Policy.Indentation; |
1318 | for (const auto *I : OID->ivars()) { |
1319 | Indent() << I->getASTContext() |
1320 | .getUnqualifiedObjCPointerType(I->getType()) |
1321 | .getAsString(Policy) << ' ' << *I << ";\n"; |
1322 | } |
1323 | Indentation -= Policy.Indentation; |
1324 | Out << "}\n"; |
1325 | } |
1326 | else if (SID || (OID->decls_begin() != OID->decls_end())) { |
1327 | Out << "\n"; |
1328 | eolnOut = true; |
1329 | } |
1330 | |
1331 | VisitDeclContext(OID, false); |
1332 | if (!eolnOut) |
1333 | Out << "\n"; |
1334 | Out << "@end"; |
1335 | |
1336 | } |
1337 | |
1338 | void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { |
1339 | if (!PID->isThisDeclarationADefinition()) { |
1340 | Out << "@protocol " << *PID << ";\n"; |
1341 | return; |
1342 | } |
1343 | |
1344 | const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols(); |
1345 | if (!Protocols.empty()) { |
1346 | Out << "@protocol " << *PID; |
1347 | for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), |
1348 | E = Protocols.end(); I != E; ++I) |
1349 | Out << (I == Protocols.begin() ? '<' : ',') << **I; |
1350 | Out << ">\n"; |
1351 | } else |
1352 | Out << "@protocol " << *PID << '\n'; |
1353 | VisitDeclContext(PID, false); |
1354 | Out << "@end"; |
1355 | } |
1356 | |
1357 | void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { |
1358 | Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n"; |
1359 | |
1360 | VisitDeclContext(PID, false); |
1361 | Out << "@end"; |
1362 | |
1363 | } |
1364 | |
1365 | void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { |
1366 | Out << "@interface " << *PID->getClassInterface(); |
1367 | if (auto TypeParams = PID->getTypeParamList()) { |
1368 | PrintObjCTypeParams(TypeParams); |
1369 | } |
1370 | Out << "(" << *PID << ")\n"; |
1371 | if (PID->ivar_size() > 0) { |
1372 | Out << "{\n"; |
1373 | Indentation += Policy.Indentation; |
1374 | for (const auto *I : PID->ivars()) |
1375 | Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()). |
1376 | getAsString(Policy) << ' ' << *I << ";\n"; |
1377 | Indentation -= Policy.Indentation; |
1378 | Out << "}\n"; |
1379 | } |
1380 | |
1381 | VisitDeclContext(PID, false); |
1382 | Out << "@end"; |
1383 | |
1384 | |
1385 | } |
1386 | |
1387 | void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) { |
1388 | Out << "@compatibility_alias " << *AID |
1389 | << ' ' << *AID->getClassInterface() << ";\n"; |
1390 | } |
1391 | |
1392 | |
1393 | |
1394 | void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { |
1395 | if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required) |
1396 | Out << "@required\n"; |
1397 | else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional) |
1398 | Out << "@optional\n"; |
1399 | |
1400 | QualType T = PDecl->getType(); |
1401 | |
1402 | Out << "@property"; |
1403 | if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) { |
1404 | bool first = true; |
1405 | Out << " ("; |
1406 | if (PDecl->getPropertyAttributes() & |
1407 | ObjCPropertyDecl::OBJC_PR_readonly) { |
1408 | Out << (first ? ' ' : ',') << "readonly"; |
1409 | first = false; |
1410 | } |
1411 | |
1412 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { |
1413 | Out << (first ? ' ' : ',') << "getter = "; |
1414 | PDecl->getGetterName().print(Out); |
1415 | first = false; |
1416 | } |
1417 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { |
1418 | Out << (first ? ' ' : ',') << "setter = "; |
1419 | PDecl->getSetterName().print(Out); |
1420 | first = false; |
1421 | } |
1422 | |
1423 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) { |
1424 | Out << (first ? ' ' : ',') << "assign"; |
1425 | first = false; |
1426 | } |
1427 | |
1428 | if (PDecl->getPropertyAttributes() & |
1429 | ObjCPropertyDecl::OBJC_PR_readwrite) { |
1430 | Out << (first ? ' ' : ',') << "readwrite"; |
1431 | first = false; |
1432 | } |
1433 | |
1434 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) { |
1435 | Out << (first ? ' ' : ',') << "retain"; |
1436 | first = false; |
1437 | } |
1438 | |
1439 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_strong) { |
1440 | Out << (first ? ' ' : ',') << "strong"; |
1441 | first = false; |
1442 | } |
1443 | |
1444 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) { |
1445 | Out << (first ? ' ' : ',') << "copy"; |
1446 | first = false; |
1447 | } |
1448 | |
1449 | if (PDecl->getPropertyAttributes() & |
1450 | ObjCPropertyDecl::OBJC_PR_nonatomic) { |
1451 | Out << (first ? ' ' : ',') << "nonatomic"; |
1452 | first = false; |
1453 | } |
1454 | if (PDecl->getPropertyAttributes() & |
1455 | ObjCPropertyDecl::OBJC_PR_atomic) { |
1456 | Out << (first ? ' ' : ',') << "atomic"; |
1457 | first = false; |
1458 | } |
1459 | |
1460 | if (PDecl->getPropertyAttributes() & |
1461 | ObjCPropertyDecl::OBJC_PR_nullability) { |
1462 | if (auto nullability = AttributedType::stripOuterNullability(T)) { |
1463 | if (*nullability == NullabilityKind::Unspecified && |
1464 | (PDecl->getPropertyAttributes() & |
1465 | ObjCPropertyDecl::OBJC_PR_null_resettable)) { |
1466 | Out << (first ? ' ' : ',') << "null_resettable"; |
1467 | } else { |
1468 | Out << (first ? ' ' : ',') |
1469 | << getNullabilitySpelling(*nullability, true); |
1470 | } |
1471 | first = false; |
1472 | } |
1473 | } |
1474 | |
1475 | if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_class) { |
1476 | Out << (first ? ' ' : ',') << "class"; |
1477 | first = false; |
1478 | } |
1479 | |
1480 | (void) first; |
1481 | Out << " )"; |
1482 | } |
1483 | Out << ' ' << PDecl->getASTContext().getUnqualifiedObjCPointerType(T). |
1484 | getAsString(Policy) << ' ' << *PDecl; |
1485 | if (Policy.PolishForDeclaration) |
1486 | Out << ';'; |
1487 | } |
1488 | |
1489 | void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { |
1490 | if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) |
1491 | Out << "@synthesize "; |
1492 | else |
1493 | Out << "@dynamic "; |
1494 | Out << *PID->getPropertyDecl(); |
1495 | if (PID->getPropertyIvarDecl()) |
1496 | Out << '=' << *PID->getPropertyIvarDecl(); |
1497 | } |
1498 | |
1499 | void DeclPrinter::VisitUsingDecl(UsingDecl *D) { |
1500 | if (!D->isAccessDeclaration()) |
1501 | Out << "using "; |
1502 | if (D->hasTypename()) |
1503 | Out << "typename "; |
1504 | D->getQualifier()->print(Out, Policy); |
1505 | |
1506 | |
1507 | |
1508 | for (const auto *Shadow : D->shadows()) { |
1509 | if (const auto *ConstructorShadow = |
1510 | dyn_cast<ConstructorUsingShadowDecl>(Shadow)) { |
1511 | getDeclContext() == ConstructorShadow->getDeclContext()", "/home/seafit/code_projects/clang_source/clang/lib/AST/DeclPrinter.cpp", 1511, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext()); |
1512 | Out << *ConstructorShadow->getNominatedBaseClass(); |
1513 | return; |
1514 | } |
1515 | } |
1516 | Out << *D; |
1517 | } |
1518 | |
1519 | void |
1520 | DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { |
1521 | Out << "using typename "; |
1522 | D->getQualifier()->print(Out, Policy); |
1523 | Out << D->getDeclName(); |
1524 | } |
1525 | |
1526 | void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { |
1527 | if (!D->isAccessDeclaration()) |
1528 | Out << "using "; |
1529 | D->getQualifier()->print(Out, Policy); |
1530 | Out << D->getDeclName(); |
1531 | } |
1532 | |
1533 | void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { |
1534 | |
1535 | } |
1536 | |
1537 | void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { |
1538 | Out << "#pragma omp threadprivate"; |
1539 | if (!D->varlist_empty()) { |
1540 | for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), |
1541 | E = D->varlist_end(); |
1542 | I != E; ++I) { |
1543 | Out << (I == D->varlist_begin() ? '(' : ','); |
1544 | NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl(); |
1545 | ND->printQualifiedName(Out); |
1546 | } |
1547 | Out << ")"; |
1548 | } |
1549 | } |
1550 | |
1551 | void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) { |
1552 | Out << "#pragma omp allocate"; |
1553 | if (!D->varlist_empty()) { |
1554 | for (OMPAllocateDecl::varlist_iterator I = D->varlist_begin(), |
1555 | E = D->varlist_end(); |
1556 | I != E; ++I) { |
1557 | Out << (I == D->varlist_begin() ? '(' : ','); |
1558 | NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl(); |
1559 | ND->printQualifiedName(Out); |
1560 | } |
1561 | Out << ")"; |
1562 | } |
1563 | if (!D->clauselist_empty()) { |
1564 | Out << " "; |
1565 | OMPClausePrinter Printer(Out, Policy); |
1566 | for (OMPClause *C : D->clauselists()) |
1567 | Printer.Visit(C); |
1568 | } |
1569 | } |
1570 | |
1571 | void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { |
1572 | Out << "#pragma omp requires "; |
1573 | if (!D->clauselist_empty()) { |
1574 | OMPClausePrinter Printer(Out, Policy); |
1575 | for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I) |
1576 | Printer.Visit(*I); |
1577 | } |
1578 | } |
1579 | |
1580 | void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { |
1581 | if (!D->isInvalidDecl()) { |
1582 | Out << "#pragma omp declare reduction ("; |
1583 | if (D->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) { |
1584 | static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = { |
1585 | nullptr, |
1586 | #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ |
1587 | Spelling, |
1588 | #include "clang/Basic/OperatorKinds.def" |
1589 | }; |
1590 | const char *OpName = |
1591 | OperatorNames[D->getDeclName().getCXXOverloadedOperator()]; |
1592 | (0) . __assert_fail ("OpName && \"not an overloaded operator\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/DeclPrinter.cpp", 1592, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(OpName && "not an overloaded operator"); |
1593 | Out << OpName; |
1594 | } else { |
1595 | getDeclName().isIdentifier()", "/home/seafit/code_projects/clang_source/clang/lib/AST/DeclPrinter.cpp", 1595, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(D->getDeclName().isIdentifier()); |
1596 | D->printName(Out); |
1597 | } |
1598 | Out << " : "; |
1599 | D->getType().print(Out, Policy); |
1600 | Out << " : "; |
1601 | D->getCombiner()->printPretty(Out, nullptr, Policy, 0); |
1602 | Out << ")"; |
1603 | if (auto *Init = D->getInitializer()) { |
1604 | Out << " initializer("; |
1605 | switch (D->getInitializerKind()) { |
1606 | case OMPDeclareReductionDecl::DirectInit: |
1607 | Out << "omp_priv("; |
1608 | break; |
1609 | case OMPDeclareReductionDecl::CopyInit: |
1610 | Out << "omp_priv = "; |
1611 | break; |
1612 | case OMPDeclareReductionDecl::CallInit: |
1613 | break; |
1614 | } |
1615 | Init->printPretty(Out, nullptr, Policy, 0); |
1616 | if (D->getInitializerKind() == OMPDeclareReductionDecl::DirectInit) |
1617 | Out << ")"; |
1618 | Out << ")"; |
1619 | } |
1620 | } |
1621 | } |
1622 | |
1623 | void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { |
1624 | if (!D->isInvalidDecl()) { |
1625 | Out << "#pragma omp declare mapper ("; |
1626 | D->printName(Out); |
1627 | Out << " : "; |
1628 | D->getType().print(Out, Policy); |
1629 | Out << " "; |
1630 | Out << D->getVarName(); |
1631 | Out << ")"; |
1632 | if (!D->clauselist_empty()) { |
1633 | OMPClausePrinter Printer(Out, Policy); |
1634 | for (auto *C : D->clauselists()) { |
1635 | Out << " "; |
1636 | Printer.Visit(C); |
1637 | } |
1638 | } |
1639 | } |
1640 | } |
1641 | |
1642 | void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { |
1643 | D->getInit()->printPretty(Out, nullptr, Policy, Indentation); |
1644 | } |
1645 | |
1646 | |