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