aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/TypePrinter.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-10 11:27:22 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-10 11:27:22 +0000
commit7c2342dd4c9947806842e5aca3d2bb2e542853c9 (patch)
tree9791dad988e7ab05776a61a84c66234aeef17f31 /lib/AST/TypePrinter.cpp
parente5ea0cae7769866b5a5f9fa979e7c9d1d23a6bcc (diff)
When pretty-printing tag types, only print the tag if we're in C (and
therefore not creating ElaboratedTypes, which are still pretty-printed with the written tag). Most of these testcase changes were done by script, so don't feel too sorry for my fingers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98149 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/TypePrinter.cpp')
-rw-r--r--lib/AST/TypePrinter.cpp121
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);