Some enhancements to DeclStmt printing. Some of this should

move to DeclPrinter.cpp, but I haven't quite worked out how best to do 
that.

llvm-svn: 72599
This commit is contained in:
Eli Friedman 2009-05-30 00:19:54 +00:00
parent d5ef49ff54
commit 15ea880358
1 changed files with 141 additions and 24 deletions

View File

@ -56,11 +56,15 @@ namespace {
}
IndentLevel -= SubIndent;
}
QualType GetBaseType(QualType T);
void PrintBaseType(QualType T, TagDecl* TD);
void PrintDeclIdentifier(NamedDecl* ND);
void PrintRawCompoundStmt(CompoundStmt *S);
void PrintRawDecl(Decl *D);
void PrintRawDeclStmt(DeclStmt *S);
void PrintFieldDecl(FieldDecl *FD);
void PrintEnumConstantDecl(EnumConstantDecl *ECD);
void PrintRawIfStmt(IfStmt *If);
void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
@ -112,6 +116,57 @@ void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
Indent() << "}";
}
QualType StmtPrinter::GetBaseType(QualType T) {
// FIXME: This should be on the Type class!
QualType BaseType = T;
while (!BaseType->isSpecifierType()) {
if (isa<TypedefType>(BaseType))
break;
else if (const PointerType* PTy = BaseType->getAsPointerType())
BaseType = PTy->getPointeeType();
else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
BaseType = ATy->getElementType();
else if (const FunctionType* FTy = BaseType->getAsFunctionType())
BaseType = FTy->getResultType();
else
assert(0 && "Unknown declarator!");
}
return BaseType;
}
void StmtPrinter::PrintBaseType(QualType BaseType, TagDecl* TD) {
std::string BaseString;
if (TD && TD->isDefinition()) {
// FIXME: This is an ugly hack; perhaps we can expose something better
// from Type.h?
if (BaseType.isConstQualified())
OS << "const ";
PrintRawDecl(TD);
OS << " ";
} else {
BaseType.getAsStringInternal(BaseString, Policy);
OS << BaseString << " ";
}
}
void StmtPrinter::PrintDeclIdentifier(NamedDecl* ND) {
std::string Name = ND->getNameAsString();
QualType Ty;
if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(ND)) {
Ty = TDD->getUnderlyingType();
} else if (ValueDecl* VD = dyn_cast<ValueDecl>(ND)) {
Ty = VD->getType();
} else {
assert(0 && "Unexpected decl");
}
PrintingPolicy SubPolicy(Policy);
SubPolicy.SuppressTypeSpecifiers = true;
Ty.getAsStringInternal(Name, SubPolicy);
OS << Name;
}
void StmtPrinter::PrintRawDecl(Decl *D) {
// FIXME: Need to complete/beautify this... this code simply shows the
// nodes are where they need to be.
@ -143,16 +198,28 @@ void StmtPrinter::PrintRawDecl(Decl *D) {
OS << " ";
if (const IdentifierInfo *II = TD->getIdentifier())
OS << II->getName();
if (RecordDecl *RD = dyn_cast<RecordDecl>(TD)) {
OS << "{\n";
IndentLevel += 1;
// FIXME: The context passed to field_begin/field_end should
// never be NULL!
ASTContext *Context = 0;
for (RecordDecl::field_iterator i = RD->field_begin(*Context);
i != RD->field_end(*Context); ++i) {
PrintFieldDecl(*i);
IndentLevel -= 1;
if (TD->isDefinition()) {
if (RecordDecl *RD = dyn_cast<RecordDecl>(TD)) {
OS << "{\n";
IndentLevel += 1;
// FIXME: The context passed to field_begin/field_end should
// never be NULL!
ASTContext *Context = 0;
for (RecordDecl::field_iterator i = RD->field_begin(*Context);
i != RD->field_end(*Context); ++i)
PrintFieldDecl(*i);
IndentLevel -= 1;
Indent() << "}";
} else if (EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
OS << "{\n";
IndentLevel += 1;
// FIXME: The context shouldn't be NULL!
ASTContext *Context = 0;
for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Context);
i != ED->enumerator_end(*Context); ++i)
PrintEnumConstantDecl(*i);
IndentLevel -= 1;
Indent() << "}";
}
}
} else {
@ -161,19 +228,72 @@ void StmtPrinter::PrintRawDecl(Decl *D) {
}
void StmtPrinter::PrintFieldDecl(FieldDecl *FD) {
Indent() << FD->getNameAsString() << "\n";
Indent();
QualType BaseType = GetBaseType(FD->getType());
PrintBaseType(BaseType, 0);
PrintDeclIdentifier(FD);
if (FD->isBitField()) {
OS << " : ";
PrintExpr(FD->getBitWidth());
}
OS << ";\n";
}
void StmtPrinter::PrintEnumConstantDecl(EnumConstantDecl *ECD) {
Indent() << ECD->getNameAsString();
if (ECD->getInitExpr()) {
OS << " = ";
PrintExpr(ECD->getInitExpr());
}
OS << ",\n";
}
void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
TagDecl* TD = dyn_cast<TagDecl>(*Begin);
if (TD)
++Begin;
if (isa<TypedefDecl>(*Begin))
OS << "typedef ";
else if (VarDecl *V = dyn_cast<VarDecl>(*Begin)) {
switch (V->getStorageClass()) {
default: assert(0 && "Unknown storage class!");
case VarDecl::None: break;
case VarDecl::Auto: OS << "auto "; break;
case VarDecl::Register: OS << "register "; break;
case VarDecl::Extern: OS << "extern "; break;
case VarDecl::Static: OS << "static "; break;
case VarDecl::PrivateExtern: OS << "__private_extern__ "; break;
}
} else if (FunctionDecl *V = dyn_cast<FunctionDecl>(*Begin)) {
switch (V->getStorageClass()) {
default: assert(0 && "Unknown storage class!");
case FunctionDecl::None: break;
case FunctionDecl::Extern: OS << "extern "; break;
case FunctionDecl::Static: OS << "static "; break;
case FunctionDecl::PrivateExtern: OS << "__private_extern__ "; break;
}
} else {
assert(0 && "Unhandled decl");
}
QualType BaseType;
if (ValueDecl* VD = dyn_cast<ValueDecl>(*Begin)) {
BaseType = VD->getType();
} else {
BaseType = cast<TypedefDecl>(*Begin)->getUnderlyingType();
}
BaseType = GetBaseType(BaseType);
PrintBaseType(BaseType, TD);
bool isFirst = true;
for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
for ( ; Begin != End; ++Begin) {
if (!isFirst) OS << ", ";
else isFirst = false;
PrintRawDecl(*I);
PrintDeclIdentifier(cast<NamedDecl>(*Begin));
}
}
@ -182,12 +302,9 @@ void StmtPrinter::VisitNullStmt(NullStmt *Node) {
}
void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end();
I!=E; ++I) {
Indent();
PrintRawDecl(*I);
OS << ";\n";
}
Indent();
PrintRawDeclStmt(Node);
OS << ";\n";
}
void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {