A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/ASTMatchFinder_8cpp_source.html below:

clang: lib/ASTMatchers/ASTMatchFinder.cpp Source File

23#include "llvm/ADT/DenseMap.h" 24#include "llvm/ADT/SmallPtrSet.h" 25#include "llvm/ADT/StringMap.h" 26#include "llvm/Support/PrettyStackTrace.h" 27#include "llvm/Support/Timer.h" 33namespace

ast_matchers {

37typedef

MatchFinder::MatchCallback MatchCallback;

47static const unsigned

MaxMemoizationEntries = 10000;

83struct

MemoizedMatchResult {

90class

MatchChildASTVisitor

91

:

public

RecursiveASTVisitor<MatchChildASTVisitor> {

93 typedef

RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;

99

MatchChildASTVisitor(

const

DynTypedMatcher *Matcher, ASTMatchFinder *Finder,

100

BoundNodesTreeBuilder *Builder,

int

MaxDepth,

101 bool

IgnoreImplicitChildren,

102

ASTMatchFinder::BindKind Bind)

103

: Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0),

104

MaxDepth(MaxDepth), IgnoreImplicitChildren(IgnoreImplicitChildren),

105

Bind(Bind), Matches(

false

) {}

118 bool

findMatch(

const

DynTypedNode &DynNode) {

120 if

(

const

Decl *

D

= DynNode.get<Decl>())

122 else if

(

const

Stmt *S = DynNode.get<Stmt>())

124 else if

(

const

NestedNameSpecifier *NNS =

125

DynNode.get<NestedNameSpecifier>())

127 else if

(

const

NestedNameSpecifierLoc *NNSLoc =

128

DynNode.get<NestedNameSpecifierLoc>())

130 else if

(

const

QualType *Q = DynNode.get<QualType>())

132 else if

(

const

TypeLoc *

T

= DynNode.get<TypeLoc>())

134 else if

(

const auto

*

C

= DynNode.get<CXXCtorInitializer>())

136 else if

(

const

TemplateArgumentLoc *TALoc =

137

DynNode.get<TemplateArgumentLoc>())

139 else if

(

const

Attr *A = DynNode.get<Attr>())

146

*Builder = ResultBindings;

154 bool

TraverseDecl(Decl *DeclNode) {

156 if

(DeclNode && DeclNode->isImplicit() &&

157

Finder->isTraversalIgnoringImplicitNodes())

158 return

baseTraverse(*DeclNode);

160

ScopedIncrement ScopedDepth(&CurrentDepth);

161 return

(DeclNode ==

nullptr

) ||

traverse

(*DeclNode);

164

Stmt *getStmtToTraverse(Stmt *StmtNode) {

165

Stmt *StmtToTraverse = StmtNode;

166 if

(

auto

*ExprNode = dyn_cast_or_null<Expr>(StmtNode)) {

167 auto

*LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode);

168 if

(LambdaNode && Finder->isTraversalIgnoringImplicitNodes())

169

StmtToTraverse = LambdaNode;

172

Finder->getASTContext().getParentMapContext().traverseIgnored(

175 return

StmtToTraverse;

178 bool

TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue =

nullptr

) {

180 if

(CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth <

INT_MAX

))

183

ScopedIncrement ScopedDepth(&CurrentDepth);

184

Stmt *StmtToTraverse = getStmtToTraverse(StmtNode);

188 if

(IgnoreImplicitChildren && isa<CXXDefaultArgExpr>(StmtNode))

191 if

(!

match

(*StmtToTraverse))

197 bool

TraverseType(QualType TypeNode) {

198 if

(TypeNode.isNull())

200

ScopedIncrement ScopedDepth(&CurrentDepth);

202 if

(!

match

(*TypeNode))

209 bool

TraverseTypeLoc(TypeLoc TypeLocNode) {

210 if

(TypeLocNode.isNull())

212

ScopedIncrement ScopedDepth(&CurrentDepth);

214 if

(!

match

(*TypeLocNode.getType()))

217 if

(!

match

(TypeLocNode.getType()))

222 bool

TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {

223

ScopedIncrement ScopedDepth(&CurrentDepth);

224 return

(NNS ==

nullptr

) ||

traverse

(*NNS);

226 bool

TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {

229

ScopedIncrement ScopedDepth(&CurrentDepth);

230 if

(!

match

(*NNS.getNestedNameSpecifier()))

234 bool

TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) {

237

ScopedIncrement ScopedDepth(&CurrentDepth);

240 bool

TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) {

241

ScopedIncrement ScopedDepth(&CurrentDepth);

244 bool

TraverseCXXForRangeStmt(CXXForRangeStmt *

Node

) {

245 if

(!Finder->isTraversalIgnoringImplicitNodes())

246 return

VisitorBase::TraverseCXXForRangeStmt(

Node

);

249

ScopedIncrement ScopedDepth(&CurrentDepth);

250 if

(

auto

*

Init

=

Node

->getInit())

253 if

(!

match

(*

Node

->getLoopVariable()))

262 bool

TraverseCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *

Node

) {

263 if

(!Finder->isTraversalIgnoringImplicitNodes())

264 return

VisitorBase::TraverseCXXRewrittenBinaryOperator(

Node

);

267

ScopedIncrement ScopedDepth(&CurrentDepth);

271 bool

TraverseAttr(Attr *A) {

274

Finder->getASTContext().getParentMapContext().getTraversalKind() ==

277

ScopedIncrement ScopedDepth(&CurrentDepth);

280 bool

TraverseLambdaExpr(LambdaExpr *

Node

) {

281 if

(!Finder->isTraversalIgnoringImplicitNodes())

282 return

VisitorBase::TraverseLambdaExpr(

Node

);

285

ScopedIncrement ScopedDepth(&CurrentDepth);

287 for

(

unsigned

I = 0, N =

Node

->capture_size(); I != N; ++I) {

288 const

LambdaCapture *

C

=

Node

->capture_begin() + I;

289 if

(!

C

->isExplicit())

291 if

(

Node

->isInitCapture(

C

) && !

match

(*

C

->getCapturedVar()))

293 const

Expr *CIE =

Node

->capture_init_begin()[I];

294 if

(CIE !=

nullptr

&& !

match

(*CIE))

298 if

(

const auto

*TPL =

Node

->getTemplateParameterList()) {

299 for

(

const auto

*TP : *TPL) {

305 for

(

const auto

*

P

:

Node

->getCallOperator()->parameters()) {

316 bool

shouldVisitTemplateInstantiations()

const

{

return true

; }

317 bool

shouldVisitImplicitCode()

const

{

return

!IgnoreImplicitChildren; }

321 struct

ScopedIncrement {

322 explicit

ScopedIncrement(

int

*Depth) : Depth(Depth) { ++(*Depth); }

323

~ScopedIncrement() { --(*Depth); }

337 bool

baseTraverse(

const

Decl &DeclNode) {

340 bool

baseTraverse(

const

Stmt &StmtNode) {

343 bool

baseTraverse(QualType TypeNode) {

346 bool

baseTraverse(TypeLoc TypeLocNode) {

349 bool

baseTraverse(

const

NestedNameSpecifier &NNS) {

351 const_cast<

NestedNameSpecifier*

>

(&NNS));

353 bool

baseTraverse(NestedNameSpecifierLoc NNS) {

356 bool

baseTraverse(

const

CXXCtorInitializer &CtorInit) {

358 const_cast<

CXXCtorInitializer *

>

(&CtorInit));

360 bool

baseTraverse(TemplateArgumentLoc TAL) {

363 bool

baseTraverse(

const

Attr &AttrNode) {

372 template

<

typename

T>

374 if

(CurrentDepth == 0 || CurrentDepth > MaxDepth) {

377 if

(Bind != ASTMatchFinder::BK_All) {

378

BoundNodesTreeBuilder RecursiveBuilder(*Builder);

380

&RecursiveBuilder)) {

382

ResultBindings.addMatch(RecursiveBuilder);

386

BoundNodesTreeBuilder RecursiveBuilder(*Builder);

388

&RecursiveBuilder)) {

391

ResultBindings.addMatch(RecursiveBuilder);

399 template

<

typename

T>

401 static_assert

(IsBaseType<T>::value,

402 "traverse can only be instantiated with base type"

);

405 return

baseTraverse(

Node

);

408 const

DynTypedMatcher *

const

Matcher;

409

ASTMatchFinder *

const

Finder;

410

BoundNodesTreeBuilder *

const

Builder;

411

BoundNodesTreeBuilder ResultBindings;

414 const bool

IgnoreImplicitChildren;

415 const

ASTMatchFinder::BindKind Bind;

421class

MatchASTVisitor :

public

RecursiveASTVisitor<MatchASTVisitor>,

422 public

ASTMatchFinder {

424

MatchASTVisitor(

const

MatchFinder::MatchersByType *Matchers,

425 const

MatchFinder::MatchFinderOptions &Options)

426

: Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {}

428

~MatchASTVisitor()

override

{

429 if

(Options.CheckProfiling) {

430

Options.CheckProfiling->Records = std::move(TimeByBucket);

434 void

onStartOfTranslationUnit() {

435 const bool

EnableCheckProfiling = Options.CheckProfiling.has_value();

436

TimeBucketRegion Timer;

437 for

(MatchCallback *MC : Matchers->AllCallbacks) {

438 if

(EnableCheckProfiling)

439

Timer.setBucket(&TimeByBucket[MC->getID()]);

440

MC->onStartOfTranslationUnit();

444 void

onEndOfTranslationUnit() {

445 const bool

EnableCheckProfiling = Options.CheckProfiling.has_value();

446

TimeBucketRegion Timer;

447 for

(MatchCallback *MC : Matchers->AllCallbacks) {

448 if

(EnableCheckProfiling)

449

Timer.setBucket(&TimeByBucket[MC->getID()]);

450

MC->onEndOfTranslationUnit();

454 void

set_active_ast_context(ASTContext *NewActiveASTContext) {

455

ActiveASTContext = NewActiveASTContext;

461 bool

VisitTypedefNameDecl(TypedefNameDecl *DeclNode) {

489 const Type

*TypeNode = DeclNode->getUnderlyingType().getTypePtr();

490 const Type

*CanonicalType =

491

ActiveASTContext->getCanonicalType(TypeNode);

492

TypeAliases[CanonicalType].insert(DeclNode);

496 bool

VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {

497 const

ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface();

498

CompatibleAliases[InterfaceDecl].insert(CAD);

502 bool

TraverseDecl(Decl *DeclNode);

503 bool

TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue =

nullptr

);

504 bool

TraverseType(QualType TypeNode);

505 bool

TraverseTypeLoc(TypeLoc TypeNode);

506 bool

TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);

507 bool

TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);

508 bool

TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);

509 bool

TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL);

510 bool

TraverseAttr(Attr *AttrNode);

512 bool

dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) {

513 if

(

auto

*RF = dyn_cast<CXXForRangeStmt>(S)) {

515

ASTNodeNotAsIsSourceScope RAII(

this

,

true

);

516

TraverseStmt(RF->getInit());

518 match

(*RF->getLoopVariable());

519

TraverseStmt(RF->getRangeInit());

522

ASTNodeNotSpelledInSourceScope RAII(

this

,

true

);

523 for

(

auto

*SubStmt : RF->children()) {

524 if

(SubStmt != RF->getBody())

525

TraverseStmt(SubStmt);

528

TraverseStmt(RF->getBody());

530

}

else if

(

auto

*RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {

532

ASTNodeNotAsIsSourceScope RAII(

this

,

true

);

533

TraverseStmt(

const_cast<

Expr *

>

(RBO->getLHS()));

534

TraverseStmt(

const_cast<

Expr *

>

(RBO->getRHS()));

537

ASTNodeNotSpelledInSourceScope RAII(

this

,

true

);

538 for

(

auto

*SubStmt : RBO->children()) {

539

TraverseStmt(SubStmt);

543

}

else if

(

auto

*LE = dyn_cast<LambdaExpr>(S)) {

544 for

(

auto

I : llvm::zip(

LE

->captures(),

LE

->capture_inits())) {

545 auto C

= std::get<0>(I);

546

ASTNodeNotSpelledInSourceScope RAII(

547 this

, TraversingASTNodeNotSpelledInSource || !

C

.isExplicit());

548

TraverseLambdaCapture(LE, &

C

, std::get<1>(I));

552

ASTNodeNotSpelledInSourceScope RAII(

this

,

true

);

553

TraverseDecl(

LE

->getLambdaClass());

556

ASTNodeNotAsIsSourceScope RAII(

this

,

true

);

560

TypeLoc TL =

LE

->getCallOperator()->getTypeSourceInfo()->getTypeLoc();

561

FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();

563 if

(

auto

*TPL =

LE

->getTemplateParameterList()) {

564 for

(NamedDecl *

D

: *TPL) {

567 if

(Expr *RequiresClause = TPL->getRequiresClause()) {

568

TraverseStmt(RequiresClause);

572 if

(

LE

->hasExplicitParameters()) {

574 for

(ParmVarDecl *Param : Proto.getParams())

578 const auto

*

T

= Proto.getTypePtr();

583

TraverseStmt(NE, Queue);

585 if

(

LE

->hasExplicitResultType())

586

TraverseTypeLoc(Proto.getReturnLoc());

587

TraverseStmt(

LE

->getTrailingRequiresClause());

590

TraverseStmt(

LE

->getBody());

597 bool

memoizedMatchesRecursively(

const

DynTypedNode &

Node

, ASTContext &Ctx,

598 const

DynTypedMatcher &Matcher,

599

BoundNodesTreeBuilder *Builder,

int

MaxDepth,

602 if

(!

Node

.getMemoizationData() || !Builder->isComparable())

603 return

matchesRecursively(

Node

, Matcher, Builder, MaxDepth,

Bind

);

606

Key.MatcherID = Matcher.getID();

609

Key.BoundNodes = *Builder;

610

Key.Traversal = Ctx.getParentMapContext().getTraversalKind();

612

Key.Type = MaxDepth == 1 ? MatchType::Child : MatchType::Descendants;

613

MemoizationMap::iterator I = ResultCache.find(Key);

614 if

(I != ResultCache.end()) {

615

*Builder = I->second.Nodes;

616 return

I->second.ResultOfMatch;

619

MemoizedMatchResult

Result

;

622

matchesRecursively(

Node

, Matcher, &

Result

.Nodes, MaxDepth,

Bind

);

624

MemoizedMatchResult &CachedResult = ResultCache[Key];

625

CachedResult = std::move(

Result

);

627

*Builder = CachedResult.Nodes;

628 return

CachedResult.ResultOfMatch;

632 bool

matchesRecursively(

const

DynTypedNode &

Node

,

633 const

DynTypedMatcher &Matcher,

634

BoundNodesTreeBuilder *Builder,

int

MaxDepth,

636 bool

ScopedTraversal = TraversingASTNodeNotSpelledInSource ||

637

TraversingASTChildrenNotSpelledInSource;

639 bool

IgnoreImplicitChildren =

false

;

641 if

(isTraversalIgnoringImplicitNodes()) {

642

IgnoreImplicitChildren =

true

;

645

ASTNodeNotSpelledInSourceScope RAII(

this

, ScopedTraversal);

647

MatchChildASTVisitor Visitor(&Matcher,

this

, Builder, MaxDepth,

648

IgnoreImplicitChildren,

Bind

);

649 return

Visitor.findMatch(

Node

);

652 bool

classIsDerivedFrom(

const

CXXRecordDecl *

Declaration

,

653 const

Matcher<NamedDecl> &

Base

,

654

BoundNodesTreeBuilder *Builder,

655 bool

Directly)

override

;

659

classIsDerivedFromImpl(

const

CXXRecordDecl *

Declaration

,

660 const

Matcher<NamedDecl> &

Base

,

661

BoundNodesTreeBuilder *Builder,

bool

Directly,

662

llvm::SmallPtrSetImpl<const CXXRecordDecl *> &

Visited

);

665 bool

objcClassIsDerivedFrom(

const

ObjCInterfaceDecl *

Declaration

,

666 const

Matcher<NamedDecl> &

Base

,

667

BoundNodesTreeBuilder *Builder,

668 bool

Directly)

override

;

672 bool

matchesChildOf(

const

DynTypedNode &

Node

, ASTContext &Ctx,

673 const

DynTypedMatcher &Matcher,

674

BoundNodesTreeBuilder *Builder, BindKind

Bind

)

override

{

675 if

(ResultCache.size() > MaxMemoizationEntries)

677 return

memoizedMatchesRecursively(

Node

, Ctx, Matcher, Builder, 1,

Bind

);

680 bool

matchesDescendantOf(

const

DynTypedNode &

Node

, ASTContext &Ctx,

681 const

DynTypedMatcher &Matcher,

682

BoundNodesTreeBuilder *Builder,

683

BindKind

Bind

)

override

{

684 if

(ResultCache.size() > MaxMemoizationEntries)

686 return

memoizedMatchesRecursively(

Node

, Ctx, Matcher, Builder,

INT_MAX

,

690 bool

matchesAncestorOf(

const

DynTypedNode &

Node

, ASTContext &Ctx,

691 const

DynTypedMatcher &Matcher,

692

BoundNodesTreeBuilder *Builder,

693

AncestorMatchMode MatchMode)

override

{

696 if

(ResultCache.size() > MaxMemoizationEntries)

698 if

(MatchMode == AncestorMatchMode::AMM_ParentOnly)

699 return

matchesParentOf(

Node

, Matcher, Builder);

700 return

matchesAnyAncestorOf(

Node

, Ctx, Matcher, Builder);

705 void match

(

const

DynTypedNode &

Node

) {

707 if

(

auto

*N =

Node

.get<Decl>()) {

709

}

else if

(

auto

*N =

Node

.get<Stmt>()) {

711

}

else if

(

auto

*N =

Node

.get<Type>()) {

713

}

else if

(

auto

*N =

Node

.get<QualType>()) {

715

}

else if

(

auto

*N =

Node

.get<NestedNameSpecifier>()) {

717

}

else if

(

auto

*N =

Node

.get<NestedNameSpecifierLoc>()) {

719

}

else if

(

auto

*N =

Node

.get<TypeLoc>()) {

721

}

else if

(

auto

*N =

Node

.get<CXXCtorInitializer>()) {

723

}

else if

(

auto

*N =

Node

.get<TemplateArgumentLoc>()) {

725

}

else if

(

auto

*N =

Node

.get<Attr>()) {

730 template

<

typename

T>

void match

(

const T

&

Node

) {

731

matchDispatch(&

Node

);

735

ASTContext &getASTContext()

const override

{

return

*ActiveASTContext; }

737 bool

shouldVisitTemplateInstantiations()

const

{

return true

; }

738 bool

shouldVisitImplicitCode()

const

{

return true

; }

742 bool

shouldVisitLambdaBody()

const

{

return false

; }

744 bool

IsMatchingInASTNodeNotSpelledInSource()

const override

{

745 return

TraversingASTNodeNotSpelledInSource;

747 bool

isMatchingChildrenNotSpelledInSource()

const override

{

748 return

TraversingASTChildrenNotSpelledInSource;

750 void

setMatchingChildrenNotSpelledInSource(

bool Set

)

override

{

751

TraversingASTChildrenNotSpelledInSource =

Set

;

754 bool

IsMatchingInASTNodeNotAsIs()

const override

{

755 return

TraversingASTNodeNotAsIs;

758 bool

TraverseTemplateInstantiations(ClassTemplateDecl *

D

) {

759

ASTNodeNotSpelledInSourceScope RAII(

this

,

true

);

760 return

RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(

764 bool

TraverseTemplateInstantiations(VarTemplateDecl *

D

) {

765

ASTNodeNotSpelledInSourceScope RAII(

this

,

true

);

766 return

RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(

770 bool

TraverseTemplateInstantiations(FunctionTemplateDecl *

D

) {

771

ASTNodeNotSpelledInSourceScope RAII(

this

,

true

);

772 return

RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations(

777 bool

TraversingASTNodeNotSpelledInSource =

false

;

778 bool

TraversingASTNodeNotAsIs =

false

;

779 bool

TraversingASTChildrenNotSpelledInSource =

false

;

786 const QualType *, const TypeLoc *, const NestedNameSpecifier *, \ 787 const NestedNameSpecifierLoc * 789 const CXXCtorInitializer *, const TemplateArgumentLoc *, const Attr *, \ 793 template <typename NodeType> \ 795 llvm::is_one_of<const NodeType *, CMD_TYPES_##Index>::value> \ 796 SetCallbackAndRawNode(const MatchCallback *CB, const NodeType &N) { \ 798 Callback.setPointerAndInt(CB, Index); \ 802 template <typename T> \ 803 std::enable_if_t<llvm::is_one_of<const T *, CMD_TYPES_##Index>::value, \ 806 assertHoldsState(); \ 807 return Callback.getInt() == (Index) ? Node##Index.dyn_cast<const T *>() \ 812

CurMatchData() :

Node0

(nullptr) {}

817

const MatchCallback *getCallback()

const

{

return

Callback.getPointer(); }

819 void

SetBoundNodes(

const

BoundNodes &BN) {

824 void

clearBoundNodes() {

836

Callback.setPointerAndInt(

nullptr

, 0);

841 void

assertHoldsState()

const

{

842

assert(Callback.getPointer() !=

nullptr

&& !

Node0

.isNull());

845 void

assertEmpty()

const

{

846

assert(Callback.getPointer() ==

nullptr

&&

Node0

.isNull() &&

850

llvm::PointerIntPair<const MatchCallback *, 1> Callback;

852

llvm::PointerUnion<CMD_TYPES_0>

Node0

;

853

llvm::PointerUnion<CMD_TYPES_1>

Node1

;

862 struct

CurMatchRAII {

863 template

<

typename

NodeType>

864

CurMatchRAII(MatchASTVisitor &MV,

const

MatchCallback *CB,

867

MV.CurMatchState.SetCallbackAndRawNode(CB, NT);

870

~CurMatchRAII() { MV.CurMatchState.reset(); }

877 class

TraceReporter : llvm::PrettyStackTraceEntry {

878 static void

dumpNode(

const

ASTContext &Ctx,

const

DynTypedNode &

Node

,

880 if

(

const auto

*

D

=

Node

.get<Decl>()) {

881

OS <<

D

->getDeclKindName() <<

"Decl "

;

882 if

(

const auto

*ND = dyn_cast<NamedDecl>(

D

)) {

883

ND->printQualifiedName(OS);

887 D

->getSourceRange().print(OS, Ctx.getSourceManager());

888

}

else if

(

const auto

*S =

Node

.get<Stmt>()) {

889

OS << S->getStmtClassName() <<

" : "

;

890

S->getSourceRange().print(OS, Ctx.getSourceManager());

891

}

else if

(

const auto

*

T

=

Node

.get<Type>()) {

893

QualType(

T

, 0).print(OS, Ctx.getPrintingPolicy());

894

}

else if

(

const auto

*QT =

Node

.get<QualType>()) {

895

OS <<

"QualType : "

;

896

QT->print(OS, Ctx.getPrintingPolicy());

898

OS <<

Node

.getNodeKind().asStringRef() <<

" : "

;

899 Node

.getSourceRange().print(OS, Ctx.getSourceManager());

903 static void

dumpNodeFromState(

const

ASTContext &Ctx,

904 const

CurMatchData &State, raw_ostream &OS) {

905 if

(

const

DynTypedNode *MatchNode = State.getNode<DynTypedNode>()) {

906

dumpNode(Ctx, *MatchNode, OS);

907

}

else if

(

const auto

*QT = State.getNode<QualType>()) {

909

}

else if

(

const auto

*TL = State.getNode<TypeLoc>()) {

911

}

else if

(

const auto

*NNS = State.getNode<NestedNameSpecifier>()) {

913

}

else if

(

const auto

*NNSL = State.getNode<NestedNameSpecifierLoc>()) {

915

}

else if

(

const auto

*CtorInit = State.getNode<CXXCtorInitializer>()) {

917

}

else if

(

const auto

*TAL = State.getNode<TemplateArgumentLoc>()) {

919

}

else if

(

const auto

*At = State.getNode<Attr>()) {

925

TraceReporter(

const

MatchASTVisitor &MV) : MV(MV) {}

926 void print

(raw_ostream &OS)

const override

{

927 const

CurMatchData &State = MV.CurMatchState;

928 const

MatchCallback *CB = State.getCallback();

930

OS <<

"ASTMatcher: Not currently matching\n"

;

934

assert(MV.ActiveASTContext &&

935 "ActiveASTContext should be set if there is a matched callback"

);

937

ASTContext &Ctx = MV.getASTContext();

939 if

(

const

BoundNodes *

Nodes

= State.getBoundNodes()) {

940

OS <<

"ASTMatcher: Processing '"

<< CB->getID() <<

"' against:\n\t"

;

941

dumpNodeFromState(Ctx, State, OS);

944

OS <<

"\nNo bound nodes\n"

;

947

OS <<

"\n--- Bound Nodes Begin ---\n"

;

948 for

(

const auto

&Item : Map) {

949

OS <<

" "

<< Item.first <<

" - { "

;

950

dumpNode(Ctx, Item.second, OS);

953

OS <<

"--- Bound Nodes End ---\n"

;

955

OS <<

"ASTMatcher: Matching '"

<< CB->getID() <<

"' against:\n\t"

;

956

dumpNodeFromState(Ctx, State, OS);

962 const

MatchASTVisitor &MV;

966 struct

ASTNodeNotSpelledInSourceScope {

967

ASTNodeNotSpelledInSourceScope(MatchASTVisitor *

V

,

bool

B)

968

: MV(

V

), MB(

V

->TraversingASTNodeNotSpelledInSource) {

969 V

->TraversingASTNodeNotSpelledInSource = B;

971

~ASTNodeNotSpelledInSourceScope() {

972

MV->TraversingASTNodeNotSpelledInSource = MB;

980 struct

ASTNodeNotAsIsSourceScope {

981

ASTNodeNotAsIsSourceScope(MatchASTVisitor *

V

,

bool

B)

982

: MV(

V

), MB(

V

->TraversingASTNodeNotAsIs) {

983 V

->TraversingASTNodeNotAsIs = B;

985

~ASTNodeNotAsIsSourceScope() { MV->TraversingASTNodeNotAsIs = MB; }

992 class

TimeBucketRegion {

994

TimeBucketRegion() =

default

;

995

~TimeBucketRegion() { setBucket(

nullptr

); }

1005 void

setBucket(llvm::TimeRecord *NewBucket) {

1006 if

(Bucket != NewBucket) {

1007 auto

Now = llvm::TimeRecord::getCurrentTime(

true

);

1017

llvm::TimeRecord *Bucket =

nullptr

;

1023 template

<

typename

T,

typename

MC>

1024 void

matchWithoutFilter(

const T

&

Node

,

const

MC &Matchers) {

1025 const bool

EnableCheckProfiling = Options.CheckProfiling.has_value();

1026

TimeBucketRegion Timer;

1027 for

(

const auto

&MP : Matchers) {

1028 if

(EnableCheckProfiling)

1029

Timer.setBucket(&TimeByBucket[MP.second->getID()]);

1030

BoundNodesTreeBuilder Builder;

1031

CurMatchRAII RAII(*

this

, MP.second,

Node

);

1032 if

(MP.first.matches(

Node

,

this

, &Builder)) {

1033

MatchVisitor Visitor(*

this

, ActiveASTContext, MP.second);

1034

Builder.visitMatches(&Visitor);

1039 void

matchWithFilter(

const

DynTypedNode &DynNode) {

1040 auto Kind

= DynNode.getNodeKind();

1041 auto

it = MatcherFiltersMap.find(

Kind

);

1043

it != MatcherFiltersMap.end() ? it->second : getFilterForKind(

Kind

);

1048 const bool

EnableCheckProfiling = Options.CheckProfiling.has_value();

1049

TimeBucketRegion Timer;

1050 auto

&Matchers = this->Matchers->DeclOrStmt;

1051 for

(

unsigned short

I : Filter) {

1052 auto

&MP = Matchers[I];

1053 if

(EnableCheckProfiling)

1054

Timer.setBucket(&TimeByBucket[MP.second->getID()]);

1055

BoundNodesTreeBuilder Builder;

1058

TraversalKindScope RAII(getASTContext(), MP.first.getTraversalKind());

1059 if

(getASTContext().getParentMapContext().traverseIgnored(DynNode) !=

1064

CurMatchRAII RAII(*

this

, MP.second, DynNode);

1065 if

(MP.first.matches(DynNode,

this

, &Builder)) {

1066

MatchVisitor Visitor(*

this

, ActiveASTContext, MP.second);

1067

Builder.visitMatches(&Visitor);

1072 const

std::vector<unsigned short> &getFilterForKind(ASTNodeKind

Kind

) {

1074 auto

&Matchers = this->Matchers->DeclOrStmt;

1075

assert((Matchers.size() <

USHRT_MAX

) &&

"Too many matchers."

);

1076 for

(

unsigned

I = 0,

E

= Matchers.size(); I !=

E

; ++I) {

1077 if

(Matchers[I].first.canMatchNodesOfKind(

Kind

)) {

1086 void

matchDispatch(

const

Decl *

Node

) {

1089 void

matchDispatch(

const

Stmt *

Node

) {

1093 void

matchDispatch(

const

Type *

Node

) {

1094

matchWithoutFilter(QualType(

Node

, 0), Matchers->Type);

1096 void

matchDispatch(

const

TypeLoc *

Node

) {

1097

matchWithoutFilter(*

Node

, Matchers->TypeLoc);

1099 void

matchDispatch(

const

QualType *

Node

) {

1100

matchWithoutFilter(*

Node

, Matchers->Type);

1102 void

matchDispatch(

const

NestedNameSpecifier *

Node

) {

1103

matchWithoutFilter(*

Node

, Matchers->NestedNameSpecifier);

1105 void

matchDispatch(

const

NestedNameSpecifierLoc *

Node

) {

1106

matchWithoutFilter(*

Node

, Matchers->NestedNameSpecifierLoc);

1108 void

matchDispatch(

const

CXXCtorInitializer *

Node

) {

1109

matchWithoutFilter(*

Node

, Matchers->CtorInit);

1111 void

matchDispatch(

const

TemplateArgumentLoc *

Node

) {

1112

matchWithoutFilter(*

Node

, Matchers->TemplateArgumentLoc);

1114 void

matchDispatch(

const

Attr *

Node

) {

1115

matchWithoutFilter(*

Node

, Matchers->Attr);

1117 void

matchDispatch(

const void

*) {

}

1122 bool

matchesParentOf(

const

DynTypedNode &

Node

,

const

DynTypedMatcher &Matcher,

1123

BoundNodesTreeBuilder *Builder) {

1124 for

(

const auto

&

Parent

: ActiveASTContext->getParents(

Node

)) {

1125

BoundNodesTreeBuilder BuilderCopy = *Builder;

1126 if

(Matcher.matches(

Parent

,

this

, &BuilderCopy)) {

1127

*Builder = std::move(BuilderCopy);

1150 bool

matchesAnyAncestorOf(DynTypedNode

Node

, ASTContext &Ctx,

1151 const

DynTypedMatcher &Matcher,

1152

BoundNodesTreeBuilder *Builder) {

1157

std::vector<MatchKey> Keys;

1159 auto

Finish = [&](

bool

Matched) {

1160 for

(

const auto

&Key : Keys) {

1161

MemoizedMatchResult &CachedResult = ResultCache[Key];

1162

CachedResult.ResultOfMatch = Matched;

1163

CachedResult.Nodes = *Builder;

1169

DynTypedNodeList Parents{ArrayRef<DynTypedNode>()};

1172 if

(Builder->isComparable()) {

1173

Keys.emplace_back();

1174

Keys.back().MatcherID = Matcher.getID();

1175

Keys.back().Node =

Node

;

1176

Keys.back().BoundNodes = *Builder;

1177

Keys.back().Traversal = Ctx.getParentMapContext().getTraversalKind();

1178

Keys.back().Type = MatchType::Ancestors;

1181

MemoizationMap::iterator I = ResultCache.find(Keys.back());

1182 if

(I != ResultCache.end()) {

1184

*Builder = I->second.Nodes;

1185 return

Finish(I->second.ResultOfMatch);

1189

Parents = ActiveASTContext->getParents(

Node

);

1192 if

(Parents.size() != 1)

1196 Node

= *Parents.begin();

1197

BoundNodesTreeBuilder BuilderCopy = *Builder;

1198 if

(Matcher.matches(

Node

,

this

, &BuilderCopy)) {

1199

*Builder = std::move(BuilderCopy);

1200 return

Finish(

true

);

1205 if

(Parents.empty()) {

1213 if

(!

Node

.get<TranslationUnitDecl>() &&

1215

llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *

D

) {

1216

return D->getKind() == Decl::TranslationUnit;

1218

llvm::errs() <<

"Tried to match orphan node:\n"

;

1219 Node

.dump(llvm::errs(), *ActiveASTContext);

1220

llvm_unreachable(

"Parent map should be complete!"

);

1224

assert(Parents.size() > 1);

1228

std::deque<DynTypedNode> Queue(Parents.begin(), Parents.end());

1229

llvm::DenseSet<const void *>

Visited

;

1230 while

(!Queue.empty()) {

1231

BoundNodesTreeBuilder BuilderCopy = *Builder;

1232 if

(Matcher.matches(Queue.front(),

this

, &BuilderCopy)) {

1233

*Builder = std::move(BuilderCopy);

1234 return

Finish(

true

);

1236 for

(

const auto

&

Parent

: ActiveASTContext->getParents(Queue.front())) {

1241

Queue.push_back(

Parent

);

1246 return

Finish(

false

);

1251 class

MatchVisitor :

public

BoundNodesTreeBuilder::Visitor {

1252 struct

CurBoundScope {

1253

CurBoundScope(MatchASTVisitor::CurMatchData &State,

const

BoundNodes &BN)

1255

State.SetBoundNodes(BN);

1258

~CurBoundScope() { State.clearBoundNodes(); }

1261

MatchASTVisitor::CurMatchData &State;

1265

MatchVisitor(MatchASTVisitor &MV, ASTContext *Context,

1266

MatchFinder::MatchCallback *Callback)

1267

: State(MV.CurMatchState), Context(Context), Callback(Callback) {}

1269 void

visitMatch(

const

BoundNodes& BoundNodesView)

override

{

1270

TraversalKindScope RAII(*Context, Callback->getCheckTraversalKind());

1271

CurBoundScope RAII2(State, BoundNodesView);

1272

Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));

1276

MatchASTVisitor::CurMatchData &State;

1277

ASTContext* Context;

1278

MatchFinder::MatchCallback* Callback;

1282 bool

typeHasMatchingAlias(

const

Type *TypeNode,

1283 const

Matcher<NamedDecl> &Matcher,

1284

BoundNodesTreeBuilder *Builder) {

1285 const Type

*

const

CanonicalType =

1286

ActiveASTContext->getCanonicalType(TypeNode);

1287 auto

Aliases = TypeAliases.find(CanonicalType);

1288 if

(Aliases == TypeAliases.end())

1290 for

(

const

TypedefNameDecl *Alias : Aliases->second) {

1291

BoundNodesTreeBuilder

Result

(*Builder);

1292 if

(Matcher.matches(*Alias,

this

, &

Result

)) {

1293

*Builder = std::move(

Result

);

1301

objcClassHasMatchingCompatibilityAlias(

const

ObjCInterfaceDecl *InterfaceDecl,

1302 const

Matcher<NamedDecl> &Matcher,

1303

BoundNodesTreeBuilder *Builder) {

1304 auto

Aliases = CompatibleAliases.find(InterfaceDecl);

1305 if

(Aliases == CompatibleAliases.end())

1307 for

(

const

ObjCCompatibleAliasDecl *Alias : Aliases->second) {

1308

BoundNodesTreeBuilder

Result

(*Builder);

1309 if

(Matcher.matches(*Alias,

this

, &

Result

)) {

1310

*Builder = std::move(

Result

);

1320

llvm::StringMap<llvm::TimeRecord> TimeByBucket;

1322 const

MatchFinder::MatchersByType *Matchers;

1330

llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap;

1332 const

MatchFinder::MatchFinderOptions &Options;

1333

ASTContext *ActiveASTContext;

1336

llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases;

1339

llvm::DenseMap<

const

ObjCInterfaceDecl *,

1344 typedef

std::map<MatchKey, MemoizedMatchResult> MemoizationMap;

1345

MemoizationMap ResultCache;

1348static

CXXRecordDecl *

1349

getAsCXXRecordDeclOrPrimaryTemplate(

const

Type *TypeNode) {

1350 if

(

auto

*RD = TypeNode->getAsCXXRecordDecl())

1354 auto

*TemplateType = TypeNode->getAs<TemplateSpecializationType>();

1355 while

(TemplateType && TemplateType->isTypeAlias())

1357

TemplateType->getAliasedType()->getAs<TemplateSpecializationType>();

1362 if

(

auto

*ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>(

1363

TemplateType->getTemplateName().getAsTemplateDecl()))

1364 return

ClassTemplate->getTemplatedDecl();

1372bool

MatchASTVisitor::classIsDerivedFrom(

const

CXXRecordDecl *

Declaration

,

1373 const

Matcher<NamedDecl> &

Base

,

1374

BoundNodesTreeBuilder *Builder,

1380bool

MatchASTVisitor::classIsDerivedFromImpl(

1382

BoundNodesTreeBuilder *Builder,

bool

Directly,

1383

llvm::SmallPtrSetImpl<const CXXRecordDecl *> &

Visited

) {

1389 const Type

*TypeNode = It.getType().getTypePtr();

1391 if

(typeHasMatchingAlias(TypeNode,

Base

, Builder))

1397

CXXRecordDecl *ClassDecl = getAsCXXRecordDeclOrPrimaryTemplate(TypeNode);

1404

BoundNodesTreeBuilder

Result

(*Builder);

1405 if

(

Base

.matches(*ClassDecl,

this

, &

Result

)) {

1406

*Builder = std::move(

Result

);

1410

classIsDerivedFromImpl(ClassDecl,

Base

, Builder, Directly,

Visited

))

1419bool

MatchASTVisitor::objcClassIsDerivedFrom(

1420 const

ObjCInterfaceDecl *

Declaration

,

const

Matcher<NamedDecl> &

Base

,

1421

BoundNodesTreeBuilder *Builder,

bool

Directly) {

1423 for

(

const

ObjCInterfaceDecl *ClassDecl =

Declaration

->getSuperClass();

1424

ClassDecl !=

nullptr

; ClassDecl = ClassDecl->getSuperClass()) {

1426 if

(objcClassHasMatchingCompatibilityAlias(ClassDecl,

Base

, Builder))

1430 const Type

*TypeNode = ClassDecl->getTypeForDecl();

1431 if

(typeHasMatchingAlias(TypeNode,

Base

, Builder))

1434 if

(

Base

.matches(*ClassDecl,

this

, Builder))

1445bool

MatchASTVisitor::TraverseDecl(Decl *DeclNode) {

1450 bool

ScopedTraversal =

1451

TraversingASTNodeNotSpelledInSource || DeclNode->isImplicit();

1452 bool

ScopedChildren = TraversingASTChildrenNotSpelledInSource;

1454 if

(

const auto

*CTSD = dyn_cast<ClassTemplateSpecializationDecl>(DeclNode)) {

1455 auto

SK = CTSD->getSpecializationKind();

1458

ScopedChildren =

true

;

1459

}

else if

(

const auto

*FD = dyn_cast<FunctionDecl>(DeclNode)) {

1460 if

(FD->isDefaulted())

1461

ScopedChildren =

true

;

1462 if

(FD->isTemplateInstantiation())

1463

ScopedTraversal =

true

;

1464

}

else if

(isa<BindingDecl>(DeclNode)) {

1465

ScopedChildren =

true

;

1468

ASTNodeNotSpelledInSourceScope RAII1(

this

, ScopedTraversal);

1469

ASTChildrenNotSpelledInSourceScope RAII2(

this

, ScopedChildren);

1475bool

MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {

1479 bool

ScopedTraversal = TraversingASTNodeNotSpelledInSource ||

1480

TraversingASTChildrenNotSpelledInSource;

1482

ASTNodeNotSpelledInSourceScope RAII(

this

, ScopedTraversal);

1487bool

MatchASTVisitor::TraverseType(QualType TypeNode) {

1492bool

MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {

1498 match

(TypeLocNode);

1499 match

(TypeLocNode.getType());

1503bool

MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {

1508bool

MatchASTVisitor::TraverseNestedNameSpecifierLoc(

1509

NestedNameSpecifierLoc NNS) {

1517 if

(NNS.hasQualifier())

1518 match

(*NNS.getNestedNameSpecifier());

1523bool

MatchASTVisitor::TraverseConstructorInitializer(

1524

CXXCtorInitializer *CtorInit) {

1528 bool

ScopedTraversal = TraversingASTNodeNotSpelledInSource ||

1529

TraversingASTChildrenNotSpelledInSource;

1531 if

(!CtorInit->isWritten())

1532

ScopedTraversal =

true

;

1534

ASTNodeNotSpelledInSourceScope RAII1(

this

, ScopedTraversal);

1542bool

MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc

Loc

) {

1547bool

MatchASTVisitor::TraverseAttr(Attr *AttrNode) {

1552class

MatchASTConsumer :

public

ASTConsumer {

1554

MatchASTConsumer(MatchFinder *Finder,

1555

MatchFinder::ParsingDoneTestCallback *ParsingDone)

1556

: Finder(Finder), ParsingDone(ParsingDone) {}

1559 void

HandleTranslationUnit(ASTContext &Context)

override

{

1560 if

(ParsingDone !=

nullptr

) {

1563

Finder->matchAST(Context);

1566

MatchFinder *Finder;

1567

MatchFinder::ParsingDoneTestCallback *ParsingDone;

1582

: Options(

std

::move(Options)), ParsingDone(nullptr) {}

1588

std::optional<TraversalKind> TK;

1592

Matchers.DeclOrStmt.emplace_back(

traverse

(*TK, NodeMatch), Action);

1594

Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);

1595

Matchers.AllCallbacks.insert(Action);

1600

Matchers.Type.emplace_back(NodeMatch, Action);

1601

Matchers.AllCallbacks.insert(Action);

1606

std::optional<TraversalKind> TK;

1610

Matchers.DeclOrStmt.emplace_back(

traverse

(*TK, NodeMatch), Action);

1612

Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);

1613

Matchers.AllCallbacks.insert(Action);

1618

Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);

1619

Matchers.AllCallbacks.insert(Action);

1624

Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);

1625

Matchers.AllCallbacks.insert(Action);

1630

Matchers.TypeLoc.emplace_back(NodeMatch, Action);

1631

Matchers.AllCallbacks.insert(Action);

1636

Matchers.CtorInit.emplace_back(NodeMatch, Action);

1637

Matchers.AllCallbacks.insert(Action);

1642

Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action);

1643

Matchers.AllCallbacks.insert(Action);

1648

Matchers.Attr.emplace_back(AttrMatch, Action);

1649

Matchers.AllCallbacks.insert(Action);

1654 if

(NodeMatch.canConvertTo<

Decl

>()) {

1657

}

else if

(NodeMatch.canConvertTo<

QualType

>()) {

1660

}

else if

(NodeMatch.canConvertTo<

Stmt

>()) {

1669

}

else if

(NodeMatch.canConvertTo<

TypeLoc

>()) {

1678

}

else if

(NodeMatch.canConvertTo<

Attr

>()) {

1686 return

std::make_unique<internal::MatchASTConsumer>(

this

, ParsingDone);

1690

internal::MatchASTVisitor Visitor(&Matchers, Options);

1691

Visitor.set_active_ast_context(&Context);

1692

Visitor.match(

Node

);

1696

internal::MatchASTVisitor Visitor(&Matchers, Options);

1697

internal::MatchASTVisitor::TraceReporter StackTrace(Visitor);

1698

Visitor.set_active_ast_context(&Context);

1699

Visitor.onStartOfTranslationUnit();

1700

Visitor.TraverseAST(Context);

1701

Visitor.onEndOfTranslationUnit();

1706

ParsingDone = NewParsingDone;

1711

std::optional<TraversalKind>

1713 return

std::nullopt;

Defines the clang::ASTContext interface.

BoundNodesTreeBuilder BoundNodes

BoundNodesTreeBuilder Nodes

DynTypedMatcher::MatcherIDType MatcherID

llvm::PointerUnion< CMD_TYPES_1 > Node1

llvm::PointerUnion< CMD_TYPES_0 > Node0

enum clang::sema::@1704::IndirectLocalPathEntry::EntryKind Kind

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

llvm::DenseSet< const void * > Visited

static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

Attr - This represents one attribute.

Represents a C++ base or member initializer.

Decl - This represents one declaration (or definition), e.g.

A dynamically typed AST node container.

static DynTypedNode create(const T &Node)

Creates a DynTypedNode from Node.

Expr * getNoexceptExpr() const

Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...

ArrayRef< QualType > exceptions() const

A C++ nested-name-specifier augmented with source location information.

Represents a C++ nested name specifier, such as "\::std::vector<int>::".

A (possibly-)qualified type.

bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)

Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...

bool TraverseType(QualType T)

Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...

bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)

Recursively visit a template argument location and dispatch to the appropriate method for the argumen...

bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)

Recursively visit a C++ nested-name-specifier with location information.

bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS)

Recursively visit a C++ nested-name-specifier.

bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue)

bool TraverseDecl(Decl *D)

Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...

bool TraverseTypeLoc(TypeLoc TL)

Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...

bool TraverseAttr(Attr *At)

Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...

bool TraverseConstructorInitializer(CXXCtorInitializer *Init)

Recursively visit a constructor initializer.

This class handles loading and caching of source files into memory.

Stmt - This represents one statement.

Location wrapper for a TemplateArgument.

Base wrapper for a particular "section" of type source info.

const char * getTypeClassName() const

Maps string IDs to AST nodes matched by parts of a matcher.

internal::BoundNodesMap::IDToNodeMap IDToNodeMap

Type of mapping from binding identifiers to bound nodes.

Called when the Match registered for it was successfully found in the AST.

virtual std::optional< TraversalKind > getCheckTraversalKind() const

TraversalKind to use while matching and processing the result nodes.

virtual StringRef getID() const

An id used to group the matchers.

Called when parsing is finished. Intended for testing only.

virtual ~ParsingDoneTestCallback()

MatchFinder(MatchFinderOptions Options=MatchFinderOptions())

bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)

Adds a matcher to execute when running over the AST.

void addMatcher(const DeclarationMatcher &NodeMatch, MatchCallback *Action)

Adds a matcher to execute when running over the AST.

void match(const T &Node, ASTContext &Context)

Calls the registered callbacks on all matches on the given Node.

void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone)

Registers a callback to notify the end of parsing.

std::unique_ptr< clang::ASTConsumer > newASTConsumer()

Creates a clang ASTConsumer that finds all matches.

void matchAST(ASTContext &Context)

Finds all matches in the given AST.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

internal::Matcher< QualType > TypeMatcher

internal::Matcher< Decl > DeclarationMatcher

Types of matchers for the top-level classes in the AST class hierarchy.

internal::Matcher< NestedNameSpecifier > NestedNameSpecifierMatcher

SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)

Returns the results of matching Matcher on Node.

internal::Matcher< CXXCtorInitializer > CXXCtorInitializerMatcher

internal::Matcher< Stmt > StatementMatcher

internal::Matcher< TypeLoc > TypeLocMatcher

internal::Matcher< TemplateArgumentLoc > TemplateArgumentLocMatcher

internal::Matcher< T > traverse(TraversalKind TK, const internal::Matcher< T > &InnerMatcher)

Causes all nested matchers to be matched with the specified traversal kind.

internal::Matcher< Attr > AttrMatcher

internal::Matcher< NestedNameSpecifierLoc > NestedNameSpecifierLocMatcher

bool LE(InterpState &S, CodePtr OpPC)

The JSON file list parser is used to communicate input to InstallAPI.

@ Bind

'bind' clause, allowed on routine constructs.

bool operator<(DeclarationName LHS, DeclarationName RHS)

Ordering on two declaration names.

TraversalKind

Defines how we descend a level in the AST when we pass through expressions.

@ TK_AsIs

Will traverse all child nodes.

@ TK_IgnoreUnlessSpelledInSource

Ignore AST nodes not written in the source.

@ Result

The result type of a method or function.

const FunctionProtoType * T

@ TSK_ExplicitInstantiationDefinition

This template specialization was instantiated from a template due to an explicit instantiation defini...

@ TSK_ExplicitInstantiationDeclaration

This template specialization was instantiated from a template due to an explicit instantiation declar...

@ Other

Other implicit parameter.

MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context)


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4