r220942 - Make QualType::dump() produce a useful dump of the structure of the type,
Richard Smith
richard-llvm at metafoo.co.uk
Thu Oct 30 18:17:46 PDT 2014
Author: rsmith
Date: Thu Oct 30 20:17:45 2014
New Revision: 220942
URL: http://llvm.org/viewvc/llvm-project?rev=220942&view=rev
Log:
Make QualType::dump() produce a useful dump of the structure of the type,
rather than simply pretty-printing it.
Modified:
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=220942&r1=220941&r2=220942&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Thu Oct 30 20:17:45 2014
@@ -20,6 +20,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
@@ -90,7 +91,7 @@ namespace {
class ASTDumper
: public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
- public ConstCommentVisitor<ASTDumper> {
+ public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> {
raw_ostream &OS;
const CommandTraits *Traits;
const SourceManager *SM;
@@ -217,8 +218,10 @@ namespace {
void dumpPointer(const void *Ptr);
void dumpSourceRange(SourceRange R);
void dumpLocation(SourceLocation Loc);
- void dumpBareType(QualType T);
+ void dumpBareType(QualType T, bool Desugar = true);
void dumpType(QualType T);
+ void dumpTypeAsChild(QualType T);
+ void dumpTypeAsChild(const Type *T);
void dumpBareDeclRef(const Decl *Node);
void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
void dumpName(const NamedDecl *D);
@@ -237,6 +240,175 @@ namespace {
void dumpTemplateArgument(const TemplateArgument &A,
SourceRange R = SourceRange());
+ // Types
+ void VisitComplexType(const ComplexType *T) {
+ dumpTypeAsChild(T->getElementType());
+ }
+ void VisitPointerType(const PointerType *T) {
+ dumpTypeAsChild(T->getPointeeType());
+ }
+ void VisitBlockPointerType(const BlockPointerType *T) {
+ dumpTypeAsChild(T->getPointeeType());
+ }
+ void VisitReferenceType(const ReferenceType *T) {
+ dumpTypeAsChild(T->getPointeeType());
+ }
+ void VisitRValueReferenceType(const ReferenceType *T) {
+ if (T->isSpelledAsLValue())
+ OS << " written as lvalue reference";
+ VisitReferenceType(T);
+ }
+ void VisitMemberPointerType(const MemberPointerType *T) {
+ dumpTypeAsChild(T->getClass());
+ dumpTypeAsChild(T->getPointeeType());
+ }
+ void VisitArrayType(const ArrayType *T) {
+ switch (T->getSizeModifier()) {
+ case ArrayType::Normal: break;
+ case ArrayType::Static: OS << " static"; break;
+ case ArrayType::Star: OS << " *"; break;
+ }
+ OS << " " << T->getIndexTypeQualifiers().getAsString();
+ dumpTypeAsChild(T->getElementType());
+ }
+ void VisitConstantArrayType(const ConstantArrayType *T) {
+ OS << " " << T->getSize();
+ VisitArrayType(T);
+ }
+ void VisitVariableArrayType(const VariableArrayType *T) {
+ OS << " ";
+ dumpSourceRange(T->getBracketsRange());
+ VisitArrayType(T);
+ dumpStmt(T->getSizeExpr());
+ }
+ void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
+ VisitArrayType(T);
+ OS << " ";
+ dumpSourceRange(T->getBracketsRange());
+ dumpStmt(T->getSizeExpr());
+ }
+ void VisitDependentSizedExtVectorType(
+ const DependentSizedExtVectorType *T) {
+ OS << " ";
+ dumpLocation(T->getAttributeLoc());
+ dumpTypeAsChild(T->getElementType());
+ dumpStmt(T->getSizeExpr());
+ }
+ void VisitVectorType(const VectorType *T) {
+ switch (T->getVectorKind()) {
+ case VectorType::GenericVector: break;
+ case VectorType::AltiVecVector: OS << " altivec"; break;
+ case VectorType::AltiVecPixel: OS << " altivec pixel"; break;
+ case VectorType::AltiVecBool: OS << " altivec bool"; break;
+ case VectorType::NeonVector: OS << " neon"; break;
+ case VectorType::NeonPolyVector: OS << " neon poly"; break;
+ }
+ OS << " " << T->getNumElements();
+ dumpTypeAsChild(T->getElementType());
+ }
+ void VisitFunctionType(const FunctionType *T) {
+ auto EI = T->getExtInfo();
+ if (EI.getNoReturn()) OS << " noreturn";
+ if (EI.getProducesResult()) OS << " produces_result";
+ if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm();
+ OS << " " << FunctionType::getNameForCallConv(EI.getCC());
+ dumpTypeAsChild(T->getReturnType());
+ }
+ void VisitFunctionProtoType(const FunctionProtoType *T) {
+ auto EPI = T->getExtProtoInfo();
+ if (EPI.HasTrailingReturn) OS << " trailing_return";
+ if (T->isConst()) OS << " const";
+ if (T->isVolatile()) OS << " volatile";
+ if (T->isRestrict()) OS << " restrict";
+ switch (EPI.RefQualifier) {
+ case RQ_None: break;
+ case RQ_LValue: OS << " &"; break;
+ case RQ_RValue: OS << " &&"; break;
+ }
+ // FIXME: Exception specification.
+ // FIXME: Consumed parameters.
+ VisitFunctionType(T);
+ for (QualType PT : T->getParamTypes())
+ dumpTypeAsChild(PT);
+ if (EPI.Variadic)
+ dumpChild([=] { OS << "..."; });
+ }
+ void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
+ dumpDeclRef(T->getDecl());
+ }
+ void VisitTypedefType(const TypedefType *T) {
+ dumpDeclRef(T->getDecl());
+ }
+ void VisitTypeOfExprType(const TypeOfExprType *T) {
+ dumpStmt(T->getUnderlyingExpr());
+ }
+ void VisitDecltypeType(const DecltypeType *T) {
+ dumpStmt(T->getUnderlyingExpr());
+ }
+ void VisitUnaryTransformType(const UnaryTransformType *T) {
+ switch (T->getUTTKind()) {
+ case UnaryTransformType::EnumUnderlyingType:
+ OS << " underlying_type";
+ break;
+ }
+ dumpTypeAsChild(T->getBaseType());
+ }
+ void VisitTagType(const TagType *T) {
+ dumpDeclRef(T->getDecl());
+ }
+ void VisitAttributedType(const AttributedType *T) {
+ // FIXME: AttrKind
+ dumpTypeAsChild(T->getModifiedType());
+ }
+ void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
+ OS << " depth " << T->getDepth() << " index " << T->getIndex();
+ if (T->isParameterPack()) OS << " pack";
+ dumpDeclRef(T->getDecl());
+ }
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+ dumpTypeAsChild(T->getReplacedParameter());
+ }
+ void VisitSubstTemplateTypeParmPackType(
+ const SubstTemplateTypeParmPackType *T) {
+ dumpTypeAsChild(T->getReplacedParameter());
+ dumpTemplateArgument(T->getArgumentPack());
+ }
+ void VisitAutoType(const AutoType *T) {
+ if (T->isDecltypeAuto()) OS << " decltype(auto)";
+ if (!T->isDeduced())
+ OS << " undeduced";
+ }
+ void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
+ if (T->isTypeAlias()) OS << " alias";
+ OS << " "; T->getTemplateName().dump(OS);
+ for (auto &Arg : *T)
+ dumpTemplateArgument(Arg);
+ if (T->isTypeAlias())
+ dumpTypeAsChild(T->getAliasedType());
+ }
+ void VisitInjectedClassNameType(const InjectedClassNameType *T) {
+ dumpDeclRef(T->getDecl());
+ }
+ void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
+ dumpDeclRef(T->getDecl());
+ }
+ void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
+ dumpTypeAsChild(T->getPointeeType());
+ }
+ void VisitAtomicType(const AtomicType *T) {
+ dumpTypeAsChild(T->getValueType());
+ }
+ void VisitAdjustedType(const AdjustedType *T) {
+ dumpTypeAsChild(T->getOriginalType());
+ }
+ void VisitPackExpansionType(const PackExpansionType *T) {
+ if (auto N = T->getNumExpansions()) OS << " expansions " << *N;
+ if (!T->isSugared())
+ dumpTypeAsChild(T->getPattern());
+ }
+ // FIXME: ElaboratedType, DependentNameType,
+ // DependentTemplateSpecializationType, ObjCObjectType
+
// Decls
void VisitLabelDecl(const LabelDecl *D);
void VisitTypedefDecl(const TypedefDecl *D);
@@ -433,13 +605,13 @@ void ASTDumper::dumpSourceRange(SourceRa
}
-void ASTDumper::dumpBareType(QualType T) {
+void ASTDumper::dumpBareType(QualType T, bool Desugar) {
ColorScope Color(*this, TypeColor);
-
+
SplitQualType T_split = T.split();
OS << "'" << QualType::getAsString(T_split) << "'";
- if (!T.isNull()) {
+ if (Desugar && !T.isNull()) {
// If the type is sugared, also dump a (shallow) desugared type.
SplitQualType D_split = T.getSplitDesugaredType();
if (T_split != D_split)
@@ -452,6 +624,59 @@ void ASTDumper::dumpType(QualType T) {
dumpBareType(T);
}
+void ASTDumper::dumpTypeAsChild(QualType T) {
+ SplitQualType SQT = T.split();
+ if (!SQT.Quals.hasQualifiers())
+ return dumpTypeAsChild(SQT.Ty);
+
+ dumpChild([=] {
+ OS << "QualType";
+ dumpPointer(T.getAsOpaquePtr());
+ OS << " ";
+ dumpBareType(T, false);
+ OS << " " << T.split().Quals.getAsString();
+ dumpTypeAsChild(T.split().Ty);
+ });
+}
+
+void ASTDumper::dumpTypeAsChild(const Type *T) {
+ dumpChild([=] {
+ if (!T) {
+ ColorScope Color(*this, NullColor);
+ OS << "<<<NULL>>>";
+ return;
+ }
+
+ {
+ ColorScope Color(*this, TypeColor);
+ OS << T->getTypeClassName() << "Type";
+ }
+ dumpPointer(T);
+ OS << " ";
+ dumpBareType(QualType(T, 0), false);
+
+ QualType SingleStepDesugar =
+ T->getLocallyUnqualifiedSingleStepDesugaredType();
+ if (SingleStepDesugar != QualType(T, 0))
+ OS << " sugar";
+ if (T->isDependentType())
+ OS << " dependent";
+ else if (T->isInstantiationDependentType())
+ OS << " instantiation_dependent";
+ if (T->isVariablyModifiedType())
+ OS << " variably_modified";
+ if (T->containsUnexpandedParameterPack())
+ OS << " contains_unexpanded_pack";
+ if (T->isFromAST())
+ OS << " imported";
+
+ TypeVisitor<ASTDumper>::Visit(T);
+
+ if (SingleStepDesugar != QualType(T, 0))
+ dumpTypeAsChild(SingleStepDesugar);
+ });
+}
+
void ASTDumper::dumpBareDeclRef(const Decl *D) {
{
ColorScope Color(*this, DeclKindNameColor);
@@ -1965,6 +2190,23 @@ void ASTDumper::visitVerbatimLineComment
}
//===----------------------------------------------------------------------===//
+// Type method implementations
+//===----------------------------------------------------------------------===//
+
+void QualType::dump(const char *msg) const {
+ if (msg)
+ llvm::errs() << msg << ": ";
+ dump();
+}
+
+LLVM_DUMP_METHOD void QualType::dump() const {
+ ASTDumper Dumper(llvm::errs(), nullptr, nullptr);
+ Dumper.dumpTypeAsChild(*this);
+}
+
+LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
+
+//===----------------------------------------------------------------------===//
// Decl method implementations
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=220942&r1=220941&r2=220942&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Oct 30 20:17:45 2014
@@ -1432,18 +1432,6 @@ PrintTemplateArgumentList(raw_ostream &O
OS << '>';
}
-void QualType::dump(const char *msg) const {
- if (msg)
- llvm::errs() << msg << ": ";
- LangOptions LO;
- print(llvm::errs(), PrintingPolicy(LO), "identifier");
- llvm::errs() << '\n';
-}
-
-LLVM_DUMP_METHOD void QualType::dump() const { dump(nullptr); }
-
-LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
-
std::string Qualifiers::getAsString() const {
LangOptions LO;
return getAsString(PrintingPolicy(LO));
More information about the cfe-commits
mailing list