diff options
Diffstat (limited to 'lib/AST/DeclPrinter.cpp')
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 193 |
1 files changed, 143 insertions, 50 deletions
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 386ad66..c3bf8f8 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -7,15 +7,16 @@ // //===----------------------------------------------------------------------===// // -// This file implements the Decl::dump method, which pretty print the +// This file implements the Decl::print method, which pretty prints the // AST back out to C/Objective-C/C++/Objective-C++ code. // //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" -#include "clang/AST/DeclVisitor.h" +#include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyPrinter.h" @@ -50,7 +51,9 @@ namespace { void VisitEnumDecl(EnumDecl *D); void VisitRecordDecl(RecordDecl *D); void VisitEnumConstantDecl(EnumConstantDecl *D); + void VisitEmptyDecl(EmptyDecl *D); void VisitFunctionDecl(FunctionDecl *D); + void VisitFriendDecl(FriendDecl *D); void VisitFieldDecl(FieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitLabelDecl(LabelDecl *D); @@ -79,9 +82,10 @@ namespace { void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); void VisitUsingDecl(UsingDecl *D); void VisitUsingShadowDecl(UsingShadowDecl *D); + void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); void PrintTemplateParameters(const TemplateParameterList *Params, - const TemplateArgumentList *Args); + const TemplateArgumentList *Args = 0); void prettyPrintAttributes(Decl *D); }; } @@ -174,16 +178,6 @@ void DeclContext::dumpDeclContext() const { Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false); } -void Decl::dump() const { - dump(llvm::errs()); -} - -void Decl::dump(raw_ostream &Out) const { - PrintingPolicy Policy = getASTContext().getPrintingPolicy(); - Policy.DumpSourceManager = &getASTContext().getSourceManager(); - print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ true); -} - raw_ostream& DeclPrinter::Indent(unsigned Indentation) { for (unsigned i = 0; i != Indentation; ++i) Out << " "; @@ -191,7 +185,7 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) { } void DeclPrinter::prettyPrintAttributes(Decl *D) { - if (Policy.SuppressAttributes) + if (Policy.PolishForDeclaration) return; if (D->hasAttrs()) { @@ -240,18 +234,18 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (isa<ObjCIvarDecl>(*D)) continue; - if (!Policy.DumpSourceManager) { - // Skip over implicit declarations in pretty-printing mode. - if (D->isImplicit()) continue; - // FIXME: Ugly hack so we don't pretty-print the builtin declaration - // of __builtin_va_list or __[u]int128_t. There should be some other way - // to check that. - if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) { - if (IdentifierInfo *II = ND->getIdentifier()) { - if (II->isStr("__builtin_va_list") || - II->isStr("__int128_t") || II->isStr("__uint128_t")) - continue; - } + // Skip over implicit declarations in pretty-printing mode. + if (D->isImplicit()) + continue; + + // FIXME: Ugly hack so we don't pretty-print the builtin declaration + // of __builtin_va_list or __[u]int128_t. There should be some other way + // to check that. + if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) { + if (IdentifierInfo *II = ND->getIdentifier()) { + if (II->isStr("__builtin_va_list") || + II->isStr("__int128_t") || II->isStr("__uint128_t")) + continue; } } @@ -298,8 +292,10 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { // FIXME: Need to be able to tell the DeclPrinter when const char *Terminator = 0; - if (isa<FunctionDecl>(*D) && - cast<FunctionDecl>(*D)->isThisDeclarationADefinition()) + if (isa<OMPThreadPrivateDecl>(*D)) + Terminator = 0; + else if (isa<FunctionDecl>(*D) && + cast<FunctionDecl>(*D)->isThisDeclarationADefinition()) Terminator = 0; else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody()) Terminator = 0; @@ -395,8 +391,9 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) { } void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { + CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D); if (!Policy.SuppressSpecifiers) { - switch (D->getStorageClassAsWritten()) { + switch (D->getStorageClass()) { case SC_None: break; case SC_Extern: Out << "extern "; break; case SC_Static: Out << "static "; break; @@ -408,6 +405,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (D->isInlineSpecified()) Out << "inline "; if (D->isVirtualAsWritten()) Out << "virtual "; if (D->isModulePrivate()) Out << "__module_private__ "; + if (CDecl && CDecl->isExplicitSpecified()) + Out << "explicit "; } PrintingPolicy SubPolicy(Policy); @@ -483,7 +482,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } } - if (CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D)) { + if (CDecl) { bool HasInitializerList = false; for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(), E = CDecl->init_end(); @@ -545,9 +544,15 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } Out << ")"; } - } - else + if (!Proto.empty()) + Out << Proto; + } else { + if (FT && FT->hasTrailingReturn()) { + Out << "auto " << Proto << " -> "; + Proto.clear(); + } AFT->getResultType().print(Out, Policy, Proto); + } } else { Ty.print(Out, Policy, Proto); } @@ -558,6 +563,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { Out << " = 0"; else if (D->isDeletedAsWritten()) Out << " = delete"; + else if (D->isExplicitlyDefaulted()) + Out << " = default"; else if (D->doesThisDeclarationHaveABody() && !Policy.TerseOutput) { if (!D->hasPrototype() && D->getNumParams()) { // This is a K&R function definition, so we need to print the @@ -579,6 +586,31 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } } +void DeclPrinter::VisitFriendDecl(FriendDecl *D) { + if (TypeSourceInfo *TSI = D->getFriendType()) { + unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists(); + for (unsigned i = 0; i < NumTPLists; ++i) + PrintTemplateParameters(D->getFriendTypeTemplateParameterList(i)); + Out << "friend "; + Out << " " << TSI->getType().getAsString(Policy); + } + else if (FunctionDecl *FD = + dyn_cast<FunctionDecl>(D->getFriendDecl())) { + Out << "friend "; + VisitFunctionDecl(FD); + } + else if (FunctionTemplateDecl *FTD = + dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) { + Out << "friend "; + VisitFunctionTemplateDecl(FTD); + } + else if (ClassTemplateDecl *CTD = + dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) { + Out << "friend "; + VisitRedeclarableTemplateDecl(CTD); + } +} + void DeclPrinter::VisitFieldDecl(FieldDecl *D) { if (!Policy.SuppressSpecifiers && D->isMutable()) Out << "mutable "; @@ -609,9 +641,9 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) { void DeclPrinter::VisitVarDecl(VarDecl *D) { - StorageClass SCAsWritten = D->getStorageClassAsWritten(); - if (!Policy.SuppressSpecifiers && SCAsWritten != SC_None) - Out << VarDecl::getStorageClassSpecifierString(SCAsWritten) << " "; + StorageClass SC = D->getStorageClass(); + if (!Policy.SuppressSpecifiers && SC != SC_None) + Out << VarDecl::getStorageClassSpecifierString(SC) << " "; if (!Policy.SuppressSpecifiers && D->isThreadSpecified()) Out << "__thread "; @@ -625,9 +657,14 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { Expr *Init = D->getInit(); if (!Policy.SuppressInitializers && Init) { bool ImplicitInit = false; - if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) - ImplicitInit = D->getInitStyle() == VarDecl::CallInit && - Construct->getNumArgs() == 0 && !Construct->isListInitialization(); + if (CXXConstructExpr *Construct = + dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) { + if (D->getInitStyle() == VarDecl::CallInit && + !Construct->isListInitialization()) { + ImplicitInit = Construct->getNumArgs() == 0 || + Construct->getArg(0)->isDefaultArgument(); + } + } if (!ImplicitInit) { if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init)) Out << "("; @@ -653,7 +690,7 @@ void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { } void DeclPrinter::VisitImportDecl(ImportDecl *D) { - Out << "@__experimental_modules_import " << D->getImportedModule()->getFullModuleName() + Out << "@import " << D->getImportedModule()->getFullModuleName() << ";\n"; } @@ -690,6 +727,10 @@ void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { Out << *D->getAliasedNamespace(); } +void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) { + prettyPrintAttributes(D); +} + void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { if (!Policy.SuppressSpecifiers && D->isModulePrivate()) Out << "__module_private__ "; @@ -746,8 +787,8 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { Visit(*D->decls_begin()); } -void DeclPrinter::PrintTemplateParameters( - const TemplateParameterList *Params, const TemplateArgumentList *Args = 0) { +void DeclPrinter::PrintTemplateParameters(const TemplateParameterList *Params, + const TemplateArgumentList *Args) { assert(Params); assert(!Args || Params->size() == Args->size()); @@ -882,6 +923,8 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { OMD->getBody()->printPretty(Out, 0, Policy); Out << '\n'; } + else if (Policy.PolishForDeclaration) + Out << ';'; } void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { @@ -892,7 +935,17 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { Out << "@implementation " << I << " : " << *SID; else Out << "@implementation " << I; - Out << "\n"; + + if (OID->ivar_size() > 0) { + Out << "{\n"; + Indentation += Policy.Indentation; + for (ObjCImplementationDecl::ivar_iterator I = OID->ivar_begin(), + E = OID->ivar_end(); I != E; ++I) { + Indent() << I->getType().getAsString(Policy) << ' ' << **I << ";\n"; + } + Indentation -= Policy.Indentation; + Out << "}\n"; + } VisitDeclContext(OID, false); Out << "@end"; } @@ -905,7 +958,7 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { Out << "@class " << I << ";"; return; } - + bool eolnOut = false; if (SID) Out << "@interface " << I << " : " << *SID; else @@ -917,13 +970,12 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) Out << (I == Protocols.begin() ? '<' : ',') << **I; - } - - if (!Protocols.empty()) Out << "> "; + } if (OID->ivar_size() > 0) { Out << "{\n"; + eolnOut = true; Indentation += Policy.Indentation; for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(), E = OID->ivar_end(); I != E; ++I) { @@ -932,19 +984,33 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { Indentation -= Policy.Indentation; Out << "}\n"; } + else if (SID) { + Out << "\n"; + eolnOut = true; + } VisitDeclContext(OID, false); + if (!eolnOut) + Out << ' '; Out << "@end"; // FIXME: implement the rest... } void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { if (!PID->isThisDeclarationADefinition()) { - Out << "@protocol " << PID->getIdentifier() << ";\n"; + Out << "@protocol " << *PID << ";\n"; return; } - - Out << "@protocol " << *PID << '\n'; + // Protocols? + const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols(); + if (!Protocols.empty()) { + Out << "@protocol " << *PID; + for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), + E = Protocols.end(); I != E; ++I) + Out << (I == Protocols.begin() ? '<' : ',') << **I; + Out << ">\n"; + } else + Out << "@protocol " << *PID << '\n'; VisitDeclContext(PID, false); Out << "@end"; } @@ -959,6 +1025,17 @@ void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { Out << "@interface " << *PID->getClassInterface() << '(' << *PID << ")\n"; + if (PID->ivar_size() > 0) { + Out << "{\n"; + Indentation += Policy.Indentation; + for (ObjCCategoryDecl::ivar_iterator I = PID->ivar_begin(), + E = PID->ivar_end(); I != E; ++I) { + Indent() << I->getType().getAsString(Policy) << ' ' << **I << ";\n"; + } + Indentation -= Policy.Indentation; + Out << "}\n"; + } + VisitDeclContext(PID, false); Out << "@end"; @@ -1040,6 +1117,8 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { Out << " )"; } Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << *PDecl; + if (Policy.PolishForDeclaration) + Out << ';'; } void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { @@ -1068,9 +1147,23 @@ DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { Out << "using "; D->getQualifier()->print(Out, Policy); - Out << D->getDeclName(); + Out << D->getName(); } void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { // ignore } + +void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { + Out << "#pragma omp threadprivate"; + if (!D->varlist_empty()) { + for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), + E = D->varlist_end(); + I != E; ++I) { + Out << (I == D->varlist_begin() ? '(' : ',') + << *cast<NamedDecl>((*I)->getDecl()); + } + Out << ")"; + } +} + |