2012-12-13 13:59:55 +00:00
|
|
|
//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
|
2007-08-08 22:51:59 +00:00
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2007-08-08 22:51:59 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2012-12-13 13:59:55 +00:00
|
|
|
// This file implements the AST dump methods, which dump out the
|
2007-08-08 22:51:59 +00:00
|
|
|
// AST in a form that exposes type details and other fields.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-07-04 17:04:04 +00:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2018-12-05 20:53:14 +00:00
|
|
|
#include "clang/AST/ASTDumperUtils.h"
|
2013-01-07 17:53:08 +00:00
|
|
|
#include "clang/AST/Attr.h"
|
2019-01-11 19:16:01 +00:00
|
|
|
#include "clang/AST/AttrVisitor.h"
|
2013-01-14 14:07:11 +00:00
|
|
|
#include "clang/AST/CommentVisitor.h"
|
2009-02-03 19:21:40 +00:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2013-06-22 21:49:40 +00:00
|
|
|
#include "clang/AST/DeclLookups.h"
|
2012-12-04 09:13:33 +00:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2016-03-31 09:30:50 +00:00
|
|
|
#include "clang/AST/DeclOpenMP.h"
|
2012-12-20 02:09:13 +00:00
|
|
|
#include "clang/AST/DeclVisitor.h"
|
2016-02-01 17:42:01 +00:00
|
|
|
#include "clang/AST/LocInfoType.h"
|
2012-12-04 09:13:33 +00:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2019-01-12 16:35:37 +00:00
|
|
|
#include "clang/AST/TemplateArgumentVisitor.h"
|
2018-12-05 21:12:39 +00:00
|
|
|
#include "clang/AST/TextNodeDumper.h"
|
2014-10-31 01:17:45 +00:00
|
|
|
#include "clang/AST/TypeVisitor.h"
|
2015-11-04 03:40:30 +00:00
|
|
|
#include "clang/Basic/Builtins.h"
|
2012-12-20 02:09:13 +00:00
|
|
|
#include "clang/Basic/Module.h"
|
2007-08-30 06:17:34 +00:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2009-12-03 09:13:13 +00:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2007-08-08 22:51:59 +00:00
|
|
|
using namespace clang;
|
2013-01-14 14:07:11 +00:00
|
|
|
using namespace clang::comments;
|
2007-08-08 22:51:59 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-13 13:59:55 +00:00
|
|
|
// ASTDumper Visitor
|
2007-08-08 22:51:59 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
namespace {
|
2018-11-29 19:30:37 +00:00
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
class ASTDumper
|
2018-12-02 17:30:40 +00:00
|
|
|
: public ConstDeclVisitor<ASTDumper>,
|
|
|
|
public ConstStmtVisitor<ASTDumper>,
|
|
|
|
public ConstCommentVisitor<ASTDumper, void, const FullComment *>,
|
2019-01-11 19:16:01 +00:00
|
|
|
public TypeVisitor<ASTDumper>,
|
2019-01-12 16:35:37 +00:00
|
|
|
public ConstAttrVisitor<ASTDumper>,
|
|
|
|
public ConstTemplateArgumentVisitor<ASTDumper> {
|
2018-12-02 17:30:40 +00:00
|
|
|
|
2018-12-05 21:12:39 +00:00
|
|
|
TextNodeDumper NodeDumper;
|
2018-12-05 20:53:14 +00:00
|
|
|
|
2011-07-23 10:55:15 +00:00
|
|
|
raw_ostream &OS;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2017-12-21 21:42:42 +00:00
|
|
|
/// The policy to use for printing; can be defaulted.
|
|
|
|
PrintingPolicy PrintPolicy;
|
|
|
|
|
2017-03-09 22:00:01 +00:00
|
|
|
/// Indicates whether we should trigger deserialization of nodes that had
|
|
|
|
/// not already been loaded.
|
|
|
|
bool Deserialize = false;
|
|
|
|
|
2018-11-29 19:30:08 +00:00
|
|
|
const bool ShowColors;
|
2013-01-26 01:31:20 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
/// Dump a child of the current node.
|
2019-01-10 20:58:21 +00:00
|
|
|
template<typename Fn> void dumpChild(Fn DoDumpChild) {
|
|
|
|
NodeDumper.AddChild(DoDumpChild);
|
2014-10-30 21:02:37 +00:00
|
|
|
}
|
2019-01-11 19:11:17 +00:00
|
|
|
template <typename Fn> void dumpChild(StringRef Label, Fn DoDumpChild) {
|
|
|
|
NodeDumper.AddChild(Label, DoDumpChild);
|
|
|
|
}
|
2012-11-07 00:33:12 +00:00
|
|
|
|
2007-08-08 22:51:59 +00:00
|
|
|
public:
|
2013-01-14 14:07:11 +00:00
|
|
|
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
|
|
|
|
const SourceManager *SM)
|
2017-12-21 21:42:42 +00:00
|
|
|
: ASTDumper(OS, Traits, SM,
|
|
|
|
SM && SM->getDiagnostics().getShowColors()) {}
|
2013-01-26 01:31:20 +00:00
|
|
|
|
|
|
|
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
|
|
|
|
const SourceManager *SM, bool ShowColors)
|
2017-12-21 21:42:42 +00:00
|
|
|
: ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
|
|
|
|
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
|
|
|
|
const SourceManager *SM, bool ShowColors,
|
|
|
|
const PrintingPolicy &PrintPolicy)
|
2019-01-08 22:32:48 +00:00
|
|
|
: NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
|
2018-12-05 20:53:14 +00:00
|
|
|
PrintPolicy(PrintPolicy), ShowColors(ShowColors) {}
|
2017-03-09 22:00:01 +00:00
|
|
|
|
|
|
|
void setDeserialize(bool D) { Deserialize = D; }
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void dumpDecl(const Decl *D);
|
2019-01-11 19:11:17 +00:00
|
|
|
void dumpStmt(const Stmt *S, StringRef Label = {});
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2013-01-31 01:44:26 +00:00
|
|
|
// Utilities
|
2014-10-31 01:17:45 +00:00
|
|
|
void dumpTypeAsChild(QualType T);
|
|
|
|
void dumpTypeAsChild(const Type *T);
|
2012-12-20 11:08:38 +00:00
|
|
|
void dumpDeclContext(const DeclContext *DC);
|
2014-08-11 22:11:07 +00:00
|
|
|
void dumpLookups(const DeclContext *DC, bool DumpDecls);
|
2013-01-07 17:53:08 +00:00
|
|
|
void dumpAttr(const Attr *A);
|
2012-12-20 02:09:13 +00:00
|
|
|
|
|
|
|
// C++ Utilities
|
2012-12-20 11:08:38 +00:00
|
|
|
void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
|
|
|
|
void dumpTemplateParameters(const TemplateParameterList *TPL);
|
2012-12-20 02:09:13 +00:00
|
|
|
void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
|
2018-12-10 21:03:00 +00:00
|
|
|
void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
|
|
|
|
const Decl *From = nullptr,
|
2018-12-10 21:04:04 +00:00
|
|
|
const char *Label = nullptr);
|
2012-12-20 02:09:13 +00:00
|
|
|
void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
|
|
|
|
void dumpTemplateArgument(const TemplateArgument &A,
|
2018-12-10 21:03:00 +00:00
|
|
|
SourceRange R = SourceRange(),
|
|
|
|
const Decl *From = nullptr,
|
2018-12-10 21:04:04 +00:00
|
|
|
const char *Label = nullptr);
|
2018-12-09 13:33:30 +00:00
|
|
|
template <typename SpecializationDecl>
|
|
|
|
void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
|
|
|
|
bool DumpExplicitInst,
|
|
|
|
bool DumpRefOnly);
|
|
|
|
template <typename TemplateDecl>
|
|
|
|
void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
|
2012-12-20 02:09:13 +00:00
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 03:57:15 +00:00
|
|
|
// Objective-C utilities.
|
|
|
|
void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams);
|
|
|
|
|
2014-10-31 01:17:45 +00:00
|
|
|
// Types
|
|
|
|
void VisitComplexType(const ComplexType *T) {
|
|
|
|
dumpTypeAsChild(T->getElementType());
|
|
|
|
}
|
2019-01-14 20:13:09 +00:00
|
|
|
void VisitLocInfoType(const LocInfoType *T) {
|
|
|
|
dumpTypeAsChild(T->getTypeSourceInfo()->getType());
|
|
|
|
}
|
2014-10-31 01:17:45 +00:00
|
|
|
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 VisitMemberPointerType(const MemberPointerType *T) {
|
|
|
|
dumpTypeAsChild(T->getClass());
|
|
|
|
dumpTypeAsChild(T->getPointeeType());
|
|
|
|
}
|
|
|
|
void VisitArrayType(const ArrayType *T) {
|
|
|
|
dumpTypeAsChild(T->getElementType());
|
|
|
|
}
|
|
|
|
void VisitVariableArrayType(const VariableArrayType *T) {
|
|
|
|
VisitArrayType(T);
|
|
|
|
dumpStmt(T->getSizeExpr());
|
|
|
|
}
|
|
|
|
void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
|
2018-12-05 20:34:07 +00:00
|
|
|
dumpTypeAsChild(T->getElementType());
|
2014-10-31 01:17:45 +00:00
|
|
|
dumpStmt(T->getSizeExpr());
|
|
|
|
}
|
|
|
|
void VisitDependentSizedExtVectorType(
|
|
|
|
const DependentSizedExtVectorType *T) {
|
|
|
|
dumpTypeAsChild(T->getElementType());
|
|
|
|
dumpStmt(T->getSizeExpr());
|
|
|
|
}
|
|
|
|
void VisitVectorType(const VectorType *T) {
|
|
|
|
dumpTypeAsChild(T->getElementType());
|
|
|
|
}
|
|
|
|
void VisitFunctionType(const FunctionType *T) {
|
|
|
|
dumpTypeAsChild(T->getReturnType());
|
|
|
|
}
|
|
|
|
void VisitFunctionProtoType(const FunctionProtoType *T) {
|
|
|
|
VisitFunctionType(T);
|
|
|
|
for (QualType PT : T->getParamTypes())
|
|
|
|
dumpTypeAsChild(PT);
|
|
|
|
}
|
|
|
|
void VisitTypeOfExprType(const TypeOfExprType *T) {
|
|
|
|
dumpStmt(T->getUnderlyingExpr());
|
|
|
|
}
|
|
|
|
void VisitDecltypeType(const DecltypeType *T) {
|
|
|
|
dumpStmt(T->getUnderlyingExpr());
|
|
|
|
}
|
|
|
|
void VisitUnaryTransformType(const UnaryTransformType *T) {
|
|
|
|
dumpTypeAsChild(T->getBaseType());
|
|
|
|
}
|
|
|
|
void VisitAttributedType(const AttributedType *T) {
|
|
|
|
// FIXME: AttrKind
|
|
|
|
dumpTypeAsChild(T->getModifiedType());
|
|
|
|
}
|
|
|
|
void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
|
|
|
|
dumpTypeAsChild(T->getReplacedParameter());
|
|
|
|
}
|
|
|
|
void VisitSubstTemplateTypeParmPackType(
|
|
|
|
const SubstTemplateTypeParmPackType *T) {
|
|
|
|
dumpTypeAsChild(T->getReplacedParameter());
|
|
|
|
dumpTemplateArgument(T->getArgumentPack());
|
|
|
|
}
|
|
|
|
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
|
|
|
|
for (auto &Arg : *T)
|
|
|
|
dumpTemplateArgument(Arg);
|
|
|
|
if (T->isTypeAlias())
|
|
|
|
dumpTypeAsChild(T->getAliasedType());
|
|
|
|
}
|
|
|
|
void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
|
|
|
|
dumpTypeAsChild(T->getPointeeType());
|
|
|
|
}
|
|
|
|
void VisitAtomicType(const AtomicType *T) {
|
|
|
|
dumpTypeAsChild(T->getValueType());
|
|
|
|
}
|
2016-05-03 05:37:07 +00:00
|
|
|
void VisitPipeType(const PipeType *T) {
|
|
|
|
dumpTypeAsChild(T->getElementType());
|
|
|
|
}
|
2014-10-31 01:17:45 +00:00
|
|
|
void VisitAdjustedType(const AdjustedType *T) {
|
|
|
|
dumpTypeAsChild(T->getOriginalType());
|
|
|
|
}
|
|
|
|
void VisitPackExpansionType(const PackExpansionType *T) {
|
|
|
|
if (!T->isSugared())
|
|
|
|
dumpTypeAsChild(T->getPattern());
|
|
|
|
}
|
|
|
|
// FIXME: ElaboratedType, DependentNameType,
|
|
|
|
// DependentTemplateSpecializationType, ObjCObjectType
|
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
// Decls
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitLabelDecl(const LabelDecl *D);
|
|
|
|
void VisitTypedefDecl(const TypedefDecl *D);
|
|
|
|
void VisitEnumDecl(const EnumDecl *D);
|
|
|
|
void VisitRecordDecl(const RecordDecl *D);
|
|
|
|
void VisitEnumConstantDecl(const EnumConstantDecl *D);
|
|
|
|
void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
|
|
|
|
void VisitFunctionDecl(const FunctionDecl *D);
|
|
|
|
void VisitFieldDecl(const FieldDecl *D);
|
|
|
|
void VisitVarDecl(const VarDecl *D);
|
2016-07-22 23:36:59 +00:00
|
|
|
void VisitDecompositionDecl(const DecompositionDecl *D);
|
2016-08-11 22:25:46 +00:00
|
|
|
void VisitBindingDecl(const BindingDecl *D);
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
|
|
|
|
void VisitImportDecl(const ImportDecl *D);
|
2016-03-02 17:28:48 +00:00
|
|
|
void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
|
2016-03-02 19:28:54 +00:00
|
|
|
void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
|
2016-03-31 09:30:50 +00:00
|
|
|
void VisitCapturedDecl(const CapturedDecl *D);
|
|
|
|
|
|
|
|
// OpenMP decls
|
|
|
|
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
|
|
|
|
void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
|
2018-09-26 04:28:39 +00:00
|
|
|
void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
|
2016-03-31 09:30:50 +00:00
|
|
|
void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
|
2012-12-20 02:09:13 +00:00
|
|
|
|
|
|
|
// C++ Decls
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitNamespaceDecl(const NamespaceDecl *D);
|
|
|
|
void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
|
|
|
|
void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
|
|
|
|
void VisitTypeAliasDecl(const TypeAliasDecl *D);
|
|
|
|
void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
|
|
|
|
void VisitCXXRecordDecl(const CXXRecordDecl *D);
|
|
|
|
void VisitStaticAssertDecl(const StaticAssertDecl *D);
|
|
|
|
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
|
|
|
|
void VisitClassTemplateDecl(const ClassTemplateDecl *D);
|
2012-12-20 02:09:13 +00:00
|
|
|
void VisitClassTemplateSpecializationDecl(
|
2013-02-01 12:35:51 +00:00
|
|
|
const ClassTemplateSpecializationDecl *D);
|
2012-12-20 02:09:13 +00:00
|
|
|
void VisitClassTemplatePartialSpecializationDecl(
|
2013-02-01 12:35:51 +00:00
|
|
|
const ClassTemplatePartialSpecializationDecl *D);
|
2012-12-20 02:09:13 +00:00
|
|
|
void VisitClassScopeFunctionSpecializationDecl(
|
2013-02-01 12:35:51 +00:00
|
|
|
const ClassScopeFunctionSpecializationDecl *D);
|
2015-11-04 03:40:30 +00:00
|
|
|
void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
|
2013-09-18 01:36:02 +00:00
|
|
|
void VisitVarTemplateDecl(const VarTemplateDecl *D);
|
|
|
|
void VisitVarTemplateSpecializationDecl(
|
|
|
|
const VarTemplateSpecializationDecl *D);
|
|
|
|
void VisitVarTemplatePartialSpecializationDecl(
|
|
|
|
const VarTemplatePartialSpecializationDecl *D);
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
|
|
|
|
void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
|
|
|
|
void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
|
|
|
|
void VisitUsingDecl(const UsingDecl *D);
|
|
|
|
void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
|
|
|
|
void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
|
|
|
|
void VisitUsingShadowDecl(const UsingShadowDecl *D);
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
|
|
|
|
void VisitAccessSpecDecl(const AccessSpecDecl *D);
|
|
|
|
void VisitFriendDecl(const FriendDecl *D);
|
2012-12-20 02:09:13 +00:00
|
|
|
|
|
|
|
// ObjC Decls
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitObjCIvarDecl(const ObjCIvarDecl *D);
|
|
|
|
void VisitObjCMethodDecl(const ObjCMethodDecl *D);
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 03:57:15 +00:00
|
|
|
void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
|
|
|
|
void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
|
|
|
|
void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
|
|
|
|
void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
|
|
|
|
void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
|
|
|
|
void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
|
|
|
|
void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
|
|
|
|
void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
|
2019-01-15 20:41:37 +00:00
|
|
|
void Visit(const BlockDecl::Capture &C);
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitBlockDecl(const BlockDecl *D);
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2007-08-30 01:00:35 +00:00
|
|
|
// Stmts.
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitDeclStmt(const DeclStmt *Node);
|
|
|
|
void VisitAttributedStmt(const AttributedStmt *Node);
|
2013-09-04 14:35:00 +00:00
|
|
|
void VisitCXXCatchStmt(const CXXCatchStmt *Node);
|
2016-03-31 09:30:50 +00:00
|
|
|
void VisitCapturedStmt(const CapturedStmt *Node);
|
|
|
|
|
|
|
|
// OpenMP
|
2019-01-15 20:31:31 +00:00
|
|
|
void Visit(const OMPClause *C);
|
2016-03-31 09:30:50 +00:00
|
|
|
void VisitOMPExecutableDirective(const OMPExecutableDirective *Node);
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2007-08-30 01:00:35 +00:00
|
|
|
// Exprs
|
2014-06-03 08:24:28 +00:00
|
|
|
void VisitInitListExpr(const InitListExpr *ILE);
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitBlockExpr(const BlockExpr *Node);
|
|
|
|
void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
|
2018-01-05 21:31:07 +00:00
|
|
|
void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
|
2007-08-30 01:00:35 +00:00
|
|
|
|
|
|
|
// C++
|
Implement a rudimentary form of generic lambdas.
Specifically, the following features are not included in this commit:
- any sort of capturing within generic lambdas
- generic lambdas within template functions and nested
within other generic lambdas
- conversion operator for captureless lambdas
- ensuring all visitors are generic lambda aware
(Although I have gotten some useful feedback on my patches of the above and will be incorporating that as I submit those patches for commit)
As an example of what compiles through this commit:
template <class F1, class F2>
struct overload : F1, F2 {
using F1::operator();
using F2::operator();
overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
};
auto Recursive = [](auto Self, auto h, auto ... rest) {
return 1 + Self(Self, rest...);
};
auto Base = [](auto Self, auto h) {
return 1;
};
overload<decltype(Base), decltype(Recursive)> O(Base, Recursive);
int num_params = O(O, 5, 3, "abc", 3.14, 'a');
Please see attached tests for more examples.
This patch has been reviewed by Doug and Richard. Minor changes (non-functionality affecting) have been made since both of them formally looked at it, but the changes involve removal of supernumerary return type deduction changes (since they are now redundant, with richard having committed a recent patch to address return type deduction for C++11 lambdas using C++14 semantics).
Some implementation notes:
- Add a new Declarator context => LambdaExprParameterContext to
clang::Declarator to allow the use of 'auto' in declaring generic
lambda parameters
- Add various helpers to CXXRecordDecl to facilitate identifying
and querying a closure class
- LambdaScopeInfo (which maintains the current lambda's Sema state)
was augmented to house the current depth of the template being
parsed (id est the Parser calls Sema::RecordParsingTemplateParameterDepth)
so that SemaType.cpp::ConvertDeclSpecToType may use it to immediately
generate a template-parameter-type when 'auto' is parsed in a generic
lambda parameter context. (i.e we do NOT use AutoType deduced to
a template parameter type - Richard seemed ok with this approach).
We encode that this template type was generated from an auto by simply
adding $auto to the name which can be used for better diagnostics if needed.
- SemaLambda.h was added to hold some common lambda utility
functions (this file is likely to grow ...)
- Teach Sema::ActOnStartOfFunctionDef to check whether it
is being called to instantiate a generic lambda's call
operator, and if so, push an appropriately prepared
LambdaScopeInfo object on the stack.
- various tests were added - but much more will be needed.
There is obviously more work to be done, and both Richard (weakly) and Doug (strongly)
have requested that LambdaExpr be removed form the CXXRecordDecl LambdaDefinitionaData
in a future patch which is forthcoming.
A greatful thanks to all reviewers including Eli Friedman, James Dennett,
and especially the two gracious wizards (Richard Smith and Doug Gregor)
who spent hours providing feedback (in person in Chicago and on the mailing lists).
And yet I am certain that I have allowed unidentified bugs to creep in; bugs, that I will do my best to slay, once identified!
Thanks!
llvm-svn: 191453
2013-09-26 19:54:12 +00:00
|
|
|
void VisitLambdaExpr(const LambdaExpr *Node) {
|
|
|
|
dumpDecl(Node->getLambdaClass());
|
|
|
|
}
|
2015-02-16 19:58:41 +00:00
|
|
|
void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2007-08-30 01:00:35 +00:00
|
|
|
// ObjC
|
2013-02-01 12:35:51 +00:00
|
|
|
void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
|
2013-01-14 14:07:11 +00:00
|
|
|
|
|
|
|
// Comments.
|
2018-12-02 17:30:40 +00:00
|
|
|
void dumpComment(const Comment *C, const FullComment *FC);
|
2019-01-11 19:16:01 +00:00
|
|
|
|
2019-01-12 16:35:37 +00:00
|
|
|
void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
|
|
|
|
dumpStmt(TA.getAsExpr());
|
|
|
|
}
|
|
|
|
void VisitPackTemplateArgument(const TemplateArgument &TA) {
|
2019-01-14 19:50:34 +00:00
|
|
|
for (const auto &TArg : TA.pack_elements())
|
2019-01-12 16:35:37 +00:00
|
|
|
dumpTemplateArgument(TArg);
|
|
|
|
}
|
|
|
|
|
2019-01-11 19:16:01 +00:00
|
|
|
// Implements Visit methods for Attrs.
|
|
|
|
#include "clang/AST/AttrNodeTraverse.inc"
|
2007-08-08 22:51:59 +00:00
|
|
|
};
|
2015-06-22 23:07:51 +00:00
|
|
|
}
|
2007-08-08 22:51:59 +00:00
|
|
|
|
2007-08-30 06:17:34 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-10-31 01:17:45 +00:00
|
|
|
void ASTDumper::dumpTypeAsChild(QualType T) {
|
|
|
|
SplitQualType SQT = T.split();
|
|
|
|
if (!SQT.Quals.hasQualifiers())
|
|
|
|
return dumpTypeAsChild(SQT.Ty);
|
|
|
|
|
|
|
|
dumpChild([=] {
|
2019-01-14 20:15:29 +00:00
|
|
|
NodeDumper.Visit(T);
|
2014-10-31 01:17:45 +00:00
|
|
|
dumpTypeAsChild(T.split().Ty);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTypeAsChild(const Type *T) {
|
|
|
|
dumpChild([=] {
|
2019-01-14 20:11:02 +00:00
|
|
|
NodeDumper.Visit(T);
|
|
|
|
if (!T)
|
2014-10-31 01:17:45 +00:00
|
|
|
return;
|
2019-01-14 20:11:02 +00:00
|
|
|
TypeVisitor<ASTDumper>::Visit(T);
|
2014-10-31 01:17:45 +00:00
|
|
|
|
|
|
|
QualType SingleStepDesugar =
|
|
|
|
T->getLocallyUnqualifiedSingleStepDesugaredType();
|
|
|
|
if (SingleStepDesugar != QualType(T, 0))
|
|
|
|
dumpTypeAsChild(SingleStepDesugar);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-12-20 11:08:38 +00:00
|
|
|
void ASTDumper::dumpDeclContext(const DeclContext *DC) {
|
2012-12-20 02:09:13 +00:00
|
|
|
if (!DC)
|
|
|
|
return;
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2017-03-09 22:00:01 +00:00
|
|
|
for (auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpDecl(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2014-08-11 22:11:07 +00:00
|
|
|
void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
|
|
|
OS << "StoredDeclsMap ";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
|
2014-10-30 21:02:37 +00:00
|
|
|
|
|
|
|
const DeclContext *Primary = DC->getPrimaryContext();
|
|
|
|
if (Primary != DC) {
|
|
|
|
OS << " primary";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpPointer(cast<Decl>(Primary));
|
2013-06-22 21:49:40 +00:00
|
|
|
}
|
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
|
2014-08-11 22:11:07 +00:00
|
|
|
|
2018-01-16 12:33:46 +00:00
|
|
|
auto Range = Deserialize
|
|
|
|
? Primary->lookups()
|
|
|
|
: Primary->noload_lookups(/*PreserveInternalState=*/true);
|
|
|
|
for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
|
2014-10-30 21:02:37 +00:00
|
|
|
DeclarationName Name = I.getLookupName();
|
2017-03-09 22:00:01 +00:00
|
|
|
DeclContextLookupResult R = *I;
|
2014-08-11 22:11:07 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
|
|
|
OS << "DeclarationName ";
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclNameColor);
|
2014-10-30 21:02:37 +00:00
|
|
|
OS << '\'' << Name << '\'';
|
|
|
|
}
|
2014-08-11 22:11:07 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
|
|
|
|
RI != RE; ++RI) {
|
|
|
|
dumpChild([=] {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(*RI);
|
2014-10-30 21:02:37 +00:00
|
|
|
|
|
|
|
if ((*RI)->isHidden())
|
|
|
|
OS << " hidden";
|
|
|
|
|
|
|
|
// If requested, dump the redecl chain for this lookup.
|
|
|
|
if (DumpDecls) {
|
|
|
|
// Dump earliest decl first.
|
|
|
|
std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
|
|
|
|
if (Decl *Prev = D->getPreviousDecl())
|
|
|
|
DumpWithPrev(Prev);
|
|
|
|
dumpDecl(D);
|
|
|
|
};
|
|
|
|
DumpWithPrev(*RI);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2013-06-22 21:49:40 +00:00
|
|
|
}
|
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
if (HasUndeserializedLookups) {
|
|
|
|
dumpChild([=] {
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, UndeserializedColor);
|
2014-10-30 21:02:37 +00:00
|
|
|
OS << "<undeserialized lookups>";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2013-06-22 21:49:40 +00:00
|
|
|
}
|
|
|
|
|
2013-01-07 17:53:08 +00:00
|
|
|
void ASTDumper::dumpAttr(const Attr *A) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
2019-01-11 19:16:01 +00:00
|
|
|
NodeDumper.Visit(A);
|
|
|
|
ConstAttrVisitor<ASTDumper>::Visit(A);
|
2014-10-30 21:02:37 +00:00
|
|
|
});
|
2013-01-07 17:53:08 +00:00
|
|
|
}
|
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-20 11:08:38 +00:00
|
|
|
void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
2019-01-15 20:17:33 +00:00
|
|
|
NodeDumper.Visit(Init);
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpStmt(Init->getInit());
|
|
|
|
});
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2012-12-20 11:08:38 +00:00
|
|
|
void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
|
2012-12-20 02:09:13 +00:00
|
|
|
if (!TPL)
|
|
|
|
return;
|
|
|
|
|
2012-12-20 11:08:38 +00:00
|
|
|
for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
|
2012-12-20 02:09:13 +00:00
|
|
|
I != E; ++I)
|
|
|
|
dumpDecl(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateArgumentListInfo(
|
|
|
|
const TemplateArgumentListInfo &TALI) {
|
2014-10-30 21:02:37 +00:00
|
|
|
for (unsigned i = 0, e = TALI.size(); i < e; ++i)
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpTemplateArgumentLoc(TALI[i]);
|
|
|
|
}
|
|
|
|
|
2018-12-10 21:03:00 +00:00
|
|
|
void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
|
2018-12-10 21:04:04 +00:00
|
|
|
const Decl *From, const char *Label) {
|
|
|
|
dumpTemplateArgument(A.getArgument(), A.getSourceRange(), From, Label);
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
|
|
|
|
for (unsigned i = 0, e = TAL.size(); i < e; ++i)
|
|
|
|
dumpTemplateArgument(TAL[i]);
|
|
|
|
}
|
|
|
|
|
2018-12-10 21:03:00 +00:00
|
|
|
void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R,
|
2018-12-10 21:04:04 +00:00
|
|
|
const Decl *From, const char *Label) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
2019-01-12 16:35:37 +00:00
|
|
|
NodeDumper.Visit(A, R, From, Label);
|
|
|
|
ConstTemplateArgumentVisitor<ASTDumper>::Visit(A);
|
2014-10-30 21:02:37 +00:00
|
|
|
});
|
2012-12-11 15:28:09 +00:00
|
|
|
}
|
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 03:57:15 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Objective-C Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
|
|
|
|
if (!typeParams)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (auto typeParam : *typeParams) {
|
|
|
|
dumpDecl(typeParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-08 22:51:59 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-11 15:28:09 +00:00
|
|
|
// Decl dumping methods.
|
2007-08-08 22:51:59 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::dumpDecl(const Decl *D) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
2019-01-15 09:35:52 +00:00
|
|
|
NodeDumper.Visit(D);
|
|
|
|
if (!D)
|
2014-10-30 21:02:37 +00:00
|
|
|
return;
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
ConstDeclVisitor<ASTDumper>::Visit(D);
|
|
|
|
|
|
|
|
for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E;
|
|
|
|
++I)
|
|
|
|
dumpAttr(*I);
|
2013-01-31 01:44:26 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
if (const FullComment *Comment =
|
|
|
|
D->getASTContext().getLocalCommentForDeclUncached(D))
|
2018-12-09 13:18:55 +00:00
|
|
|
dumpComment(Comment, Comment);
|
2013-01-31 01:44:26 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
// Decls within functions are visited by the body.
|
2018-12-09 13:20:43 +00:00
|
|
|
if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
|
2019-01-18 22:15:09 +00:00
|
|
|
if (const auto *DC = dyn_cast<DeclContext>(D))
|
2018-12-09 13:20:43 +00:00
|
|
|
dumpDeclContext(DC);
|
|
|
|
}
|
2014-10-30 21:02:37 +00:00
|
|
|
});
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2018-12-05 21:12:39 +00:00
|
|
|
void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); }
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getUnderlyingType());
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
2016-01-12 21:59:26 +00:00
|
|
|
dumpTypeAsChild(D->getUnderlyingType());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isScoped()) {
|
|
|
|
if (D->isScopedUsingClassTag())
|
|
|
|
OS << " class";
|
|
|
|
else
|
|
|
|
OS << " struct";
|
|
|
|
}
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
if (D->isFixed())
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpType(D->getIntegerType());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ' << D->getKindName();
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
2013-08-30 05:32:29 +00:00
|
|
|
if (D->isCompleteDefinition())
|
|
|
|
OS << " definition";
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2014-10-30 21:02:37 +00:00
|
|
|
if (const Expr *Init = D->getInitExpr())
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(Init);
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2014-03-18 00:35:12 +00:00
|
|
|
for (auto *Child : D->chain())
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(Child);
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2013-04-03 19:27:57 +00:00
|
|
|
StorageClass SC = D->getStorageClass();
|
2012-12-20 02:09:13 +00:00
|
|
|
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";
|
2016-11-21 23:43:54 +00:00
|
|
|
if (D->isDefaulted()) {
|
|
|
|
OS << " default";
|
|
|
|
if (D->isDeleted())
|
|
|
|
OS << "_delete";
|
|
|
|
}
|
|
|
|
if (D->isDeletedAsWritten())
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << " delete";
|
2016-11-21 23:43:54 +00:00
|
|
|
if (D->isTrivial())
|
|
|
|
OS << " trivial";
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2019-01-15 23:05:11 +00:00
|
|
|
if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
|
2013-05-17 02:09:46 +00:00
|
|
|
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
|
2014-07-31 21:57:55 +00:00
|
|
|
switch (EPI.ExceptionSpec.Type) {
|
2013-05-17 02:09:46 +00:00
|
|
|
default: break;
|
|
|
|
case EST_Unevaluated:
|
2014-07-31 21:57:55 +00:00
|
|
|
OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
|
2013-05-17 02:09:46 +00:00
|
|
|
break;
|
|
|
|
case EST_Uninstantiated:
|
2014-07-31 21:57:55 +00:00
|
|
|
OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
|
2013-05-17 02:09:46 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-15 23:05:11 +00:00
|
|
|
if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
|
2017-06-20 21:06:00 +00:00
|
|
|
if (MD->size_overridden_methods() != 0) {
|
2017-12-21 21:42:42 +00:00
|
|
|
auto dumpOverride = [=](const CXXMethodDecl *D) {
|
|
|
|
SplitQualType T_split = D->getType().split();
|
|
|
|
OS << D << " " << D->getParent()->getName()
|
|
|
|
<< "::" << D->getNameAsString() << " '"
|
|
|
|
<< QualType::getAsString(T_split, PrintPolicy) << "'";
|
|
|
|
};
|
2017-06-20 21:06:00 +00:00
|
|
|
|
|
|
|
dumpChild([=] {
|
2017-12-17 23:52:45 +00:00
|
|
|
auto Overrides = MD->overridden_methods();
|
2017-06-20 21:06:00 +00:00
|
|
|
OS << "Overrides: [ ";
|
2017-12-17 23:52:45 +00:00
|
|
|
dumpOverride(*Overrides.begin());
|
2017-06-20 21:06:00 +00:00
|
|
|
for (const auto *Override :
|
2017-12-17 23:52:45 +00:00
|
|
|
llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
|
2017-07-29 20:42:58 +00:00
|
|
|
OS << ", ";
|
2017-06-20 21:06:00 +00:00
|
|
|
dumpOverride(Override);
|
2017-07-29 20:42:58 +00:00
|
|
|
}
|
2017-06-20 21:06:00 +00:00
|
|
|
OS << " ]";
|
|
|
|
});
|
|
|
|
}
|
2017-07-29 20:42:58 +00:00
|
|
|
}
|
2017-06-20 21:06:00 +00:00
|
|
|
|
2019-01-18 22:00:16 +00:00
|
|
|
// Since NumParams comes from the FunctionProtoType of the FunctionDecl and
|
|
|
|
// the Params are set later, it is possible for a dump during debugging to
|
|
|
|
// encounter a FunctionDecl that has been created but hasn't been assigned
|
|
|
|
// ParmVarDecls yet.
|
|
|
|
if (!D->param_empty() && !D->param_begin())
|
|
|
|
OS << " <<<NULL params x " << D->getNumParams() << ">>>";
|
|
|
|
|
2019-01-15 23:05:11 +00:00
|
|
|
if (const auto *FTSI = D->getTemplateSpecializationInfo())
|
2019-01-15 22:50:37 +00:00
|
|
|
dumpTemplateArgumentList(*FTSI->TemplateArguments);
|
|
|
|
|
2019-01-18 22:00:16 +00:00
|
|
|
if (D->param_begin())
|
|
|
|
for (const auto *Parameter : D->parameters())
|
2019-01-15 22:50:37 +00:00
|
|
|
dumpDecl(Parameter);
|
|
|
|
|
2019-01-15 23:05:11 +00:00
|
|
|
if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
|
|
|
|
for (const auto *I : C->inits())
|
|
|
|
dumpCXXCtorInitializer(I);
|
2019-01-15 22:50:37 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
if (D->doesThisDeclarationHaveABody())
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getBody());
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isMutable())
|
|
|
|
OS << " mutable";
|
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
2013-01-31 01:44:26 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
if (D->isBitField())
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getBitWidth());
|
2014-10-30 21:02:37 +00:00
|
|
|
if (Expr *Init = D->getInClassInitializer())
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(Init);
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitVarDecl(const VarDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2013-04-03 19:27:57 +00:00
|
|
|
StorageClass SC = D->getStorageClass();
|
2012-12-20 02:09:13 +00:00
|
|
|
if (SC != SC_None)
|
|
|
|
OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
|
2013-04-13 02:43:54 +00:00
|
|
|
switch (D->getTLSKind()) {
|
|
|
|
case VarDecl::TLS_None: break;
|
|
|
|
case VarDecl::TLS_Static: OS << " tls"; break;
|
|
|
|
case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
|
|
|
|
}
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isModulePrivate())
|
|
|
|
OS << " __module_private__";
|
|
|
|
if (D->isNRVOVariable())
|
|
|
|
OS << " nrvo";
|
2016-06-25 00:15:56 +00:00
|
|
|
if (D->isInline())
|
|
|
|
OS << " inline";
|
|
|
|
if (D->isConstexpr())
|
|
|
|
OS << " constexpr";
|
2013-01-31 01:44:26 +00:00
|
|
|
if (D->hasInit()) {
|
2014-07-10 22:54:03 +00:00
|
|
|
switch (D->getInitStyle()) {
|
|
|
|
case VarDecl::CInit: OS << " cinit"; break;
|
|
|
|
case VarDecl::CallInit: OS << " callinit"; break;
|
|
|
|
case VarDecl::ListInit: OS << " listinit"; break;
|
|
|
|
}
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getInit());
|
2013-01-31 01:44:26 +00:00
|
|
|
}
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2016-07-22 23:36:59 +00:00
|
|
|
void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) {
|
|
|
|
VisitVarDecl(D);
|
|
|
|
for (auto *B : D->bindings())
|
|
|
|
dumpDecl(B);
|
|
|
|
}
|
|
|
|
|
2016-08-11 22:25:46 +00:00
|
|
|
void ASTDumper::VisitBindingDecl(const BindingDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2016-08-11 22:25:46 +00:00
|
|
|
if (auto *E = D->getBinding())
|
|
|
|
dumpStmt(E);
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getAsmString());
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitImportDecl(const ImportDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ' << D->getImportedModule()->getFullModuleName();
|
|
|
|
}
|
|
|
|
|
2016-03-02 17:28:48 +00:00
|
|
|
void ASTDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
|
|
|
|
OS << ' ';
|
|
|
|
switch (D->getCommentKind()) {
|
|
|
|
case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind");
|
|
|
|
case PCK_Compiler: OS << "compiler"; break;
|
|
|
|
case PCK_ExeStr: OS << "exestr"; break;
|
|
|
|
case PCK_Lib: OS << "lib"; break;
|
|
|
|
case PCK_Linker: OS << "linker"; break;
|
|
|
|
case PCK_User: OS << "user"; break;
|
|
|
|
}
|
|
|
|
StringRef Arg = D->getArg();
|
|
|
|
if (!Arg.empty())
|
|
|
|
OS << " \"" << Arg << "\"";
|
|
|
|
}
|
|
|
|
|
2016-03-02 19:28:54 +00:00
|
|
|
void ASTDumper::VisitPragmaDetectMismatchDecl(
|
|
|
|
const PragmaDetectMismatchDecl *D) {
|
|
|
|
OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
|
|
|
|
}
|
|
|
|
|
2016-03-31 09:30:50 +00:00
|
|
|
void ASTDumper::VisitCapturedDecl(const CapturedDecl *D) {
|
|
|
|
dumpStmt(D->getBody());
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenMP Declarations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
|
|
|
|
for (auto *E : D->varlists())
|
|
|
|
dumpStmt(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2016-03-31 09:30:50 +00:00
|
|
|
OS << " combiner";
|
2018-12-10 20:53:39 +00:00
|
|
|
NodeDumper.dumpPointer(D->getCombiner());
|
|
|
|
if (const auto *Initializer = D->getInitializer()) {
|
2016-03-31 09:30:50 +00:00
|
|
|
OS << " initializer";
|
2018-12-10 20:53:39 +00:00
|
|
|
NodeDumper.dumpPointer(Initializer);
|
2017-09-06 14:49:58 +00:00
|
|
|
switch (D->getInitializerKind()) {
|
|
|
|
case OMPDeclareReductionDecl::DirectInit:
|
|
|
|
OS << " omp_priv = ";
|
|
|
|
break;
|
|
|
|
case OMPDeclareReductionDecl::CopyInit:
|
|
|
|
OS << " omp_priv ()";
|
|
|
|
break;
|
|
|
|
case OMPDeclareReductionDecl::CallInit:
|
|
|
|
break;
|
|
|
|
}
|
2016-03-31 09:30:50 +00:00
|
|
|
}
|
2018-12-10 20:53:39 +00:00
|
|
|
|
|
|
|
dumpStmt(D->getCombiner());
|
|
|
|
if (const auto *Initializer = D->getInitializer())
|
|
|
|
dumpStmt(Initializer);
|
2016-03-31 09:30:50 +00:00
|
|
|
}
|
|
|
|
|
2018-09-26 04:28:39 +00:00
|
|
|
void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
|
|
|
|
for (auto *C : D->clauselists()) {
|
|
|
|
dumpChild([=] {
|
|
|
|
if (!C) {
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, NullColor);
|
2018-09-26 04:28:39 +00:00
|
|
|
OS << "<<<NULL>>> OMPClause";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, AttrColor);
|
2018-09-26 04:28:39 +00:00
|
|
|
StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
|
|
|
|
OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
|
|
|
|
<< ClauseName.drop_front() << "Clause";
|
|
|
|
}
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpPointer(C);
|
|
|
|
NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
|
2018-09-26 04:28:39 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-31 09:30:50 +00:00
|
|
|
void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2016-03-31 09:30:50 +00:00
|
|
|
dumpStmt(D->getInit());
|
|
|
|
}
|
2016-03-02 19:28:54 +00:00
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Declarations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isInline())
|
|
|
|
OS << " inline";
|
|
|
|
if (!D->isOriginalNamespace())
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original");
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ';
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getNominatedNamespace());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getAliasedNamespace());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getUnderlyingType());
|
2016-01-12 21:59:26 +00:00
|
|
|
dumpTypeAsChild(D->getUnderlyingType());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
dumpDecl(D->getTemplatedDecl());
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
VisitRecordDecl(D);
|
|
|
|
if (!D->isCompleteDefinition())
|
|
|
|
return;
|
|
|
|
|
2017-09-22 00:11:15 +00:00
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "DefinitionData";
|
|
|
|
}
|
|
|
|
#define FLAG(fn, name) if (D->fn()) OS << " " #name;
|
|
|
|
FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
|
|
|
|
|
|
|
|
FLAG(isGenericLambda, generic);
|
|
|
|
FLAG(isLambda, lambda);
|
|
|
|
|
|
|
|
FLAG(canPassInRegisters, pass_in_registers);
|
|
|
|
FLAG(isEmpty, empty);
|
|
|
|
FLAG(isAggregate, aggregate);
|
|
|
|
FLAG(isStandardLayout, standard_layout);
|
|
|
|
FLAG(isTriviallyCopyable, trivially_copyable);
|
|
|
|
FLAG(isPOD, pod);
|
|
|
|
FLAG(isTrivial, trivial);
|
|
|
|
FLAG(isPolymorphic, polymorphic);
|
|
|
|
FLAG(isAbstract, abstract);
|
|
|
|
FLAG(isLiteral, literal);
|
|
|
|
|
|
|
|
FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
|
|
|
|
FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
|
|
|
|
FLAG(hasMutableFields, has_mutable_fields);
|
|
|
|
FLAG(hasVariantMembers, has_variant_members);
|
|
|
|
FLAG(allowConstDefaultInit, can_const_default_init);
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "DefaultConstructor";
|
|
|
|
}
|
|
|
|
FLAG(hasDefaultConstructor, exists);
|
|
|
|
FLAG(hasTrivialDefaultConstructor, trivial);
|
|
|
|
FLAG(hasNonTrivialDefaultConstructor, non_trivial);
|
|
|
|
FLAG(hasUserProvidedDefaultConstructor, user_provided);
|
|
|
|
FLAG(hasConstexprDefaultConstructor, constexpr);
|
|
|
|
FLAG(needsImplicitDefaultConstructor, needs_implicit);
|
|
|
|
FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
|
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "CopyConstructor";
|
|
|
|
}
|
|
|
|
FLAG(hasSimpleCopyConstructor, simple);
|
|
|
|
FLAG(hasTrivialCopyConstructor, trivial);
|
|
|
|
FLAG(hasNonTrivialCopyConstructor, non_trivial);
|
|
|
|
FLAG(hasUserDeclaredCopyConstructor, user_declared);
|
|
|
|
FLAG(hasCopyConstructorWithConstParam, has_const_param);
|
|
|
|
FLAG(needsImplicitCopyConstructor, needs_implicit);
|
|
|
|
FLAG(needsOverloadResolutionForCopyConstructor,
|
|
|
|
needs_overload_resolution);
|
|
|
|
if (!D->needsOverloadResolutionForCopyConstructor())
|
|
|
|
FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
|
|
|
|
FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
|
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "MoveConstructor";
|
|
|
|
}
|
|
|
|
FLAG(hasMoveConstructor, exists);
|
|
|
|
FLAG(hasSimpleMoveConstructor, simple);
|
|
|
|
FLAG(hasTrivialMoveConstructor, trivial);
|
|
|
|
FLAG(hasNonTrivialMoveConstructor, non_trivial);
|
|
|
|
FLAG(hasUserDeclaredMoveConstructor, user_declared);
|
|
|
|
FLAG(needsImplicitMoveConstructor, needs_implicit);
|
|
|
|
FLAG(needsOverloadResolutionForMoveConstructor,
|
|
|
|
needs_overload_resolution);
|
|
|
|
if (!D->needsOverloadResolutionForMoveConstructor())
|
|
|
|
FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
|
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "CopyAssignment";
|
|
|
|
}
|
|
|
|
FLAG(hasTrivialCopyAssignment, trivial);
|
|
|
|
FLAG(hasNonTrivialCopyAssignment, non_trivial);
|
|
|
|
FLAG(hasCopyAssignmentWithConstParam, has_const_param);
|
|
|
|
FLAG(hasUserDeclaredCopyAssignment, user_declared);
|
|
|
|
FLAG(needsImplicitCopyAssignment, needs_implicit);
|
|
|
|
FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
|
|
|
|
FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
|
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "MoveAssignment";
|
|
|
|
}
|
|
|
|
FLAG(hasMoveAssignment, exists);
|
|
|
|
FLAG(hasSimpleMoveAssignment, simple);
|
|
|
|
FLAG(hasTrivialMoveAssignment, trivial);
|
|
|
|
FLAG(hasNonTrivialMoveAssignment, non_trivial);
|
|
|
|
FLAG(hasUserDeclaredMoveAssignment, user_declared);
|
|
|
|
FLAG(needsImplicitMoveAssignment, needs_implicit);
|
|
|
|
FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
|
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
{
|
2018-11-29 19:30:37 +00:00
|
|
|
ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
2017-09-22 00:11:15 +00:00
|
|
|
OS << "Destructor";
|
|
|
|
}
|
|
|
|
FLAG(hasSimpleDestructor, simple);
|
|
|
|
FLAG(hasIrrelevantDestructor, irrelevant);
|
|
|
|
FLAG(hasTrivialDestructor, trivial);
|
|
|
|
FLAG(hasNonTrivialDestructor, non_trivial);
|
|
|
|
FLAG(hasUserDeclaredDestructor, user_declared);
|
|
|
|
FLAG(needsImplicitDestructor, needs_implicit);
|
|
|
|
FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
|
|
|
|
if (!D->needsOverloadResolutionForDestructor())
|
|
|
|
FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-03-13 15:41:46 +00:00
|
|
|
for (const auto &I : D->bases()) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
|
|
|
if (I.isVirtual())
|
|
|
|
OS << "virtual ";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier());
|
|
|
|
NodeDumper.dumpType(I.getType());
|
2014-10-30 21:02:37 +00:00
|
|
|
if (I.isPackExpansion())
|
|
|
|
OS << "...";
|
|
|
|
});
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getAssertExpr());
|
|
|
|
dumpStmt(D->getMessage());
|
|
|
|
}
|
|
|
|
|
2018-12-09 13:33:30 +00:00
|
|
|
template <typename SpecializationDecl>
|
|
|
|
void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
|
|
|
|
bool DumpExplicitInst,
|
|
|
|
bool DumpRefOnly) {
|
2014-03-18 02:07:28 +00:00
|
|
|
bool DumpedAny = false;
|
|
|
|
for (auto *RedeclWithBadType : D->redecls()) {
|
|
|
|
// FIXME: The redecls() range sometimes has elements of a less-specific
|
|
|
|
// type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
|
|
|
|
// us TagDecls, and should give CXXRecordDecls).
|
|
|
|
auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
|
|
|
|
if (!Redecl) {
|
|
|
|
// Found the injected-class-name for a class template. This will be dumped
|
|
|
|
// as part of its surrounding class so we don't need to dump it here.
|
|
|
|
assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
|
|
|
|
"expected an injected-class-name");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Redecl->getTemplateSpecializationKind()) {
|
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
if (!DumpExplicitInst)
|
|
|
|
break;
|
2017-12-19 22:06:11 +00:00
|
|
|
LLVM_FALLTHROUGH;
|
2014-03-18 02:07:28 +00:00
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ImplicitInstantiation:
|
2014-10-30 21:02:37 +00:00
|
|
|
if (DumpRefOnly)
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(Redecl);
|
2014-10-30 21:02:37 +00:00
|
|
|
else
|
|
|
|
dumpDecl(Redecl);
|
2014-03-18 02:07:28 +00:00
|
|
|
DumpedAny = true;
|
|
|
|
break;
|
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure we dump at least one decl for each specialization.
|
|
|
|
if (!DumpedAny)
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D);
|
2014-03-18 02:07:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-09 13:33:30 +00:00
|
|
|
template <typename TemplateDecl>
|
|
|
|
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpDecl(D->getTemplatedDecl());
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2014-03-18 02:07:28 +00:00
|
|
|
for (auto *Child : D->specializations())
|
2018-12-09 13:33:30 +00:00
|
|
|
dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
|
|
|
|
!D->isCanonicalDecl());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2014-03-17 23:34:53 +00:00
|
|
|
void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
|
|
|
|
// FIXME: We don't add a declaration of a function template specialization
|
|
|
|
// to its context when it's explicitly instantiated, so dump explicit
|
|
|
|
// instantiations when we dump the template itself.
|
2018-12-09 13:33:30 +00:00
|
|
|
dumpTemplateDecl(D, true);
|
2014-03-17 23:34:53 +00:00
|
|
|
}
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2014-03-17 23:34:53 +00:00
|
|
|
void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
|
2018-12-09 13:33:30 +00:00
|
|
|
dumpTemplateDecl(D, false);
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
void ASTDumper::VisitClassTemplateSpecializationDecl(
|
2013-02-01 12:35:51 +00:00
|
|
|
const ClassTemplateSpecializationDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
VisitCXXRecordDecl(D);
|
|
|
|
dumpTemplateArgumentList(D->getTemplateArgs());
|
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
|
2013-02-01 12:35:51 +00:00
|
|
|
const ClassTemplatePartialSpecializationDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
VisitClassTemplateSpecializationDecl(D);
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
|
2013-02-01 12:35:51 +00:00
|
|
|
const ClassScopeFunctionSpecializationDecl *D) {
|
2018-03-16 13:36:56 +00:00
|
|
|
dumpDecl(D->getSpecialization());
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->hasExplicitTemplateArgs())
|
|
|
|
dumpTemplateArgumentListInfo(D->templateArgs());
|
|
|
|
}
|
|
|
|
|
2013-09-18 01:36:02 +00:00
|
|
|
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
|
2018-12-09 13:33:30 +00:00
|
|
|
dumpTemplateDecl(D, false);
|
2013-09-18 01:36:02 +00:00
|
|
|
}
|
|
|
|
|
2015-11-04 03:40:30 +00:00
|
|
|
void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2015-11-04 03:40:30 +00:00
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
}
|
|
|
|
|
2013-09-18 01:36:02 +00:00
|
|
|
void ASTDumper::VisitVarTemplateSpecializationDecl(
|
|
|
|
const VarTemplateSpecializationDecl *D) {
|
|
|
|
dumpTemplateArgumentList(D->getTemplateArgs());
|
|
|
|
VisitVarDecl(D);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDumper::VisitVarTemplatePartialSpecializationDecl(
|
|
|
|
const VarTemplatePartialSpecializationDecl *D) {
|
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
|
|
|
VisitVarTemplateSpecializationDecl(D);
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->wasDeclaredWithTypename())
|
|
|
|
OS << " typename";
|
|
|
|
else
|
|
|
|
OS << " class";
|
2017-02-21 02:04:03 +00:00
|
|
|
OS << " depth " << D->getDepth() << " index " << D->getIndex();
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isParameterPack())
|
|
|
|
OS << " ...";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2014-10-30 21:02:37 +00:00
|
|
|
if (D->hasDefaultArgument())
|
2018-12-10 21:03:00 +00:00
|
|
|
dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
|
|
|
|
D->getDefaultArgStorage().getInheritedFrom(),
|
|
|
|
D->defaultArgumentWasInherited() ? "inherited from"
|
|
|
|
: "previous");
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpType(D->getType());
|
2017-02-21 02:04:03 +00:00
|
|
|
OS << " depth " << D->getDepth() << " index " << D->getIndex();
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isParameterPack())
|
|
|
|
OS << " ...";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2014-10-30 21:02:37 +00:00
|
|
|
if (D->hasDefaultArgument())
|
2018-12-10 21:03:00 +00:00
|
|
|
dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
|
|
|
|
D->getDefaultArgStorage().getInheritedFrom(),
|
|
|
|
D->defaultArgumentWasInherited() ? "inherited from"
|
|
|
|
: "previous");
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitTemplateTemplateParmDecl(
|
|
|
|
const TemplateTemplateParmDecl *D) {
|
2017-02-21 02:04:03 +00:00
|
|
|
OS << " depth " << D->getDepth() << " index " << D->getIndex();
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isParameterPack())
|
|
|
|
OS << " ...";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpTemplateParameters(D->getTemplateParameters());
|
2014-10-30 21:02:37 +00:00
|
|
|
if (D->hasDefaultArgument())
|
2018-12-10 21:03:00 +00:00
|
|
|
dumpTemplateArgumentLoc(
|
|
|
|
D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
|
|
|
|
D->defaultArgumentWasInherited() ? "inherited from" : "previous");
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ';
|
2015-12-05 22:37:55 +00:00
|
|
|
if (D->getQualifier())
|
|
|
|
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << D->getNameAsString();
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitUnresolvedUsingTypenameDecl(
|
|
|
|
const UnresolvedUsingTypenameDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ';
|
2015-12-05 22:37:55 +00:00
|
|
|
if (D->getQualifier())
|
|
|
|
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << D->getNameAsString();
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ';
|
2015-12-05 22:37:55 +00:00
|
|
|
if (D->getQualifier())
|
|
|
|
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << D->getNameAsString();
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpType(D->getType());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ';
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getTargetDecl());
|
2016-01-12 21:59:26 +00:00
|
|
|
if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
|
|
|
|
dumpTypeAsChild(TD->getTypeForDecl());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
void ASTDumper::VisitConstructorUsingShadowDecl(
|
|
|
|
const ConstructorUsingShadowDecl *D) {
|
|
|
|
if (D->constructsVirtualBase())
|
|
|
|
OS << " virtual";
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
OS << "target ";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getTargetDecl());
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
OS << "nominated ";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass());
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
OS << ' ';
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
dumpChild([=] {
|
|
|
|
OS << "constructed ";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass());
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
OS << ' ';
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
switch (D->getLanguage()) {
|
|
|
|
case LinkageSpecDecl::lang_c: OS << " C"; break;
|
|
|
|
case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
OS << ' ';
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpAccessSpecifier(D->getAccess());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
if (TypeSourceInfo *T = D->getFriendType())
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpType(T->getType());
|
2012-12-20 02:09:13 +00:00
|
|
|
else
|
|
|
|
dumpDecl(D->getFriendDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Obj-C Declarations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2012-12-20 02:09:13 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->isInstanceMethod())
|
|
|
|
OS << " -";
|
|
|
|
else
|
|
|
|
OS << " +";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getReturnType());
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2019-01-18 21:38:30 +00:00
|
|
|
if (D->isVariadic())
|
|
|
|
OS << " variadic";
|
|
|
|
|
2019-01-18 22:14:59 +00:00
|
|
|
if (D->isThisDeclarationADefinition())
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpDeclContext(D);
|
2019-01-18 22:14:59 +00:00
|
|
|
else
|
2016-06-24 05:33:44 +00:00
|
|
|
for (const ParmVarDecl *Parameter : D->parameters())
|
|
|
|
dumpDecl(Parameter);
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
if (D->hasBody())
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getBody());
|
|
|
|
}
|
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 03:57:15 +00:00
|
|
|
void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2015-07-07 03:58:54 +00:00
|
|
|
switch (D->getVariance()) {
|
|
|
|
case ObjCTypeParamVariance::Invariant:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCTypeParamVariance::Covariant:
|
|
|
|
OS << " covariant";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCTypeParamVariance::Contravariant:
|
|
|
|
OS << " contravariant";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 03:57:15 +00:00
|
|
|
if (D->hasExplicitBound())
|
|
|
|
OS << " bounded";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpType(D->getUnderlyingType());
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 03:57:15 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getClassInterface());
|
|
|
|
NodeDumper.dumpDeclRef(D->getImplementation());
|
2012-12-20 02:09:13 +00:00
|
|
|
for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
|
2013-02-01 12:35:51 +00:00
|
|
|
E = D->protocol_end();
|
2014-10-30 21:02:37 +00:00
|
|
|
I != E; ++I)
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(*I);
|
2019-01-15 23:07:30 +00:00
|
|
|
dumpObjCTypeParamList(D->getTypeParamList());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getClassInterface());
|
|
|
|
NodeDumper.dumpDeclRef(D->getCategoryDecl());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2014-03-18 02:37:59 +00:00
|
|
|
for (auto *Child : D->protocols())
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(Child);
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
|
2014-03-17 23:00:06 +00:00
|
|
|
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getImplementation());
|
2014-03-18 02:37:59 +00:00
|
|
|
for (auto *Child : D->protocols())
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(Child);
|
2019-01-15 23:07:30 +00:00
|
|
|
dumpObjCTypeParamList(D->getTypeParamListAsWritten());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
|
|
|
|
NodeDumper.dumpDeclRef(D->getClassInterface());
|
2013-02-01 12:35:51 +00:00
|
|
|
for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
|
|
|
|
E = D->init_end();
|
2014-10-30 21:02:37 +00:00
|
|
|
I != E; ++I)
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpCXXCtorInitializer(*I);
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getClassInterface());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D);
|
|
|
|
NodeDumper.dumpType(D->getType());
|
2012-12-20 02:09:13 +00:00
|
|
|
|
|
|
|
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";
|
2016-01-26 18:52:43 +00:00
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
|
|
|
|
OS << " class";
|
2014-10-30 21:02:37 +00:00
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter");
|
2014-10-30 21:02:37 +00:00
|
|
|
if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter");
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpName(D->getPropertyDecl());
|
2012-12-20 02:09:13 +00:00
|
|
|
if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
|
|
|
|
OS << " synthesize";
|
|
|
|
else
|
|
|
|
OS << " dynamic";
|
2019-01-08 23:11:24 +00:00
|
|
|
NodeDumper.dumpDeclRef(D->getPropertyDecl());
|
|
|
|
NodeDumper.dumpDeclRef(D->getPropertyIvarDecl());
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2019-01-15 20:41:37 +00:00
|
|
|
void ASTDumper::Visit(const BlockDecl::Capture &C) {
|
|
|
|
dumpChild([=] {
|
|
|
|
NodeDumper.Visit(C);
|
|
|
|
if (C.hasCopyExpr())
|
|
|
|
dumpStmt(C.getCopyExpr());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
|
2019-01-18 21:38:30 +00:00
|
|
|
if (D->isVariadic())
|
|
|
|
OS << " variadic";
|
|
|
|
|
2019-01-18 21:55:24 +00:00
|
|
|
if (D->capturesCXXThis())
|
|
|
|
OS << " captures_this";
|
|
|
|
|
2016-06-24 04:05:48 +00:00
|
|
|
for (auto I : D->parameters())
|
2014-03-07 16:09:59 +00:00
|
|
|
dumpDecl(I);
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2019-01-15 20:41:37 +00:00
|
|
|
for (const auto &I : D->captures())
|
|
|
|
Visit(I);
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpStmt(D->getBody());
|
2007-08-08 22:51:59 +00:00
|
|
|
}
|
|
|
|
|
2012-12-11 15:20:44 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-11 15:28:09 +00:00
|
|
|
// Stmt dumping methods.
|
2012-12-11 15:20:44 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-01-11 19:11:17 +00:00
|
|
|
void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) {
|
|
|
|
dumpChild(Label, [=] {
|
2019-01-12 16:53:27 +00:00
|
|
|
NodeDumper.Visit(S);
|
|
|
|
|
2014-10-30 21:02:37 +00:00
|
|
|
if (!S) {
|
|
|
|
return;
|
|
|
|
}
|
2018-12-06 23:33:33 +00:00
|
|
|
|
2018-12-03 21:05:52 +00:00
|
|
|
ConstStmtVisitor<ASTDumper>::Visit(S);
|
|
|
|
|
2018-01-05 21:31:07 +00:00
|
|
|
// Some statements have custom mechanisms for dumping their children.
|
2018-12-03 21:05:52 +00:00
|
|
|
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
|
2018-01-05 21:31:07 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-12-11 15:20:44 +00:00
|
|
|
|
2015-07-02 21:03:14 +00:00
|
|
|
for (const Stmt *SubStmt : S->children())
|
|
|
|
dumpStmt(SubStmt);
|
2014-10-30 21:02:37 +00:00
|
|
|
});
|
2012-12-11 15:20:44 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
|
|
|
|
for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
|
|
|
|
E = Node->decl_end();
|
2014-10-30 21:02:37 +00:00
|
|
|
I != E; ++I)
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpDecl(*I);
|
2007-12-12 06:59:42 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
|
|
|
|
for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
|
|
|
|
E = Node->getAttrs().end();
|
2014-10-30 21:02:37 +00:00
|
|
|
I != E; ++I)
|
2013-01-07 17:53:08 +00:00
|
|
|
dumpAttr(*I);
|
|
|
|
}
|
|
|
|
|
2013-09-04 14:35:00 +00:00
|
|
|
void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
|
|
|
|
dumpDecl(Node->getExceptionDecl());
|
|
|
|
}
|
|
|
|
|
2016-03-31 09:30:50 +00:00
|
|
|
void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) {
|
|
|
|
dumpDecl(Node->getCapturedDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenMP dumping methods.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-01-15 20:31:31 +00:00
|
|
|
void ASTDumper::Visit(const OMPClause *C) {
|
|
|
|
dumpChild([=] {
|
|
|
|
NodeDumper.Visit(C);
|
|
|
|
for (auto *S : C->children())
|
|
|
|
dumpStmt(S);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-03-31 09:30:50 +00:00
|
|
|
void ASTDumper::VisitOMPExecutableDirective(
|
|
|
|
const OMPExecutableDirective *Node) {
|
2019-01-15 20:31:31 +00:00
|
|
|
for (const auto *C : Node->clauses())
|
|
|
|
Visit(C);
|
2016-03-31 09:30:50 +00:00
|
|
|
}
|
|
|
|
|
2007-08-08 22:51:59 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2012-12-11 15:28:09 +00:00
|
|
|
// Expr dumping methods.
|
2007-08-08 22:51:59 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-08-30 01:00:35 +00:00
|
|
|
|
2014-06-03 08:24:28 +00:00
|
|
|
void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
|
|
|
|
if (auto *Filler = ILE->getArrayFiller()) {
|
2019-01-11 19:11:17 +00:00
|
|
|
dumpStmt(Filler, "array_filler");
|
2014-06-03 08:24:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
|
2012-12-20 02:09:13 +00:00
|
|
|
dumpDecl(Node->getBlockDecl());
|
2011-02-07 10:33:21 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
|
2014-10-30 21:02:37 +00:00
|
|
|
if (Expr *Source = Node->getSourceExpr())
|
2012-12-11 15:20:44 +00:00
|
|
|
dumpStmt(Source);
|
2011-11-06 09:01:30 +00:00
|
|
|
}
|
|
|
|
|
2018-01-05 21:31:07 +00:00
|
|
|
void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
|
|
|
|
if (E->isResultDependent())
|
|
|
|
OS << " result_dependent";
|
|
|
|
dumpStmt(E->getControllingExpr());
|
|
|
|
dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
|
|
|
|
dumpChild([=] {
|
|
|
|
if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) {
|
|
|
|
OS << "case ";
|
2018-12-05 21:12:39 +00:00
|
|
|
NodeDumper.dumpType(TSI->getType());
|
2018-01-05 21:31:07 +00:00
|
|
|
} else {
|
|
|
|
OS << "default";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!E->isResultDependent() && E->getResultIndex() == I)
|
|
|
|
OS << " selected";
|
|
|
|
|
|
|
|
if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I))
|
|
|
|
dumpTypeAsChild(TSI->getType());
|
|
|
|
dumpStmt(E->getAssocExpr(I));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-09 18:03:18 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Expressions
|
|
|
|
//===----------------------------------------------------------------------===//
|
2007-08-08 22:51:59 +00:00
|
|
|
|
2015-02-16 19:58:41 +00:00
|
|
|
void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
|
2015-09-23 21:41:42 +00:00
|
|
|
if (Node->isPartiallySubstituted())
|
|
|
|
for (const auto &A : Node->getPartialArguments())
|
|
|
|
dumpTemplateArgument(A);
|
2015-02-16 19:58:41 +00:00
|
|
|
}
|
|
|
|
|
2007-08-21 17:43:55 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Obj-C Expressions
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-01 12:35:51 +00:00
|
|
|
void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
|
|
|
|
if (const VarDecl *CatchParam = Node->getCatchParamDecl())
|
2012-12-11 15:20:44 +00:00
|
|
|
dumpDecl(CatchParam);
|
2012-03-06 20:05:56 +00:00
|
|
|
}
|
|
|
|
|
2013-01-14 14:07:11 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Comments
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2018-12-02 17:30:40 +00:00
|
|
|
void ASTDumper::dumpComment(const Comment *C, const FullComment *FC) {
|
2014-10-30 21:02:37 +00:00
|
|
|
dumpChild([=] {
|
2018-12-09 13:30:17 +00:00
|
|
|
NodeDumper.Visit(C, FC);
|
2014-10-30 21:02:37 +00:00
|
|
|
if (!C) {
|
|
|
|
return;
|
|
|
|
}
|
2018-12-02 17:30:40 +00:00
|
|
|
ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC);
|
2014-10-30 21:02:37 +00:00
|
|
|
for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
|
|
|
|
I != E; ++I)
|
2018-12-02 17:30:40 +00:00
|
|
|
dumpComment(*I, FC);
|
2014-10-30 21:02:37 +00:00
|
|
|
});
|
2013-01-14 14:07:11 +00:00
|
|
|
}
|
|
|
|
|
2014-10-31 01:17:45 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Type method implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void QualType::dump(const char *msg) const {
|
|
|
|
if (msg)
|
|
|
|
llvm::errs() << msg << ": ";
|
|
|
|
dump();
|
|
|
|
}
|
|
|
|
|
2016-11-02 23:57:18 +00:00
|
|
|
LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
|
|
|
|
|
|
|
|
LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
|
|
|
|
ASTDumper Dumper(OS, nullptr, nullptr);
|
2014-10-31 01:17:45 +00:00
|
|
|
Dumper.dumpTypeAsChild(*this);
|
|
|
|
}
|
|
|
|
|
2016-11-02 23:57:18 +00:00
|
|
|
LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
|
|
|
|
|
|
|
|
LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
|
|
|
|
QualType(this, 0).dump(OS);
|
|
|
|
}
|
2014-10-31 01:17:45 +00:00
|
|
|
|
2012-12-20 02:09:13 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Decl method implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
|
2012-12-20 02:09:13 +00:00
|
|
|
|
2017-03-09 22:00:01 +00:00
|
|
|
LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const {
|
2017-12-21 21:42:42 +00:00
|
|
|
const ASTContext &Ctx = getASTContext();
|
|
|
|
const SourceManager &SM = Ctx.getSourceManager();
|
|
|
|
ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
|
|
|
|
SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
|
2017-03-09 22:00:01 +00:00
|
|
|
P.setDeserialize(Deserialize);
|
2013-02-01 12:35:51 +00:00
|
|
|
P.dumpDecl(this);
|
2012-12-20 02:09:13 +00:00
|
|
|
}
|
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Decl::dumpColor() const {
|
2017-12-21 21:42:42 +00:00
|
|
|
const ASTContext &Ctx = getASTContext();
|
|
|
|
ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
|
|
|
|
&Ctx.getSourceManager(), /*ShowColors*/ true,
|
|
|
|
Ctx.getPrintingPolicy());
|
2013-02-01 12:35:51 +00:00
|
|
|
P.dumpDecl(this);
|
2013-01-26 01:31:20 +00:00
|
|
|
}
|
2013-06-22 21:49:40 +00:00
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
|
2013-06-24 01:45:33 +00:00
|
|
|
dumpLookups(llvm::errs());
|
|
|
|
}
|
|
|
|
|
2014-08-11 22:11:07 +00:00
|
|
|
LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
|
2017-03-09 22:00:01 +00:00
|
|
|
bool DumpDecls,
|
|
|
|
bool Deserialize) const {
|
2013-06-22 21:49:40 +00:00
|
|
|
const DeclContext *DC = this;
|
|
|
|
while (!DC->isTranslationUnit())
|
|
|
|
DC = DC->getParent();
|
|
|
|
ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
|
2017-12-21 21:42:42 +00:00
|
|
|
const SourceManager &SM = Ctx.getSourceManager();
|
|
|
|
ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(),
|
|
|
|
SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
|
2017-03-09 22:00:01 +00:00
|
|
|
P.setDeserialize(Deserialize);
|
2014-08-11 22:11:07 +00:00
|
|
|
P.dumpLookups(this, DumpDecls);
|
2013-06-22 21:49:40 +00:00
|
|
|
}
|
|
|
|
|
2007-08-08 22:51:59 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Stmt method implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
|
2010-08-09 10:54:31 +00:00
|
|
|
dump(llvm::errs(), SM);
|
|
|
|
}
|
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
|
2014-05-12 05:36:57 +00:00
|
|
|
ASTDumper P(OS, nullptr, &SM);
|
2013-02-01 12:35:51 +00:00
|
|
|
P.dumpStmt(this);
|
2007-08-30 00:40:08 +00:00
|
|
|
}
|
|
|
|
|
2015-03-22 13:35:56 +00:00
|
|
|
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
|
|
|
|
ASTDumper P(OS, nullptr, nullptr);
|
|
|
|
P.dumpStmt(this);
|
|
|
|
}
|
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Stmt::dump() const {
|
2014-05-12 05:36:57 +00:00
|
|
|
ASTDumper P(llvm::errs(), nullptr, nullptr);
|
2013-02-01 12:35:51 +00:00
|
|
|
P.dumpStmt(this);
|
2007-08-08 22:51:59 +00:00
|
|
|
}
|
2013-01-14 14:07:11 +00:00
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Stmt::dumpColor() const {
|
2014-05-12 05:36:57 +00:00
|
|
|
ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
|
2013-02-01 12:35:51 +00:00
|
|
|
P.dumpStmt(this);
|
2013-01-26 01:31:20 +00:00
|
|
|
}
|
|
|
|
|
2013-01-14 14:07:11 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Comment method implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-05-12 05:36:57 +00:00
|
|
|
LLVM_DUMP_METHOD void Comment::dump() const {
|
|
|
|
dump(llvm::errs(), nullptr, nullptr);
|
|
|
|
}
|
2013-01-14 14:07:11 +00:00
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
|
2013-01-14 14:07:11 +00:00
|
|
|
dump(llvm::errs(), &Context.getCommentCommandTraits(),
|
|
|
|
&Context.getSourceManager());
|
|
|
|
}
|
|
|
|
|
2013-01-15 12:20:21 +00:00
|
|
|
void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
|
2013-01-14 14:07:11 +00:00
|
|
|
const SourceManager *SM) const {
|
|
|
|
const FullComment *FC = dyn_cast<FullComment>(this);
|
2018-12-09 13:18:55 +00:00
|
|
|
if (!FC)
|
|
|
|
return;
|
2013-01-14 14:07:11 +00:00
|
|
|
ASTDumper D(OS, Traits, SM);
|
2018-12-09 13:18:55 +00:00
|
|
|
D.dumpComment(FC, FC);
|
2013-01-14 14:07:11 +00:00
|
|
|
}
|
2013-01-26 01:31:20 +00:00
|
|
|
|
2014-01-04 13:47:14 +00:00
|
|
|
LLVM_DUMP_METHOD void Comment::dumpColor() const {
|
2013-01-26 01:31:20 +00:00
|
|
|
const FullComment *FC = dyn_cast<FullComment>(this);
|
2018-12-09 13:18:55 +00:00
|
|
|
if (!FC)
|
|
|
|
return;
|
2014-05-12 05:36:57 +00:00
|
|
|
ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
|
2018-12-09 13:18:55 +00:00
|
|
|
D.dumpComment(FC, FC);
|
2013-01-26 01:31:20 +00:00
|
|
|
}
|