15
15
#define LLVM_CLANG_AST_ASTCONTEXT_H
16
16
17
17
#include " clang/AST/ASTContextAllocate.h"
18
- #include " clang/AST/ASTTypeTraits .h"
18
+ #include " clang/AST/ASTFwd .h"
19
19
#include " clang/AST/CanonicalType.h"
20
20
#include " clang/AST/CommentCommandTraits.h"
21
21
#include " clang/AST/ComparisonCategories.h"
26
26
#include " clang/AST/NestedNameSpecifier.h"
27
27
#include " clang/AST/PrettyPrinter.h"
28
28
#include " clang/AST/RawCommentList.h"
29
- #include " clang/AST/TemplateBase.h"
30
29
#include " clang/AST/TemplateName.h"
31
30
#include " clang/AST/Type.h"
32
31
#include " clang/Basic/AddressSpaces.h"
@@ -94,6 +93,8 @@ class CXXConstructorDecl;
94
93
class CXXMethodDecl ;
95
94
class CXXRecordDecl ;
96
95
class DiagnosticsEngine ;
96
+ class ParentMapContext ;
97
+ class DynTypedNodeList ;
97
98
class Expr ;
98
99
class FixedPointSemantics ;
99
100
class GlobalDecl ;
@@ -129,6 +130,10 @@ class VarTemplateDecl;
129
130
class VTableContextBase ;
130
131
struct BlockVarCopyInit ;
131
132
133
+ namespace ast_type_traits {
134
+ class DynTypedNode ;
135
+ }
136
+
132
137
namespace Builtin {
133
138
134
139
class Context ;
@@ -565,18 +570,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
565
570
const TargetInfo *AuxTarget = nullptr ;
566
571
clang::PrintingPolicy PrintingPolicy;
567
572
std::unique_ptr<interp::Context> InterpContext;
568
-
569
- ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs;
573
+ std::unique_ptr<ParentMapContext> ParentMapCtx;
570
574
571
575
public:
572
- ast_type_traits::TraversalKind getTraversalKind () const { return Traversal; }
573
- void setTraversalKind (ast_type_traits::TraversalKind TK) { Traversal = TK; }
574
-
575
- const Expr *traverseIgnored (const Expr *E) const ;
576
- Expr *traverseIgnored (Expr *E) const ;
577
- ast_type_traits::DynTypedNode
578
- traverseIgnored (const ast_type_traits::DynTypedNode &N) const ;
579
-
580
576
IdentifierTable &Idents;
581
577
SelectorTable &Selectors;
582
578
Builtin::Context &BuiltinInfo;
@@ -587,46 +583,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
587
583
// / Returns the clang bytecode interpreter context.
588
584
interp::Context &getInterpContext ();
589
585
590
- // / Container for either a single DynTypedNode or for an ArrayRef to
591
- // / DynTypedNode. For use with ParentMap.
592
- class DynTypedNodeList {
593
- using DynTypedNode = ast_type_traits::DynTypedNode;
594
-
595
- llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
596
- ArrayRef<DynTypedNode>> Storage;
597
- bool IsSingleNode;
598
-
599
- public:
600
- DynTypedNodeList (const DynTypedNode &N) : IsSingleNode(true ) {
601
- new (Storage.buffer ) DynTypedNode (N);
602
- }
603
-
604
- DynTypedNodeList (ArrayRef<DynTypedNode> A) : IsSingleNode(false ) {
605
- new (Storage.buffer ) ArrayRef<DynTypedNode>(A);
606
- }
607
-
608
- const ast_type_traits::DynTypedNode *begin () const {
609
- if (!IsSingleNode)
610
- return reinterpret_cast <const ArrayRef<DynTypedNode> *>(Storage.buffer )
611
- ->begin ();
612
- return reinterpret_cast <const DynTypedNode *>(Storage.buffer );
613
- }
614
-
615
- const ast_type_traits::DynTypedNode *end () const {
616
- if (!IsSingleNode)
617
- return reinterpret_cast <const ArrayRef<DynTypedNode> *>(Storage.buffer )
618
- ->end ();
619
- return reinterpret_cast <const DynTypedNode *>(Storage.buffer ) + 1 ;
620
- }
621
-
622
- size_t size () const { return end () - begin (); }
623
- bool empty () const { return begin () == end (); }
624
-
625
- const DynTypedNode &operator [](size_t N) const {
626
- assert (N < size () && " Out of bounds!" );
627
- return *(begin () + N);
628
- }
629
- };
586
+ // / Returns the dynamic AST node parent map context.
587
+ ParentMapContext &getParentMapContext ();
630
588
631
589
// A traversal scope limits the parts of the AST visible to certain analyses.
632
590
// RecursiveASTVisitor::TraverseAST will only visit reachable nodes, and
@@ -638,35 +596,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
638
596
std::vector<Decl *> getTraversalScope () const { return TraversalScope; }
639
597
void setTraversalScope (const std::vector<Decl *> &);
640
598
641
- // / Returns the parents of the given node (within the traversal scope).
642
- // /
643
- // / Note that this will lazily compute the parents of all nodes
644
- // / and store them for later retrieval. Thus, the first call is O(n)
645
- // / in the number of AST nodes.
646
- // /
647
- // / Caveats and FIXMEs:
648
- // / Calculating the parent map over all AST nodes will need to load the
649
- // / full AST. This can be undesirable in the case where the full AST is
650
- // / expensive to create (for example, when using precompiled header
651
- // / preambles). Thus, there are good opportunities for optimization here.
652
- // / One idea is to walk the given node downwards, looking for references
653
- // / to declaration contexts - once a declaration context is found, compute
654
- // / the parent map for the declaration context; if that can satisfy the
655
- // / request, loading the whole AST can be avoided. Note that this is made
656
- // / more complex by statements in templates having multiple parents - those
657
- // / problems can be solved by building closure over the templated parts of
658
- // / the AST, which also avoids touching large parts of the AST.
659
- // / Additionally, we will want to add an interface to already give a hint
660
- // / where to search for the parents, for example when looking at a statement
661
- // / inside a certain function.
662
- // /
663
- // / 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
664
- // / NestedNameSpecifier or NestedNameSpecifierLoc.
665
- template <typename NodeT> DynTypedNodeList getParents (const NodeT &Node) {
666
- return getParents (ast_type_traits::DynTypedNode::create (Node));
667
- }
668
-
669
- DynTypedNodeList getParents (const ast_type_traits::DynTypedNode &Node);
599
+ // / Forwards to get node parents from the ParentMapContext. New callers should
600
+ // / use ParentMapContext::getParents() directly.
601
+ template <typename NodeT> DynTypedNodeList getParents (const NodeT &Node);
670
602
671
603
const clang::PrintingPolicy &getPrintingPolicy () const {
672
604
return PrintingPolicy;
@@ -3026,8 +2958,6 @@ OPT_LIST(V)
3026
2958
llvm::PointerIntPair<StoredDeclsMap *, 1 > LastSDM;
3027
2959
3028
2960
std::vector<Decl *> TraversalScope;
3029
- class ParentMap ;
3030
- std::map<ast_type_traits::TraversalKind, std::unique_ptr<ParentMap>> Parents;
3031
2961
3032
2962
std::unique_ptr<VTableContextBase> VTContext;
3033
2963
@@ -3071,22 +3001,6 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
3071
3001
return Ctx.Selectors .getSelector (1 , &II);
3072
3002
}
3073
3003
3074
- class TraversalKindScope {
3075
- ASTContext &Ctx;
3076
- ast_type_traits::TraversalKind TK = ast_type_traits::TK_AsIs;
3077
-
3078
- public:
3079
- TraversalKindScope (ASTContext &Ctx,
3080
- llvm::Optional<ast_type_traits::TraversalKind> ScopeTK)
3081
- : Ctx(Ctx) {
3082
- TK = Ctx.getTraversalKind ();
3083
- if (ScopeTK)
3084
- Ctx.setTraversalKind (*ScopeTK);
3085
- }
3086
-
3087
- ~TraversalKindScope () { Ctx.setTraversalKind (TK); }
3088
- };
3089
-
3090
3004
} // namespace clang
3091
3005
3092
3006
// operator new and delete aren't allowed inside namespaces.
0 commit comments