2012-12-13 21:59:55 +08:00
|
|
|
//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
|
2007-08-09 06:51:59 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-08-09 06:51:59 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2012-12-13 21:59:55 +08:00
|
|
|
// This file implements the AST dump methods, which dump out the
|
2007-08-09 06:51:59 +08:00
|
|
|
// AST in a form that exposes type details and other fields.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-07-05 01:04:04 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-02-04 03:21:40 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2012-12-20 10:09:13 +08:00
|
|
|
#include "clang/AST/DeclVisitor.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2012-12-20 10:09:13 +08:00
|
|
|
#include "clang/Basic/Module.h"
|
2007-08-30 14:17:34 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2009-12-03 17:13:13 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2007-08-09 06:51:59 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-13 21:59:55 +08:00
|
|
|
// ASTDumper Visitor
|
2007-08-09 06:51:59 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
namespace {
|
2012-12-20 10:09:13 +08:00
|
|
|
class ASTDumper
|
|
|
|
: public DeclVisitor<ASTDumper>, public StmtVisitor<ASTDumper> {
|
2007-08-30 14:17:34 +08:00
|
|
|
SourceManager *SM;
|
2011-07-23 18:55:15 +08:00
|
|
|
raw_ostream &OS;
|
2007-08-09 06:51:59 +08:00
|
|
|
unsigned IndentLevel;
|
2012-11-07 08:33:12 +08:00
|
|
|
bool IsFirstLine;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-12-11 23:28:09 +08:00
|
|
|
/// Keep track of the last location we print out so that we can
|
|
|
|
/// print out deltas from then on out.
|
2007-08-30 14:17:34 +08:00
|
|
|
const char *LastLocFilename;
|
|
|
|
unsigned LastLocLine;
|
2009-05-30 04:38:28 +08:00
|
|
|
|
2012-11-07 08:33:12 +08:00
|
|
|
class IndentScope {
|
2012-12-13 21:59:55 +08:00
|
|
|
ASTDumper &Dumper;
|
2012-11-07 08:33:12 +08:00
|
|
|
public:
|
2012-12-13 21:59:55 +08:00
|
|
|
IndentScope(ASTDumper &Dumper) : Dumper(Dumper) {
|
2012-11-07 08:33:12 +08:00
|
|
|
Dumper.indent();
|
|
|
|
}
|
|
|
|
~IndentScope() {
|
|
|
|
Dumper.unindent();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2007-08-09 06:51:59 +08:00
|
|
|
public:
|
2012-12-13 21:59:55 +08:00
|
|
|
ASTDumper(SourceManager *SM, raw_ostream &OS)
|
2012-11-17 05:43:31 +08:00
|
|
|
: SM(SM), OS(OS), IndentLevel(0), IsFirstLine(true),
|
|
|
|
LastLocFilename(""), LastLocLine(~0U) { }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
~ASTDumper() {
|
2012-11-07 08:33:12 +08:00
|
|
|
OS << "\n";
|
|
|
|
}
|
|
|
|
|
2012-12-11 23:20:44 +08:00
|
|
|
void dumpDecl(Decl *D);
|
|
|
|
void dumpStmt(Stmt *S);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-12-11 23:28:09 +08:00
|
|
|
// Utilities
|
|
|
|
void indent();
|
|
|
|
void unindent();
|
2012-12-20 10:09:13 +08:00
|
|
|
void dumpPointer(const void *Ptr);
|
|
|
|
void dumpSourceRange(SourceRange R);
|
2012-12-11 23:28:09 +08:00
|
|
|
void dumpLocation(SourceLocation Loc);
|
2012-12-20 10:09:13 +08:00
|
|
|
void dumpBareType(QualType T);
|
2012-12-11 23:28:09 +08:00
|
|
|
void dumpType(QualType T);
|
2012-12-20 10:09:13 +08:00
|
|
|
void dumpBareDeclRef(Decl *node);
|
|
|
|
void dumpDeclRef(Decl *node, const char *Label = NULL);
|
|
|
|
void dumpName(NamedDecl *D);
|
|
|
|
void dumpDeclContext(DeclContext *DC);
|
|
|
|
|
|
|
|
// C++ Utilities
|
|
|
|
void dumpAccessSpecifier(AccessSpecifier AS);
|
|
|
|
void dumpCXXCtorInitializer(CXXCtorInitializer *Init);
|
|
|
|
void dumpTemplateParameters(TemplateParameterList *TPL);
|
|
|
|
void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
|
|
|
|
void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
|
|
|
|
void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
|
|
|
|
void dumpTemplateArgument(const TemplateArgument &A,
|
|
|
|
SourceRange R = SourceRange());
|
|
|
|
|
|
|
|
// Decls
|
|
|
|
void VisitLabelDecl(LabelDecl *D);
|
|
|
|
void VisitTypedefDecl(TypedefDecl *D);
|
|
|
|
void VisitEnumDecl(EnumDecl *D);
|
|
|
|
void VisitRecordDecl(RecordDecl *D);
|
|
|
|
void VisitEnumConstantDecl(EnumConstantDecl *D);
|
|
|
|
void VisitIndirectFieldDecl(IndirectFieldDecl *D);
|
|
|
|
void VisitFunctionDecl(FunctionDecl *D);
|
|
|
|
void VisitFieldDecl(FieldDecl *D);
|
|
|
|
void VisitVarDecl(VarDecl *D);
|
|
|
|
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
|
|
|
|
void VisitImportDecl(ImportDecl *D);
|
|
|
|
|
|
|
|
// C++ Decls
|
|
|
|
void VisitNamespaceDecl(NamespaceDecl *D);
|
|
|
|
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
|
|
|
|
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
|
|
|
|
void VisitTypeAliasDecl(TypeAliasDecl *D);
|
|
|
|
void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
|
|
|
|
void VisitCXXRecordDecl(CXXRecordDecl *D);
|
|
|
|
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
|
|
|
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
|
|
|
|
void VisitClassTemplateDecl(ClassTemplateDecl *D);
|
|
|
|
void VisitClassTemplateSpecializationDecl(
|
|
|
|
ClassTemplateSpecializationDecl *D);
|
|
|
|
void VisitClassTemplatePartialSpecializationDecl(
|
|
|
|
ClassTemplatePartialSpecializationDecl *D);
|
|
|
|
void VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D);
|
|
|
|
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
|
|
|
|
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
|
|
|
|
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
|
|
|
|
void VisitUsingDecl(UsingDecl *D);
|
|
|
|
void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
|
|
|
|
void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
|
|
|
|
void VisitUsingShadowDecl(UsingShadowDecl *D);
|
|
|
|
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
|
|
|
void VisitAccessSpecDecl(AccessSpecDecl *D);
|
|
|
|
void VisitFriendDecl(FriendDecl *D);
|
|
|
|
|
|
|
|
// ObjC Decls
|
|
|
|
void VisitObjCIvarDecl(ObjCIvarDecl *D);
|
|
|
|
void VisitObjCMethodDecl(ObjCMethodDecl *D);
|
|
|
|
void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
|
|
|
|
void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
|
|
|
|
void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
|
|
|
|
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
|
|
|
|
void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
|
|
|
|
void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
|
|
|
|
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
|
|
|
|
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
|
|
|
|
void VisitBlockDecl(BlockDecl *D);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-08-30 09:00:35 +08:00
|
|
|
// Stmts.
|
2007-08-21 12:04:25 +08:00
|
|
|
void VisitStmt(Stmt *Node);
|
2007-12-12 14:59:42 +08:00
|
|
|
void VisitDeclStmt(DeclStmt *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitLabelStmt(LabelStmt *Node);
|
|
|
|
void VisitGotoStmt(GotoStmt *Node);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-08-30 09:00:35 +08:00
|
|
|
// Exprs
|
|
|
|
void VisitExpr(Expr *Node);
|
2009-08-23 07:33:40 +08:00
|
|
|
void VisitCastExpr(CastExpr *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitDeclRefExpr(DeclRefExpr *Node);
|
2008-08-10 09:53:14 +08:00
|
|
|
void VisitPredefinedExpr(PredefinedExpr *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitCharacterLiteral(CharacterLiteral *Node);
|
|
|
|
void VisitIntegerLiteral(IntegerLiteral *Node);
|
|
|
|
void VisitFloatingLiteral(FloatingLiteral *Node);
|
|
|
|
void VisitStringLiteral(StringLiteral *Str);
|
|
|
|
void VisitUnaryOperator(UnaryOperator *Node);
|
2011-03-12 03:24:49 +08:00
|
|
|
void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitMemberExpr(MemberExpr *Node);
|
2008-04-19 07:10:10 +08:00
|
|
|
void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitBinaryOperator(BinaryOperator *Node);
|
|
|
|
void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
|
|
|
|
void VisitAddrLabelExpr(AddrLabelExpr *Node);
|
2011-02-07 18:33:21 +08:00
|
|
|
void VisitBlockExpr(BlockExpr *Node);
|
2011-11-06 17:01:30 +08:00
|
|
|
void VisitOpaqueValueExpr(OpaqueValueExpr *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
|
|
|
|
// C++
|
2008-10-28 03:41:14 +08:00
|
|
|
void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
|
2008-11-04 22:56:14 +08:00
|
|
|
void VisitCXXThisExpr(CXXThisExpr *Node);
|
2008-10-28 03:41:14 +08:00
|
|
|
void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
|
2009-08-12 08:21:52 +08:00
|
|
|
void VisitCXXConstructExpr(CXXConstructExpr *Node);
|
|
|
|
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node);
|
2010-12-06 16:20:24 +08:00
|
|
|
void VisitExprWithCleanups(ExprWithCleanups *Node);
|
2009-12-12 05:50:11 +08:00
|
|
|
void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node);
|
2012-12-11 23:28:09 +08:00
|
|
|
void dumpCXXTemporary(CXXTemporary *Temporary);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-08-30 09:00:35 +08:00
|
|
|
// ObjC
|
2010-04-24 06:50:49 +08:00
|
|
|
void VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node);
|
2007-08-30 09:00:35 +08:00
|
|
|
void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
|
2012-12-11 23:28:09 +08:00
|
|
|
void VisitObjCMessageExpr(ObjCMessageExpr *Node);
|
|
|
|
void VisitObjCBoxedExpr(ObjCBoxedExpr *Node);
|
2007-10-17 04:40:23 +08:00
|
|
|
void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
|
2007-10-18 00:58:11 +08:00
|
|
|
void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
|
2008-08-30 13:35:15 +08:00
|
|
|
void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
|
2012-03-07 04:05:56 +08:00
|
|
|
void VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node);
|
2008-03-12 21:19:12 +08:00
|
|
|
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
|
2012-03-07 04:05:56 +08:00
|
|
|
void VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node);
|
2007-08-09 06:51:59 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2007-08-30 14:17:34 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::indent() {
|
2012-12-11 23:28:09 +08:00
|
|
|
if (IsFirstLine)
|
|
|
|
IsFirstLine = false;
|
|
|
|
else
|
|
|
|
OS << "\n";
|
|
|
|
OS.indent(IndentLevel * 2);
|
|
|
|
OS << "(";
|
|
|
|
IndentLevel++;
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::unindent() {
|
2012-12-11 23:28:09 +08:00
|
|
|
OS << ")";
|
|
|
|
IndentLevel--;
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
void ASTDumper::dumpPointer(const void *Ptr) {
|
|
|
|
OS << ' ' << Ptr;
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::dumpLocation(SourceLocation Loc) {
|
2009-01-16 15:00:02 +08:00
|
|
|
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-08-30 14:17:34 +08:00
|
|
|
// The general format we print out is filename:line:col, but we drop pieces
|
|
|
|
// that haven't changed since the last loc printed.
|
2009-01-27 15:57:44 +08:00
|
|
|
PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
|
|
|
|
|
2010-11-12 15:15:47 +08:00
|
|
|
if (PLoc.isInvalid()) {
|
|
|
|
OS << "<invalid sloc>";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-01-27 15:57:44 +08:00
|
|
|
if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << PLoc.getFilename() << ':' << PLoc.getLine()
|
|
|
|
<< ':' << PLoc.getColumn();
|
2009-01-27 15:57:44 +08:00
|
|
|
LastLocFilename = PLoc.getFilename();
|
|
|
|
LastLocLine = PLoc.getLine();
|
|
|
|
} else if (PLoc.getLine() != LastLocLine) {
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << "line" << ':' << PLoc.getLine()
|
|
|
|
<< ':' << PLoc.getColumn();
|
2009-01-27 15:57:44 +08:00
|
|
|
LastLocLine = PLoc.getLine();
|
2007-08-30 14:17:34 +08:00
|
|
|
} else {
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << "col" << ':' << PLoc.getColumn();
|
2007-08-30 14:17:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
void ASTDumper::dumpSourceRange(SourceRange R) {
|
2007-08-30 14:17:34 +08:00
|
|
|
// Can't translate locations if a SourceManager isn't available.
|
2012-12-11 23:28:09 +08:00
|
|
|
if (!SM)
|
|
|
|
return;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " <";
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpLocation(R.getBegin());
|
2007-10-17 06:36:42 +08:00
|
|
|
if (R.getBegin() != R.getEnd()) {
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << ", ";
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpLocation(R.getEnd());
|
2007-08-30 14:17:34 +08:00
|
|
|
}
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << ">";
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-08-30 14:17:34 +08:00
|
|
|
// <t2.c:123:421[blah], t2.c:412:321>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
void ASTDumper::dumpBareType(QualType T) {
|
2012-12-11 23:28:09 +08:00
|
|
|
SplitQualType T_split = T.split();
|
|
|
|
OS << "'" << QualType::getAsString(T_split) << "'";
|
|
|
|
|
|
|
|
if (!T.isNull()) {
|
|
|
|
// If the type is sugared, also dump a (shallow) desugared type.
|
|
|
|
SplitQualType D_split = T.getSplitDesugaredType();
|
|
|
|
if (T_split != D_split)
|
|
|
|
OS << ":'" << QualType::getAsString(D_split) << "'";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
void ASTDumper::dumpType(QualType T) {
|
|
|
|
OS << ' ';
|
|
|
|
dumpBareType(T);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpBareDeclRef(Decl *D) {
|
|
|
|
OS << D->getDeclKindName();
|
|
|
|
dumpPointer(D);
|
2012-12-11 23:28:09 +08:00
|
|
|
|
|
|
|
if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
|
|
|
|
OS << " '";
|
|
|
|
ND->getDeclName().printName(OS);
|
|
|
|
OS << "'";
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpType(VD->getType());
|
2012-12-20 10:09:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpDeclRef(Decl *D, const char *Label) {
|
|
|
|
if (!D)
|
|
|
|
return;
|
|
|
|
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
if (Label)
|
|
|
|
OS << Label << ' ';
|
|
|
|
dumpBareDeclRef(D);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpName(NamedDecl *ND) {
|
|
|
|
if (ND->getDeclName())
|
|
|
|
OS << ' ' << ND->getNameAsString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpDeclContext(DeclContext *DC) {
|
|
|
|
if (!DC)
|
|
|
|
return;
|
|
|
|
for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
|
|
|
|
I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
|
|
|
|
switch (AS) {
|
|
|
|
case AS_none:
|
|
|
|
break;
|
|
|
|
case AS_public:
|
|
|
|
OS << "public";
|
|
|
|
break;
|
|
|
|
case AS_protected:
|
|
|
|
OS << "protected";
|
|
|
|
break;
|
|
|
|
case AS_private:
|
|
|
|
OS << "private";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpCXXCtorInitializer(CXXCtorInitializer *Init) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
OS << "CXXCtorInitializer";
|
|
|
|
if (Init->isAnyMemberInitializer()) {
|
|
|
|
OS << ' ';
|
|
|
|
dumpBareDeclRef(Init->getAnyMember());
|
|
|
|
} else {
|
|
|
|
dumpType(QualType(Init->getBaseClass(), 0));
|
|
|
|
}
|
|
|
|
dumpStmt(Init->getInit());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateParameters(TemplateParameterList *TPL) {
|
|
|
|
if (!TPL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
|
|
|
|
I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateArgumentListInfo(
|
|
|
|
const TemplateArgumentListInfo &TALI) {
|
|
|
|
for (unsigned i = 0, e = TALI.size(); i < e; ++i)
|
|
|
|
dumpTemplateArgumentLoc(TALI[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
|
|
|
|
dumpTemplateArgument(A.getArgument(), A.getSourceRange());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
|
|
|
|
for (unsigned i = 0, e = TAL.size(); i < e; ++i)
|
|
|
|
dumpTemplateArgument(TAL[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
OS << "TemplateArgument";
|
|
|
|
if (R.isValid())
|
|
|
|
dumpSourceRange(R);
|
|
|
|
|
|
|
|
switch (A.getKind()) {
|
|
|
|
case TemplateArgument::Null:
|
|
|
|
OS << " null";
|
|
|
|
break;
|
|
|
|
case TemplateArgument::Type:
|
|
|
|
OS << " type";
|
|
|
|
dumpType(A.getAsType());
|
|
|
|
break;
|
|
|
|
case TemplateArgument::Declaration:
|
|
|
|
OS << " decl";
|
|
|
|
dumpDeclRef(A.getAsDecl());
|
|
|
|
break;
|
|
|
|
case TemplateArgument::NullPtr:
|
|
|
|
OS << " nullptr";
|
|
|
|
break;
|
|
|
|
case TemplateArgument::Integral:
|
|
|
|
OS << " integral";
|
|
|
|
OS << ' ' << A.getAsIntegral();
|
|
|
|
break;
|
|
|
|
case TemplateArgument::Template:
|
|
|
|
OS << " template ";
|
|
|
|
A.getAsTemplate().dump(OS);
|
|
|
|
break;
|
|
|
|
case TemplateArgument::TemplateExpansion:
|
|
|
|
OS << " template expansion";
|
|
|
|
A.getAsTemplateOrTemplatePattern().dump(OS);
|
|
|
|
break;
|
|
|
|
case TemplateArgument::Expression:
|
|
|
|
OS << " expr";
|
|
|
|
dumpStmt(A.getAsExpr());
|
|
|
|
break;
|
|
|
|
case TemplateArgument::Pack:
|
|
|
|
OS << " pack";
|
|
|
|
for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
|
|
|
|
I != E; ++I)
|
|
|
|
dumpTemplateArgument(*I);
|
|
|
|
break;
|
2012-12-11 23:28:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-09 06:51:59 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-11 23:28:09 +08:00
|
|
|
// Decl dumping methods.
|
2007-08-09 06:51:59 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::dumpDecl(Decl *D) {
|
2012-12-20 10:09:13 +08:00
|
|
|
IndentScope Indent(*this);
|
|
|
|
|
|
|
|
if (!D) {
|
|
|
|
OS << "<<<NULL>>>";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << D->getDeclKindName() << "Decl";
|
|
|
|
dumpPointer(D);
|
|
|
|
dumpSourceRange(D->getSourceRange());
|
|
|
|
DeclVisitor<ASTDumper>::Visit(D);
|
|
|
|
// Decls within functions are visited by the body
|
|
|
|
if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D))
|
|
|
|
dumpDeclContext(dyn_cast<DeclContext>(D));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitLabelDecl(LabelDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitTypedefDecl(TypedefDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getUnderlyingType());
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitEnumDecl(EnumDecl *D) {
|
|
|
|
if (D->isScoped()) {
|
|
|
|
if (D->isScopedUsingClassTag())
|
|
|
|
OS << " class";
|
|
|
|
else
|
|
|
|
OS << " struct";
|
|
|
|
}
|
|
|
|
dumpName(D);
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
if (D->isFixed())
|
|
|
|
dumpType(D->getIntegerType());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitRecordDecl(RecordDecl *D) {
|
|
|
|
OS << ' ' << D->getKindName();
|
|
|
|
dumpName(D);
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitEnumConstantDecl(EnumConstantDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
if (Expr *Init = D->getInitExpr())
|
|
|
|
dumpStmt(Init);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
|
|
|
|
E = D->chain_end(); I != E; ++I)
|
|
|
|
dumpDeclRef(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitFunctionDecl(FunctionDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
|
|
|
|
StorageClass SC = D->getStorageClassAsWritten();
|
|
|
|
if (SC != SC_None)
|
|
|
|
OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
|
|
|
|
if (D->isInlineSpecified())
|
|
|
|
OS << " inline";
|
|
|
|
if (D->isVirtualAsWritten())
|
|
|
|
OS << " virtual";
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
|
|
|
|
if (D->isPure())
|
|
|
|
OS << " pure";
|
|
|
|
else if (D->isDeletedAsWritten())
|
|
|
|
OS << " delete";
|
|
|
|
|
|
|
|
if (const FunctionTemplateSpecializationInfo *FTSI =
|
|
|
|
D->getTemplateSpecializationInfo())
|
|
|
|
dumpTemplateArgumentList(*FTSI->TemplateArguments);
|
|
|
|
|
|
|
|
for (llvm::ArrayRef<NamedDecl*>::iterator
|
|
|
|
I = D->getDeclsInPrototypeScope().begin(),
|
|
|
|
E = D->getDeclsInPrototypeScope().end(); I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
|
|
|
|
|
|
|
for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
|
|
|
|
I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
|
|
|
|
|
|
|
if (CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D))
|
|
|
|
for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
|
|
|
|
E = C->init_end(); I != E; ++I)
|
|
|
|
dumpCXXCtorInitializer(*I);
|
|
|
|
|
|
|
|
if (D->doesThisDeclarationHaveABody())
|
|
|
|
dumpStmt(D->getBody());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitFieldDecl(FieldDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
if (D->isMutable())
|
|
|
|
OS << " mutable";
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
if (D->isBitField())
|
|
|
|
dumpStmt(D->getBitWidth());
|
|
|
|
if (Expr *Init = D->getInClassInitializer())
|
|
|
|
dumpStmt(Init);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitVarDecl(VarDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
StorageClass SC = D->getStorageClassAsWritten();
|
|
|
|
if (SC != SC_None)
|
|
|
|
OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
|
|
|
|
if (D->isThreadSpecified())
|
|
|
|
OS << " __thread";
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
if (D->isNRVOVariable())
|
|
|
|
OS << " nrvo";
|
|
|
|
if (D->hasInit())
|
|
|
|
dumpStmt(D->getInit());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
|
|
|
|
dumpStmt(D->getAsmString());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitImportDecl(ImportDecl *D) {
|
|
|
|
OS << ' ' << D->getImportedModule()->getFullModuleName();
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Declarations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTDumper::VisitNamespaceDecl(NamespaceDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
if (D->isInline())
|
|
|
|
OS << " inline";
|
|
|
|
if (!D->isOriginalNamespace())
|
|
|
|
dumpDeclRef(D->getOriginalNamespace(), "original");
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
dumpBareDeclRef(D->getNominatedNamespace());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpDeclRef(D->getAliasedNamespace());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitTypeAliasDecl(TypeAliasDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getUnderlyingType());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
dumpDecl(D->getTemplatedDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
|
|
|
VisitRecordDecl(D);
|
|
|
|
if (!D->isCompleteDefinition())
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
|
|
|
|
E = D->bases_end(); I != E; ++I) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
if (I->isVirtual())
|
|
|
|
OS << "virtual ";
|
|
|
|
dumpAccessSpecifier(I->getAccessSpecifier());
|
|
|
|
dumpType(I->getType());
|
|
|
|
if (I->isPackExpansion())
|
|
|
|
OS << "...";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
|
|
|
dumpStmt(D->getAssertExpr());
|
|
|
|
dumpStmt(D->getMessage());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
dumpDecl(D->getTemplatedDecl());
|
|
|
|
for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
|
|
|
|
E = D->spec_end(); I != E; ++I) {
|
|
|
|
switch (I->getTemplateSpecializationKind()) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
dumpDecl(*I);
|
|
|
|
break;
|
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
dumpDeclRef(*I);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
dumpDecl(D->getTemplatedDecl());
|
|
|
|
for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
|
|
|
|
I != E; ++I) {
|
|
|
|
switch (I->getTemplateSpecializationKind()) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
dumpDecl(*I);
|
|
|
|
break;
|
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
dumpDeclRef(*I);
|
|
|
|
break;
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2012-12-20 10:09:13 +08:00
|
|
|
}
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
void ASTDumper::VisitClassTemplateSpecializationDecl(
|
|
|
|
ClassTemplateSpecializationDecl *D) {
|
|
|
|
VisitCXXRecordDecl(D);
|
|
|
|
dumpTemplateArgumentList(D->getTemplateArgs());
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
|
|
|
|
ClassTemplatePartialSpecializationDecl *D) {
|
|
|
|
VisitClassTemplateSpecializationDecl(D);
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D) {
|
|
|
|
dumpDeclRef(D->getSpecialization());
|
|
|
|
if (D->hasExplicitTemplateArgs())
|
|
|
|
dumpTemplateArgumentListInfo(D->templateArgs());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
|
|
|
if (D->wasDeclaredWithTypename())
|
|
|
|
OS << " typename";
|
|
|
|
else
|
|
|
|
OS << " class";
|
|
|
|
if (D->isParameterPack())
|
|
|
|
OS << " ...";
|
|
|
|
dumpName(D);
|
|
|
|
if (D->hasDefaultArgument())
|
|
|
|
dumpType(D->getDefaultArgument());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
|
|
|
dumpType(D->getType());
|
|
|
|
if (D->isParameterPack())
|
|
|
|
OS << " ...";
|
|
|
|
dumpName(D);
|
|
|
|
if (D->hasDefaultArgument())
|
|
|
|
dumpStmt(D->getDefaultArgument());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
|
|
|
if (D->isParameterPack())
|
|
|
|
OS << " ...";
|
|
|
|
dumpName(D);
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
if (D->hasDefaultArgument())
|
|
|
|
dumpTemplateArgumentLoc(D->getDefaultArgument());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitUsingDecl(UsingDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
|
|
|
OS << D->getNameAsString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ASTDumper::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
|
|
|
OS << D->getNameAsString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
|
|
|
OS << D->getNameAsString();
|
|
|
|
dumpType(D->getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitUsingShadowDecl(UsingShadowDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
dumpBareDeclRef(D->getTargetDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
|
|
|
|
switch (D->getLanguage()) {
|
|
|
|
case LinkageSpecDecl::lang_c: OS << " C"; break;
|
|
|
|
case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
dumpAccessSpecifier(D->getAccess());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitFriendDecl(FriendDecl *D) {
|
|
|
|
if (TypeSourceInfo *T = D->getFriendType())
|
|
|
|
dumpType(T->getType());
|
|
|
|
else
|
|
|
|
dumpDecl(D->getFriendDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Obj-C Declarations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCIvarDecl(ObjCIvarDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
if (D->getSynthesize())
|
|
|
|
OS << " synthesize";
|
|
|
|
|
|
|
|
switch (D->getAccessControl()) {
|
|
|
|
case ObjCIvarDecl::None:
|
|
|
|
OS << " none";
|
|
|
|
break;
|
|
|
|
case ObjCIvarDecl::Private:
|
|
|
|
OS << " private";
|
|
|
|
break;
|
|
|
|
case ObjCIvarDecl::Protected:
|
|
|
|
OS << " protected";
|
|
|
|
break;
|
|
|
|
case ObjCIvarDecl::Public:
|
|
|
|
OS << " public";
|
|
|
|
break;
|
|
|
|
case ObjCIvarDecl::Package:
|
|
|
|
OS << " package";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCMethodDecl(ObjCMethodDecl *D) {
|
|
|
|
if (D->isInstanceMethod())
|
|
|
|
OS << " -";
|
|
|
|
else
|
|
|
|
OS << " +";
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getResultType());
|
|
|
|
|
|
|
|
if (D->isThisDeclarationADefinition())
|
|
|
|
dumpDeclContext(D);
|
|
|
|
else {
|
|
|
|
for (ObjCMethodDecl::param_iterator I = D->param_begin(),
|
|
|
|
E = D->param_end(); I != E; ++I) {
|
|
|
|
dumpDecl(*I);
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
}
|
2012-12-20 10:09:13 +08:00
|
|
|
|
|
|
|
if (D->isVariadic()) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
OS << "...";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (D->hasBody())
|
|
|
|
dumpStmt(D->getBody());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpDeclRef(D->getClassInterface());
|
|
|
|
dumpDeclRef(D->getImplementation());
|
|
|
|
for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
|
|
|
|
E = D->protocol_end(); I != E; ++I)
|
|
|
|
dumpDeclRef(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpDeclRef(D->getClassInterface());
|
|
|
|
dumpDeclRef(D->getCategoryDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
|
|
|
|
E = D->protocol_end(); I != E; ++I)
|
|
|
|
dumpDeclRef(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpDeclRef(D->getSuperClass(), "super");
|
|
|
|
dumpDeclRef(D->getImplementation());
|
|
|
|
for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
|
|
|
|
E = D->protocol_end(); I != E; ++I)
|
|
|
|
dumpDeclRef(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpDeclRef(D->getSuperClass(), "super");
|
|
|
|
dumpDeclRef(D->getClassInterface());
|
|
|
|
for (ObjCImplementationDecl::init_iterator I = D->init_begin(),
|
|
|
|
E = D->init_end(); I != E; ++I)
|
|
|
|
dumpCXXCtorInitializer(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpDeclRef(D->getClassInterface());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
|
|
|
|
dumpName(D);
|
|
|
|
dumpType(D->getType());
|
|
|
|
|
|
|
|
if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
|
|
|
|
OS << " required";
|
|
|
|
else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
|
|
|
|
OS << " optional";
|
|
|
|
|
|
|
|
ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
|
|
|
|
if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
|
|
|
|
OS << " readonly";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
|
|
|
|
OS << " assign";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
|
|
|
|
OS << " readwrite";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
|
|
|
|
OS << " retain";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
|
|
|
|
OS << " copy";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
|
|
|
OS << " nonatomic";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
|
|
|
|
OS << " atomic";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
|
|
|
|
OS << " weak";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
|
|
|
|
OS << " strong";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
|
|
|
|
OS << " unsafe_unretained";
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
|
|
|
|
dumpDeclRef(D->getGetterMethodDecl(), "getter");
|
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
|
|
|
|
dumpDeclRef(D->getSetterMethodDecl(), "setter");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
|
|
|
|
dumpName(D->getPropertyDecl());
|
|
|
|
if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
|
|
|
|
OS << " synthesize";
|
|
|
|
else
|
|
|
|
OS << " dynamic";
|
|
|
|
dumpDeclRef(D->getPropertyDecl());
|
|
|
|
dumpDeclRef(D->getPropertyIvarDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitBlockDecl(BlockDecl *D) {
|
|
|
|
for (BlockDecl::param_iterator I = D->param_begin(), E = D->param_end();
|
|
|
|
I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
|
|
|
|
|
|
|
if (D->isVariadic()) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
OS << "...";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (D->capturesCXXThis()) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
OS << "capture this";
|
|
|
|
}
|
|
|
|
for (BlockDecl::capture_iterator I = D->capture_begin(),
|
|
|
|
E = D->capture_end(); I != E; ++I) {
|
|
|
|
IndentScope Indent(*this);
|
|
|
|
OS << "capture";
|
|
|
|
if (I->isByRef())
|
|
|
|
OS << " byref";
|
|
|
|
if (I->isNested())
|
|
|
|
OS << " nested";
|
|
|
|
if (I->getVariable()) {
|
|
|
|
OS << ' ';
|
|
|
|
dumpBareDeclRef(I->getVariable());
|
|
|
|
}
|
|
|
|
if (I->hasCopyExpr())
|
|
|
|
dumpStmt(I->getCopyExpr());
|
|
|
|
}
|
|
|
|
|
|
|
|
dumpStmt(D->getBody());
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-11 23:20:44 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-11 23:28:09 +08:00
|
|
|
// Stmt dumping methods.
|
2012-12-11 23:20:44 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::dumpStmt(Stmt *S) {
|
2012-12-11 23:20:44 +08:00
|
|
|
IndentScope Indent(*this);
|
|
|
|
|
|
|
|
if (!S) {
|
|
|
|
OS << "<<<NULL>>>";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
|
|
|
|
VisitDeclStmt(DS);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
StmtVisitor<ASTDumper>::Visit(S);
|
2012-12-11 23:20:44 +08:00
|
|
|
for (Stmt::child_range CI = S->children(); CI; ++CI)
|
|
|
|
dumpStmt(*CI);
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitStmt(Stmt *Node) {
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << Node->getStmtClassName();
|
|
|
|
dumpPointer(Node);
|
|
|
|
dumpSourceRange(Node->getSourceRange());
|
2012-12-11 23:20:44 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitDeclStmt(DeclStmt *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitStmt(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end();
|
|
|
|
I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
2007-12-12 14:59:42 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitLabelStmt(LabelStmt *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitStmt(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " '" << Node->getName() << "'";
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitGotoStmt(GotoStmt *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitStmt(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << " '" << Node->getLabel()->getName() << "'";
|
|
|
|
dumpPointer(Node->getLabel());
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-11 23:28:09 +08:00
|
|
|
// Expr dumping methods.
|
2007-08-09 06:51:59 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitExpr(Expr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitStmt(Node);
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpType(Node->getType());
|
|
|
|
|
|
|
|
switch (Node->getValueKind()) {
|
|
|
|
case VK_RValue:
|
|
|
|
break;
|
|
|
|
case VK_LValue:
|
|
|
|
OS << " lvalue";
|
|
|
|
break;
|
|
|
|
case VK_XValue:
|
|
|
|
OS << " xvalue";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Node->getObjectKind()) {
|
|
|
|
case OK_Ordinary:
|
|
|
|
break;
|
|
|
|
case OK_BitField:
|
|
|
|
OS << " bitfield";
|
|
|
|
break;
|
|
|
|
case OK_ObjCProperty:
|
|
|
|
OS << " objcproperty";
|
|
|
|
break;
|
|
|
|
case OK_ObjCSubscript:
|
|
|
|
OS << " objcsubscript";
|
|
|
|
break;
|
|
|
|
case OK_VectorComponent:
|
|
|
|
OS << " vectorcomponent";
|
|
|
|
break;
|
|
|
|
}
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-11 23:28:09 +08:00
|
|
|
static void dumpBasePath(raw_ostream &OS, CastExpr *Node) {
|
2010-08-07 14:22:56 +08:00
|
|
|
if (Node->path_empty())
|
2010-04-25 03:06:50 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
OS << " (";
|
|
|
|
bool First = true;
|
2010-08-07 14:22:56 +08:00
|
|
|
for (CastExpr::path_iterator
|
|
|
|
I = Node->path_begin(), E = Node->path_end(); I != E; ++I) {
|
2010-04-25 03:06:50 +08:00
|
|
|
const CXXBaseSpecifier *Base = *I;
|
|
|
|
if (!First)
|
|
|
|
OS << " -> ";
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2010-04-25 03:06:50 +08:00
|
|
|
const CXXRecordDecl *RD =
|
|
|
|
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2010-04-25 03:06:50 +08:00
|
|
|
if (Base->isVirtual())
|
|
|
|
OS << "virtual ";
|
|
|
|
OS << RD->getName();
|
|
|
|
First = false;
|
|
|
|
}
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2010-04-25 03:06:50 +08:00
|
|
|
OS << ')';
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCastExpr(CastExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2010-04-25 03:06:50 +08:00
|
|
|
OS << " <" << Node->getCastKindName();
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpBasePath(OS, Node);
|
2010-04-25 03:06:50 +08:00
|
|
|
OS << ">";
|
2009-08-23 07:33:40 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2007-09-11 01:32:55 +08:00
|
|
|
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " ";
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpBareDeclRef(Node->getDecl());
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
if (Node->getDecl() != Node->getFoundDecl()) {
|
|
|
|
OS << " (";
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpBareDeclRef(Node->getFoundDecl());
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
OS << ")";
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-12 05:50:11 +08:00
|
|
|
OS << " (";
|
2012-12-11 23:28:09 +08:00
|
|
|
if (!Node->requiresADL())
|
|
|
|
OS << "no ";
|
2010-04-17 17:33:03 +08:00
|
|
|
OS << "ADL) = '" << Node->getName() << '\'';
|
2009-12-12 05:50:11 +08:00
|
|
|
|
|
|
|
UnresolvedLookupExpr::decls_iterator
|
|
|
|
I = Node->decls_begin(), E = Node->decls_end();
|
2012-12-11 23:28:09 +08:00
|
|
|
if (I == E)
|
|
|
|
OS << " empty";
|
2009-12-12 05:50:11 +08:00
|
|
|
for (; I != E; ++I)
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpPointer(*I);
|
2009-12-12 05:50:11 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2008-03-12 21:19:12 +08:00
|
|
|
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << Node->getDecl()->getDeclKindName()
|
2012-12-20 10:09:13 +08:00
|
|
|
<< "Decl='" << *Node->getDecl() << "'";
|
|
|
|
dumpPointer(Node->getDecl());
|
2008-05-24 06:01:24 +08:00
|
|
|
if (Node->isFreeIvar())
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " isFreeIvar";
|
2008-03-12 21:19:12 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitPredefinedExpr(PredefinedExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2007-08-09 06:51:59 +08:00
|
|
|
switch (Node->getIdentType()) {
|
2011-09-23 13:06:16 +08:00
|
|
|
default: llvm_unreachable("unknown case");
|
2009-12-03 17:13:13 +08:00
|
|
|
case PredefinedExpr::Func: OS << " __func__"; break;
|
|
|
|
case PredefinedExpr::Function: OS << " __FUNCTION__"; break;
|
2012-12-11 23:28:09 +08:00
|
|
|
case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break;
|
2009-12-03 17:13:13 +08:00
|
|
|
case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCharacterLiteral(CharacterLiteral *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2011-11-04 07:56:23 +08:00
|
|
|
OS << " " << Node->getValue();
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitIntegerLiteral(IntegerLiteral *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2007-08-09 06:51:59 +08:00
|
|
|
|
|
|
|
bool isSigned = Node->getType()->isSignedIntegerType();
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << Node->getValue().toString(10, isSigned);
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitFloatingLiteral(FloatingLiteral *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << Node->getValueAsApproximateDouble();
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2007-08-26 11:42:43 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitStringLiteral(StringLiteral *Str) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Str);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " ";
|
2012-06-14 04:25:24 +08:00
|
|
|
Str->outputString(OS);
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2007-08-30 09:00:35 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitUnaryOperator(UnaryOperator *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
|
|
|
|
<< " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2011-03-12 03:24:49 +08:00
|
|
|
switch(Node->getKind()) {
|
|
|
|
case UETT_SizeOf:
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << " sizeof";
|
2011-03-12 03:24:49 +08:00
|
|
|
break;
|
|
|
|
case UETT_AlignOf:
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << " alignof";
|
2011-03-12 03:24:49 +08:00
|
|
|
break;
|
|
|
|
case UETT_VecStep:
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << " vec_step";
|
2011-03-12 03:24:49 +08:00
|
|
|
break;
|
|
|
|
}
|
2008-11-12 01:56:53 +08:00
|
|
|
if (Node->isArgumentType())
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpType(Node->getArgumentType());
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2007-08-10 01:35:30 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitMemberExpr(MemberExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
|
|
|
|
dumpPointer(Node->getMemberDecl());
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << Node->getAccessor().getNameStart();
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitBinaryOperator(BinaryOperator *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
|
2007-08-25 10:00:02 +08:00
|
|
|
}
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
|
|
|
|
<< "' ComputeLHSTy=";
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpBareType(Node->getComputationLHSType());
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " ComputeResultTy=";
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpBareType(Node->getComputationResultType());
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitBlockExpr(BlockExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpDecl(Node->getBlockDecl());
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2011-11-06 17:01:30 +08:00
|
|
|
|
2012-11-07 08:33:12 +08:00
|
|
|
if (Expr *Source = Node->getSourceExpr())
|
2012-12-11 23:20:44 +08:00
|
|
|
dumpStmt(Source);
|
2011-11-06 17:01:30 +08:00
|
|
|
}
|
|
|
|
|
2007-08-09 06:51:59 +08:00
|
|
|
// GNU extensions.
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << " " << Node->getLabel()->getName();
|
|
|
|
dumpPointer(Node->getLabel());
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2007-08-10 02:03:18 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Expressions
|
|
|
|
//===----------------------------------------------------------------------===//
|
2007-08-09 06:51:59 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-12-11 23:28:09 +08:00
|
|
|
OS << " " << Node->getCastName()
|
2009-12-03 17:13:13 +08:00
|
|
|
<< "<" << Node->getTypeAsWritten().getAsString() << ">"
|
2010-04-25 03:06:50 +08:00
|
|
|
<< " <" << Node->getCastKindName();
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpBasePath(OS, Node);
|
2010-04-25 03:06:50 +08:00
|
|
|
OS << ">";
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << (Node->getValue() ? "true" : "false");
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCXXThisExpr(CXXThisExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " this";
|
2008-11-04 22:56:14 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2011-09-03 01:38:59 +08:00
|
|
|
OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
|
|
|
|
<< " <" << Node->getCastKindName() << ">";
|
2008-10-28 03:41:14 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2010-02-03 03:03:45 +08:00
|
|
|
CXXConstructorDecl *Ctor = Node->getConstructor();
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpType(Ctor->getType());
|
2009-08-12 08:21:52 +08:00
|
|
|
if (Node->isElidable())
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " elidable";
|
2010-08-07 14:38:55 +08:00
|
|
|
if (Node->requiresZeroInitialization())
|
|
|
|
OS << " zeroing";
|
2009-08-12 08:21:52 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " ";
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpCXXTemporary(Node->getTemporary());
|
2009-08-12 08:21:52 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitExprWithCleanups(ExprWithCleanups *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
|
|
|
|
dumpDeclRef(Node->getObject(i), "cleanup");
|
2009-08-12 08:21:52 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::dumpCXXTemporary(CXXTemporary *Temporary) {
|
2012-12-20 10:09:13 +08:00
|
|
|
OS << "(CXXTemporary";
|
|
|
|
dumpPointer(Temporary);
|
|
|
|
OS << ")";
|
2009-08-12 08:21:52 +08:00
|
|
|
}
|
|
|
|
|
2007-08-22 01:43:55 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Obj-C Expressions
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCMessageExpr(ObjCMessageExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " selector=" << Node->getSelector().getAsString();
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
switch (Node->getReceiverKind()) {
|
|
|
|
case ObjCMessageExpr::Instance:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::Class:
|
|
|
|
OS << " class=";
|
2012-12-20 10:09:13 +08:00
|
|
|
dumpBareType(Node->getClassReceiver());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::SuperInstance:
|
|
|
|
OS << " super (instance)";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::SuperClass:
|
|
|
|
OS << " super (class)";
|
|
|
|
break;
|
|
|
|
}
|
2008-03-01 06:04:05 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCBoxedExpr(ObjCBoxedExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-05-11 04:02:31 +08:00
|
|
|
OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitStmt(Node);
|
2012-12-20 10:09:13 +08:00
|
|
|
if (VarDecl *CatchParam = Node->getCatchParamDecl())
|
2012-12-11 23:20:44 +08:00
|
|
|
dumpDecl(CatchParam);
|
2012-12-20 10:09:13 +08:00
|
|
|
else
|
2010-04-24 06:50:49 +08:00
|
|
|
OS << " catch all";
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-12-11 23:28:09 +08:00
|
|
|
dumpType(Node->getEncodedType());
|
2007-08-22 23:14:15 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-12-03 17:13:13 +08:00
|
|
|
OS << " " << Node->getSelector().getAsString();
|
2007-10-17 04:40:23 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-12-11 23:28:09 +08:00
|
|
|
OS << ' ' << *Node->getProtocol();
|
2007-10-18 00:58:11 +08:00
|
|
|
}
|
2008-08-30 13:35:15 +08:00
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2010-12-02 09:19:52 +08:00
|
|
|
if (Node->isImplicitProperty()) {
|
2010-12-23 03:46:35 +08:00
|
|
|
OS << " Kind=MethodRef Getter=\"";
|
|
|
|
if (Node->getImplicitPropertyGetter())
|
|
|
|
OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
|
|
|
|
else
|
|
|
|
OS << "(null)";
|
|
|
|
|
|
|
|
OS << "\" Setter=\"";
|
2010-12-02 09:19:52 +08:00
|
|
|
if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
|
|
|
|
OS << Setter->getSelector().getAsString();
|
|
|
|
else
|
|
|
|
OS << "(null)";
|
|
|
|
OS << "\"";
|
|
|
|
} else {
|
2011-10-15 02:45:37 +08:00
|
|
|
OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
|
2010-12-02 09:19:52 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-10-15 00:04:05 +08:00
|
|
|
if (Node->isSuperReceiver())
|
|
|
|
OS << " super";
|
2012-03-30 08:19:18 +08:00
|
|
|
|
|
|
|
OS << " Messaging=";
|
|
|
|
if (Node->isMessagingGetter() && Node->isMessagingSetter())
|
|
|
|
OS << "Getter&Setter";
|
|
|
|
else if (Node->isMessagingGetter())
|
|
|
|
OS << "Getter";
|
|
|
|
else if (Node->isMessagingSetter())
|
|
|
|
OS << "Setter";
|
2008-11-04 22:56:14 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-03-07 04:05:56 +08:00
|
|
|
if (Node->isArraySubscriptRefExpr())
|
|
|
|
OS << " Kind=ArraySubscript GetterForArray=\"";
|
|
|
|
else
|
|
|
|
OS << " Kind=DictionarySubscript GetterForDictionary=\"";
|
|
|
|
if (Node->getAtIndexMethodDecl())
|
|
|
|
OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
|
|
|
|
else
|
|
|
|
OS << "(null)";
|
2012-12-11 23:28:09 +08:00
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
if (Node->isArraySubscriptRefExpr())
|
|
|
|
OS << "\" SetterForArray=\"";
|
|
|
|
else
|
|
|
|
OS << "\" SetterForDictionary=\"";
|
|
|
|
if (Node->setAtIndexMethodDecl())
|
|
|
|
OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
|
|
|
|
else
|
|
|
|
OS << "(null)";
|
|
|
|
}
|
|
|
|
|
2012-12-13 21:59:55 +08:00
|
|
|
void ASTDumper::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
|
2012-12-11 23:20:44 +08:00
|
|
|
VisitExpr(Node);
|
2012-03-07 04:05:56 +08:00
|
|
|
OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
|
|
|
|
}
|
|
|
|
|
2012-12-20 10:09:13 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Decl method implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void Decl::dump() const {
|
|
|
|
dump(llvm::errs());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Decl::dump(raw_ostream &OS) const {
|
|
|
|
ASTDumper P(&getASTContext().getSourceManager(), OS);
|
|
|
|
P.dumpDecl(const_cast<Decl*>(this));
|
|
|
|
}
|
|
|
|
|
2007-08-09 06:51:59 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Stmt method implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-08-30 14:17:34 +08:00
|
|
|
void Stmt::dump(SourceManager &SM) const {
|
2010-08-09 18:54:31 +08:00
|
|
|
dump(llvm::errs(), SM);
|
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
|
2012-12-13 21:59:55 +08:00
|
|
|
ASTDumper P(&SM, OS);
|
2012-12-11 23:20:44 +08:00
|
|
|
P.dumpStmt(const_cast<Stmt*>(this));
|
2007-08-30 08:40:08 +08:00
|
|
|
}
|
|
|
|
|
2007-08-09 06:51:59 +08:00
|
|
|
void Stmt::dump() const {
|
2012-12-13 21:59:55 +08:00
|
|
|
ASTDumper P(0, llvm::errs());
|
2012-12-11 23:20:44 +08:00
|
|
|
P.dumpStmt(const_cast<Stmt*>(this));
|
2007-08-09 06:51:59 +08:00
|
|
|
}
|