diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-31 01:17:45 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-31 01:17:45 +0000 |
commit | d5e7ff856c2c8d58cb1ef4ed0bce838a70215b18 (patch) | |
tree | 92e5346014a2ffce5f3fce2d65094e2001dc9565 /clang/lib/AST/ASTDumper.cpp | |
parent | c158884726f6188c12ba3a19b2efb87bdfc7e4dd (diff) | |
download | bcm5719-llvm-d5e7ff856c2c8d58cb1ef4ed0bce838a70215b18.tar.gz bcm5719-llvm-d5e7ff856c2c8d58cb1ef4ed0bce838a70215b18.zip |
Make QualType::dump() produce a useful dump of the structure of the type,
rather than simply pretty-printing it.
llvm-svn: 220942
Diffstat (limited to 'clang/lib/AST/ASTDumper.cpp')
-rw-r--r-- | clang/lib/AST/ASTDumper.cpp | 252 |
1 files changed, 247 insertions, 5 deletions
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index d121d0d5277..ce32f5090a7 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -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(SourceRange R) { } -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(const VerbatimLineComment *C) { } //===----------------------------------------------------------------------===// +// 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 //===----------------------------------------------------------------------===// |