diff options
111 files changed, 484 insertions, 483 deletions
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 0635ec5dcd..587b5c2b40 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -36,7 +36,7 @@ struct PrintingPolicy { /// \brief Create a default printing policy for C. PrintingPolicy(const LangOptions &LO) : Indentation(2), LangOpts(LO), SuppressSpecifiers(false), - SuppressTag(false), SuppressTagKind(false), SuppressScope(false), + SuppressTag(false), SuppressScope(false), Dump(false), ConstantArraySizeAsWritten(false) { } /// \brief The number of spaces to use to indent each line. @@ -71,10 +71,6 @@ struct PrintingPolicy { /// \endcode bool SuppressTag : 1; - /// \brief If we are printing a tag type, suppresses printing of the - /// kind of tag, e.g., "struct", "union", "enum". - bool SuppressTagKind : 1; - /// \brief Suppresses printing of scope specifiers. bool SuppressScope : 1; @@ -101,6 +97,7 @@ struct PrintingPolicy { /// char a[9] = "A string"; /// \endcode bool ConstantArraySizeAsWritten : 1; + }; } // end namespace clang diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index c08a3a26e1..efd0fd1b8d 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -181,7 +181,6 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { } PrintingPolicy Policy(Context.getLangOptions()); - Policy.SuppressTagKind = true; std::string Proto = FD->getQualifiedNameAsString(Policy); diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index e26c0bba49..45518e98bc 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -142,7 +142,6 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS, Type *T = getAsType(); PrintingPolicy InnerPolicy(Policy); - InnerPolicy.SuppressTagKind = true; InnerPolicy.SuppressScope = true; // Nested-name-specifiers are intended to contain minimally-qualified diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 6e88ca32ca..037bc14e7a 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -30,6 +30,7 @@ namespace { explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { } void Print(QualType T, std::string &S); + void AppendScope(DeclContext *DC, std::string &S); void PrintTag(TagDecl *T, std::string &S); #define ABSTRACT_TYPE(CLASS, PARENT) #define TYPE(CLASS, PARENT) \ @@ -373,28 +374,71 @@ void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { S = "decltype(" + s.str() + ")" + S; } +/// Appends the given scope to the end of a string. +void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) { + if (DC->isTranslationUnit()) return; + AppendScope(DC->getParent(), Buffer); + + unsigned OldSize = Buffer.size(); + + if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { + if (NS->getIdentifier()) + Buffer += NS->getNameAsString(); + else + Buffer += "<anonymous>"; + } else if (ClassTemplateSpecializationDecl *Spec + = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + std::string TemplateArgsStr + = TemplateSpecializationType::PrintTemplateArgumentList( + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size(), + Policy); + Buffer += Spec->getIdentifier()->getName(); + Buffer += TemplateArgsStr; + } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { + if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) + Buffer += Typedef->getIdentifier()->getName(); + else if (Tag->getIdentifier()) + Buffer += Tag->getIdentifier()->getName(); + } + + if (Buffer.size() != OldSize) + Buffer += "::"; +} + void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) { if (Policy.SuppressTag) return; - - if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. - InnerString = ' ' + InnerString; - - const char *Kind = Policy.SuppressTagKind? 0 : D->getKindName(); + + std::string Buffer; + + // We don't print tags unless this is an elaborated type. + // In C, we just assume every RecordType is an elaborated type. + if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) { + Buffer += D->getKindName(); + Buffer += ' '; + } + + if (!Policy.SuppressScope) + // Compute the full nested-name-specifier for this type. In C, + // this will always be empty. + AppendScope(D->getDeclContext(), Buffer); + const char *ID; if (const IdentifierInfo *II = D->getIdentifier()) ID = II->getNameStart(); else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) { - Kind = 0; assert(Typedef->getIdentifier() && "Typedef without identifier?"); ID = Typedef->getIdentifier()->getNameStart(); } else ID = "<anonymous>"; - + Buffer += ID; + // If this is a class template specialization, print the template // arguments. if (ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(D)) { + = dyn_cast<ClassTemplateSpecializationDecl>(D)) { const TemplateArgument *Args; unsigned NumArgs; if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { |