forked from OSchip/llvm-project
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:
parent
d5ef49ff54
commit
15ea880358
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue