//===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Decl::dump method, which pretty print the
// AST back out to C/Objective-C/C++/Objective-C++ code.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
namespace {
class DeclPrinter : public DeclVisitor<DeclPrinter> {
llvm::raw_ostream &Out;
ASTContext &Context;
PrintingPolicy Policy;
unsigned Indentation;
llvm::raw_ostream& Indent() { return Indent(Indentation); }
llvm::raw_ostream& Indent(unsigned Indentation);
void ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls);
void Print(AccessSpecifier AS);
public:
DeclPrinter(llvm::raw_ostream &Out, ASTContext &Context,
const PrintingPolicy &Policy,
unsigned Indentation = 0)
: Out(Out), Context(Context), Policy(Policy), Indentation(Indentation) { }
void VisitDeclContext(DeclContext *DC, bool Indent = true);
void VisitTranslationUnitDecl(TranslationUnitDecl *D);
void VisitTypedefDecl(TypedefDecl *D);
void VisitEnumDecl(EnumDecl *D);
void VisitRecordDecl(RecordDecl *D);
void VisitEnumConstantDecl(EnumConstantDecl *D);
void VisitFunctionDecl(FunctionDecl *D);
void VisitFieldDecl(FieldDecl *D);
void VisitVarDecl(VarDecl *D);
void VisitParmVarDecl(ParmVarDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
void VisitCXXRecordDecl(CXXRecordDecl *D);
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitObjCMethodDecl(ObjCMethodDecl *D);
void VisitObjCClassDecl(ObjCClassDecl *D);
void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
};
}
void Decl::print(llvm::raw_ostream &Out, unsigned Indentation) const {
print(Out, getASTContext().PrintingPolicy, Indentation);
}
void Decl::print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation) const {
DeclPrinter Printer(Out, getASTContext(), Policy, Indentation);
Printer.Visit(const_cast<Decl*>(this));
}
static QualType 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->getAs<PointerType>())
BaseType = PTy->getPointeeType();
else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
BaseType = ATy->getElementType();
else if (const FunctionType* FTy = BaseType->getAs<FunctionType>())
BaseType = FTy->getResultType();
else if (const VectorType *VTy = BaseType->getAs<VectorType>())
BaseType = VTy->getElementType();
else
assert(0 && "Unknown declarator!");
}
return BaseType;
}
static QualType getDeclType(Decl* D) {
if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(D))
return TDD->getUnderlyingType();
if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
return VD->getType();
return QualType();
}
void Decl::printGroup(Decl** Begin, unsigned NumDecls,
<