diff options
Diffstat (limited to 'lib/AST/TypePrinter.cpp')
-rw-r--r-- | lib/AST/TypePrinter.cpp | 121 |
1 files changed, 64 insertions, 57 deletions
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()) { @@ -407,48 +451,17 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) { Args = TemplateArgs.getFlatArgumentList(); NumArgs = TemplateArgs.flat_size(); } - std::string TemplateArgsStr - = TemplateSpecializationType::PrintTemplateArgumentList(Args, NumArgs, - Policy); - InnerString = TemplateArgsStr + InnerString; + Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args, + NumArgs, + Policy); } - - if (!Policy.SuppressScope) { - // Compute the full nested-name-specifier for this type. In C, - // this will always be empty. - std::string ContextStr; - for (DeclContext *DC = D->getDeclContext(); - !DC->isTranslationUnit(); DC = DC->getParent()) { - std::string MyPart; - if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { - if (NS->getIdentifier()) - MyPart = NS->getNameAsString(); - } else if (ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { - const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - std::string TemplateArgsStr - = TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size(), - Policy); - MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr; - } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { - if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) - MyPart = Typedef->getIdentifier()->getName(); - else if (Tag->getIdentifier()) - MyPart = Tag->getIdentifier()->getName(); - } - - if (!MyPart.empty()) - ContextStr = MyPart + "::" + ContextStr; - } - - if (Kind) - InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString; - else - InnerString = ContextStr + ID + InnerString; - } else - InnerString = ID + InnerString; + + if (!InnerString.empty()) { + Buffer += ' '; + Buffer += InnerString; + } + + std::swap(Buffer, InnerString); } void TypePrinter::PrintRecord(const RecordType *T, std::string &S) { @@ -460,11 +473,7 @@ void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { } void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { - std::string TypeStr; - PrintingPolicy InnerPolicy(Policy); - InnerPolicy.SuppressTagKind = true; - TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S); - + Print(T->getUnderlyingType(), S); S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S; } @@ -507,8 +516,7 @@ void TypePrinter::PrintTemplateSpecialization( void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T, std::string &S) { - // TODO: this should probably be printed with template arguments - PrintTag(T->getDecl(), S); + PrintTemplateSpecialization(T->getUnderlyingTST(), S); } void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, @@ -522,7 +530,6 @@ void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, std::string TypeStr; PrintingPolicy InnerPolicy(Policy); - InnerPolicy.SuppressTagKind = true; InnerPolicy.SuppressScope = true; TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr); |