A RetroSearch Logo

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

Search Query:

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

clang: lib/Tooling/ASTDiff/ASTDiff.cpp Source File

18#include "llvm/ADT/PriorityQueue.h" 23#include <unordered_set> 26using namespace clang

;

36

Mapping(Mapping &&

Other

) =

default

;

37

Mapping &operator=(Mapping &&

Other

) =

default

;

39

Mapping(

size_t

Size) {

40

SrcToDst = std::make_unique<NodeId[]>(Size);

41

DstToSrc = std::make_unique<NodeId[]>(Size);

44 void link

(NodeId Src, NodeId Dst) {

45

SrcToDst[Src] = Dst, DstToSrc[Dst] = Src;

48

NodeId getDst(NodeId Src)

const

{

return

SrcToDst[Src]; }

49

NodeId getSrc(NodeId Dst)

const

{

return

DstToSrc[Dst]; }

50 bool

hasSrc(NodeId Src)

const

{

return

getDst(Src).isValid(); }

51 bool

hasDst(NodeId Dst)

const

{

return

getSrc(Dst).isValid(); }

54

std::unique_ptr<NodeId[]> SrcToDst, DstToSrc;

76

assert(&*

Tree

== &

T2

&&

"Invalid tree."

);

88 bool

haveSameParents(

const

Mapping &M,

NodeId

Id1,

NodeId

Id2)

const

;

92 void

addOptimalMapping(Mapping &M,

NodeId

Id1,

NodeId

Id2)

const

;

96 double

getJaccardSimilarity(

const

Mapping &M,

NodeId

Id1,

NodeId

Id2)

const

;

99 NodeId

findCandidate(

const

Mapping &M,

NodeId

Id1)

const

;

102

Mapping matchTopDown()

const

;

105 void

matchBottomUp(Mapping &M)

const

;

162 void

setLeftMostDescendants();

190 int Id

= 0, Depth = 0;

194

PreorderVisitor(SyntaxTree::Impl &Tree) :

Tree

(

Tree

) {}

196 template

<

class

T> std::tuple<NodeId, NodeId> PreTraverse(

T

*ASTNode) {

198 Tree

.Nodes.emplace_back();

199 Node

&N =

Tree

.getMutableNode(MyId);

203

assert(!N.ASTNode.getNodeKind().isNone() &&

204 "Expected nodes to have a valid kind."

);

207 P

.Children.push_back(MyId);

212 return

std::make_tuple(MyId,

Tree

.getNode(MyId).Parent);

214 void

PostTraverse(std::tuple<NodeId, NodeId> State) {

215

NodeId MyId, PreviousParent;

216

std::tie(MyId, PreviousParent) = State;

217

assert(MyId.isValid() &&

"Expecting to only traverse valid nodes."

);

220 Node

&N =

Tree

.getMutableNode(MyId);

221

N.RightMostDescendant =

Id

- 1;

222

assert(N.RightMostDescendant >= 0 &&

223

N.RightMostDescendant <

Tree

.getSize() &&

224 "Rightmost descendant must be a valid tree node."

);

226 Tree

.Leaves.push_back(MyId);

228 for

(NodeId Child : N.Children)

229

N.Height = std::max(N.Height, 1 +

Tree

.getNode(Child).Height);

231 bool

TraverseDecl(

Decl

*

D

) {

234 auto

SavedState = PreTraverse(

D

);

236

PostTraverse(SavedState);

239 bool

TraverseStmt(

Stmt

*S) {

240 if

(

auto

*

E

= dyn_cast_or_null<Expr>(S))

244 auto

SavedState = PreTraverse(S);

246

PostTraverse(SavedState);

249 bool

TraverseType(

QualType T

) {

return true

; }

253 auto

SavedState = PreTraverse(

Init

);

255

PostTraverse(SavedState);

262

:

Parent

(

Parent

), AST(AST), TypePP(AST.getLangOpts()) {

268

PreorderVisitor PreorderWalker(*

this

);

269

PreorderWalker.TraverseDecl(N);

275

PreorderVisitor PreorderWalker(*

this

);

276

PreorderWalker.TraverseStmt(N);

282

std::vector<NodeId> Postorder;

287

Postorder.push_back(

Id

);

295

std::vector<NodeId> Ids;

298 while

(Expanded < Ids.size())

299 for

(

NodeId

Child :

Tree

.getNode(Ids[Expanded++]).Children)

300

Ids.push_back(Child);

304void

SyntaxTree::Impl::initTree() {

305

setLeftMostDescendants();

307

PostorderIds.resize(

getSize

());

308

std::function<void(NodeId)> PostorderTraverse = [&](NodeId

Id

) {

310

PostorderTraverse(Child);

311

PostorderIds[

Id

] = PostorderId;

318void

SyntaxTree::Impl::setLeftMostDescendants() {

319 for

(NodeId Leaf : Leaves) {

320

getMutableNode(Leaf).LeftMostDescendant = Leaf;

321

NodeId

Parent

, Cur = Leaf;

325

getMutableNode(Cur).LeftMostDescendant = Leaf;

344 for

(

size_t

I = 0,

E

= Siblings.size(); I <

E

; ++I) {

347 if

(Siblings[I] ==

Id

) {

352

llvm_unreachable(

"Node not found in parent's children."

);

361

std::string ContextPrefix;

364 if

(

auto

*Namespace = dyn_cast<NamespaceDecl>(Context))

365

ContextPrefix = Namespace->getQualifiedNameAsString();

366 else if

(

auto

*

Record

= dyn_cast<RecordDecl>(Context))

367

ContextPrefix =

Record

->getQualifiedNameAsString();

368 else if

(AST.getLangOpts().CPlusPlus11)

369 if

(

auto

*Tag = dyn_cast<TagDecl>(Context))

370

ContextPrefix = Tag->getQualifiedNameAsString();

374 if

(!ContextPrefix.empty() && StringRef(Val).starts_with(ContextPrefix))

375

Val = Val.substr(ContextPrefix.size() + 1);

389 const auto

&

P

= Parents[0];

390 if

(

const auto

*

D

=

P

.get<

Decl

>())

392

S =

P

.get<

Stmt

>();

399 if

(

Init

->isAnyMemberInitializer())

400 return

std::string(

Init

->getAnyMember()->getName());

401 if

(

Init

->isBaseInitializer())

403 if

(

Init

->isDelegatingInitializer())

404 return Init

->getTypeSourceInfo()->getType().getAsString(TypePP);

405

llvm_unreachable(

"Unknown initializer type"

);

414 if

(

auto

*S = DTN.

get

<

Stmt

>())

415 return

getStmtValue(S);

416 if

(

auto

*

D

= DTN.

get

<

Decl

>())

417 return

getDeclValue(

D

);

420

llvm_unreachable(

"Fatal: unhandled AST node.\n"

);

425 if

(

auto

*

V

= dyn_cast<ValueDecl>(

D

))

426 return

getRelativeName(

V

) +

"("

+

V

->getType().getAsString(TypePP) +

")"

;

427 if

(

auto

*N = dyn_cast<NamedDecl>(

D

))

428 Value

+= getRelativeName(N) +

";"

;

429 if

(

auto

*

T

= dyn_cast<TypedefNameDecl>(

D

))

430 return Value

+

T

->getUnderlyingType().getAsString(TypePP) +

";"

;

431 if

(

auto

*

T

= dyn_cast<TypeDecl>(

D

))

432 if

(

T

->getTypeForDecl())

436 if

(

auto

*

U

= dyn_cast<UsingDirectiveDecl>(

D

))

437 return

std::string(

U

->getNominatedNamespace()->getName());

438 if

(

auto

*A = dyn_cast<AccessSpecDecl>(

D

)) {

447 if

(

auto

*

U

= dyn_cast<UnaryOperator>(S))

449 if

(

auto

*B = dyn_cast<BinaryOperator>(S))

450 return

std::string(B->getOpcodeStr());

451 if

(

auto

*M = dyn_cast<MemberExpr>(S))

452 return

getRelativeName(M->getMemberDecl());

453 if

(

auto

*I = dyn_cast<IntegerLiteral>(S)) {

455

I->getValue().toString(Str,

10,

false

);

456 return

std::string(Str);

458 if

(

auto

*F = dyn_cast<FloatingLiteral>(S)) {

460

F->getValue().toString(Str);

461 return

std::string(Str);

463 if

(

auto

*

D

= dyn_cast<DeclRefExpr>(S))

465 if

(

auto

*String = dyn_cast<StringLiteral>(S))

466 return

std::string(String->getString());

467 if

(

auto

*B = dyn_cast<CXXBoolLiteralExpr>(S))

468 return

B->getValue() ?

"true"

:

"false"

;

479 operator int

()

const

{

return Id

; }

490

std::vector<NodeId> RootIds;

492

std::vector<SNodeId> LeftMostDescendants;

499 int

NumLeaves = setLeftMostDescendants();

500

computeKeyRoots(NumLeaves);

502 int getSize

()

const

{

return

RootIds.size(); }

504

assert(

Id

> 0 &&

Id

<= getSize() &&

"Invalid subtree node index."

);

505 return

RootIds[

Id

- 1];

508 return Tree

.getNode(getIdInRoot(

Id

));

511

assert(

Id

> 0 &&

Id

<= getSize() &&

"Invalid subtree node index."

);

512 return

LeftMostDescendants[

Id

- 1];

516 return Tree

.PostorderIds[getIdInRoot(

SNodeId

(1))];

519 return Tree

.getNodeValue(getIdInRoot(

Id

));

524 int

setLeftMostDescendants() {

526

LeftMostDescendants.resize(getSize());

527 for

(

int

I = 0; I < getSize(); ++I) {

530

NumLeaves += N.

isLeaf

();

531

assert(I ==

Tree

.PostorderIds[getIdInRoot(SI)] - getPostorderOffset() &&

532 "Postorder traversal in subtree should correspond to traversal in " 533 "the root tree by a constant offset."

);

535

getPostorderOffset());

539 void

computeKeyRoots(

int

Leaves) {

540

KeyRoots.resize(Leaves);

541

std::unordered_set<int>

Visited

;

543 for

(SNodeId I(getSize()); I > 0; --I) {

544

SNodeId LeftDesc = getLeftMostDescendant(I);

547

assert(K >= 0 &&

"K should be non-negative"

);

562

std::unique_ptr<std::unique_ptr<double[]>[]> TreeDist, ForestDist;

567

: DiffImpl(DiffImpl), S1(T1, Id1), S2(T2, Id2) {

568

TreeDist = std::make_unique<std::unique_ptr<double[]>[]>(

570

ForestDist = std::make_unique<std::unique_ptr<double[]>[]>(

572 for

(

int

I = 0,

E

= S1.

getSize

() + 1; I <

E

; ++I) {

573

TreeDist[I] = std::make_unique<double[]>(

size_t

(S2.

getSize

()) + 1);

574

ForestDist[I] = std::make_unique<double[]>(

size_t

(S2.

getSize

()) + 1);

579

std::vector<std::pair<NodeId, NodeId>> Matches;

580

std::vector<std::pair<SNodeId, SNodeId>> TreePairs;

584 bool

RootNodePair =

true

;

588 while

(!TreePairs.empty()) {

589 SNodeId

LastRow, LastCol, FirstRow, FirstCol, Row, Col;

590

std::tie(LastRow, LastCol) = TreePairs.back();

591

TreePairs.pop_back();

594

computeForestDist(LastRow, LastCol);

597

RootNodePair =

false

;

605 while

(Row > FirstRow || Col > FirstCol) {

606 if

(Row > FirstRow &&

607

ForestDist[Row - 1][Col] + 1 == ForestDist[Row][Col]) {

609

}

else if

(Col > FirstCol &&

610

ForestDist[Row][Col - 1] + 1 == ForestDist[Row][Col]) {

619

assert(DiffImpl.isMatchingPossible(Id1, Id2) &&

620 "These nodes must not be matched."

);

621

Matches.emplace_back(Id1, Id2);

625

TreePairs.emplace_back(Row, Col);

641 static constexpr double

DeletionCost = 1;

642 static constexpr double

InsertionCost = 1;

646 return

std::numeric_limits<double>::max();

650 void

computeTreeDist() {

653

computeForestDist(Id1, Id2);

656 void

computeForestDist(SNodeId Id1, SNodeId Id2) {

657

assert(Id1 > 0 && Id2 > 0 &&

"Expecting offsets greater than 0."

);

661

ForestDist[LMD1][LMD2] = 0;

662 for

(SNodeId D1 = LMD1 + 1; D1 <= Id1; ++D1) {

663

ForestDist[D1][LMD2] = ForestDist[D1 - 1][LMD2] + DeletionCost;

664 for

(SNodeId D2 = LMD2 + 1; D2 <= Id2; ++D2) {

665

ForestDist[LMD1][D2] = ForestDist[LMD1][D2 - 1] + InsertionCost;

668 if

(DLMD1 == LMD1 && DLMD2 == LMD2) {

669 double

UpdateCost = getUpdateCost(D1, D2);

671

std::min({ForestDist[D1 - 1][D2] + DeletionCost,

672

ForestDist[D1][D2 - 1] + InsertionCost,

673

ForestDist[D1 - 1][D2 - 1] + UpdateCost});

674

TreeDist[D1][D2] = ForestDist[D1][D2];

677

std::min({ForestDist[D1 - 1][D2] + DeletionCost,

678

ForestDist[D1][D2 - 1] + InsertionCost,

679

ForestDist[DLMD1][DLMD2] + TreeDist[D1][D2]});

691 if

(

auto

*ND = ASTNode.get<

NamedDecl

>()) {

692 if

(ND->getDeclName().isIdentifier())

693 return

ND->getQualifiedNameAsString();

699 if

(

auto

*ND = ASTNode.get<

NamedDecl

>()) {

700 if

(ND->getDeclName().isIdentifier())

701 return

ND->getName();

711 bool

operator()(NodeId Id1, NodeId Id2)

const

{

712 return Tree

.getNode(Id1).Height <

Tree

.getNode(Id2).Height;

720 const

SyntaxTree::Impl &

Tree

;

722

std::vector<NodeId> Container;

723

PriorityQueue<NodeId, std::vector<NodeId>, HeightLess> List;

726

PriorityList(

const

SyntaxTree::Impl &

Tree

)

729 void

push(NodeId

id

) { List.push(

id

); }

731

std::vector<NodeId> pop() {

733

std::vector<NodeId> Result;

736 while

(peekMax() ==

Max

) {

737

Result.push_back(List.top());

744 int

peekMax()

const

{

747 return Tree

.getNode(List.top()).Height;

749 void

open(NodeId

Id

) {

750 for

(NodeId Child :

Tree

.getNode(

Id

).Children)

756bool

ASTDiff::Impl::identical(NodeId Id1, NodeId Id2)

const

{

757 const Node

&N1 = T1.getNode(Id1);

758 const Node

&N2 = T2.getNode(Id2);

759 if

(N1.Children.size() != N2.Children.size() ||

760

!isMatchingPossible(Id1, Id2) ||

761

T1.getNodeValue(Id1) != T2.getNodeValue(Id2))

763 for

(

size_t Id

= 0,

E

= N1.Children.size();

Id

<

E

; ++

Id

)

764 if

(!identical(N1.Children[

Id

], N2.Children[

Id

]))

769bool

ASTDiff::Impl::isMatchingPossible(NodeId Id1, NodeId Id2)

const

{

770 return

Options.isMatchingAllowed(T1.getNode(Id1), T2.getNode(Id2));

773bool

ASTDiff::Impl::haveSameParents(

const

Mapping &M, NodeId Id1,

775

NodeId P1 = T1.getNode(Id1).Parent;

776

NodeId P2 = T2.getNode(Id2).Parent;

777 return

(P1.isInvalid() && P2.isInvalid()) ||

778

(P1.isValid() && P2.isValid() && M.getDst(P1) == P2);

781void

ASTDiff::Impl::addOptimalMapping(Mapping &M, NodeId Id1,

783 if

(std::max(T1.getNumberOfDescendants(Id1), T2.getNumberOfDescendants(Id2)) >

786

ZhangShashaMatcher Matcher(*

this

, T1, T2, Id1, Id2);

787

std::vector<std::pair<NodeId, NodeId>> R = Matcher.getMatchingNodes();

788 for

(

const auto

&Tuple : R) {

789

NodeId Src = Tuple.first;

790

NodeId Dst = Tuple.second;

791 if

(!M.hasSrc(Src) && !M.hasDst(Dst))

796double

ASTDiff::Impl::getJaccardSimilarity(

const

Mapping &M, NodeId Id1,

798 int

CommonDescendants = 0;

799 const Node

&N1 = T1.getNode(Id1);

801 for

(NodeId Src = Id1 + 1; Src <= N1.RightMostDescendant; ++Src) {

802

NodeId Dst = M.getDst(Src);

803

CommonDescendants +=

int

(Dst.isValid() && T2.isInSubtree(Dst, Id2));

806 double

Denominator = T1.getNumberOfDescendants(Id1) - 1 +

807

T2.getNumberOfDescendants(Id2) - 1 - CommonDescendants;

809

assert(Denominator >= 0 &&

"Expected non-negative denominator."

);

810 if

(Denominator == 0)

812 return

CommonDescendants / Denominator;

815

NodeId ASTDiff::Impl::findCandidate(

const

Mapping &M, NodeId Id1)

const

{

817 double

HighestSimilarity = 0.0;

818 for

(NodeId Id2 : T2) {

819 if

(!isMatchingPossible(Id1, Id2))

823 double

Similarity = getJaccardSimilarity(M, Id1, Id2);

824 if

(Similarity >= Options.MinSimilarity && Similarity > HighestSimilarity) {

825

HighestSimilarity = Similarity;

832void

ASTDiff::Impl::matchBottomUp(Mapping &M)

const

{

834 for

(NodeId Id1 : Postorder) {

835 if

(Id1 == T1.getRootId() && !M.hasSrc(T1.getRootId()) &&

836

!M.hasDst(T2.getRootId())) {

837 if

(isMatchingPossible(T1.getRootId(), T2.getRootId())) {

838

M.link(T1.getRootId(), T2.getRootId());

839

addOptimalMapping(M, T1.getRootId(), T2.getRootId());

843 bool

Matched = M.hasSrc(Id1);

844 const Node

&N1 = T1.getNode(Id1);

845 bool

MatchedChildren = llvm::any_of(

846

N1.Children, [&](NodeId Child) { return M.hasSrc(Child); });

847 if

(Matched || !MatchedChildren)

849

NodeId Id2 = findCandidate(M, Id1);

852

addOptimalMapping(M, Id1, Id2);

857

Mapping ASTDiff::Impl::matchTopDown()

const

{

861

Mapping M(T1.getSize() + T2.getSize());

863

L1.push(T1.getRootId());

864

L2.push(T2.getRootId());

867 while

(std::min(Max1 = L1.peekMax(), Max2 = L2.peekMax()) >

870 for

(NodeId

Id

: L1.pop())

875 for

(NodeId

Id

: L2.pop())

879

std::vector<NodeId> H1, H2;

882 for

(NodeId Id1 : H1) {

883 for

(NodeId Id2 : H2) {

884 if

(identical(Id1, Id2) && !M.hasSrc(Id1) && !M.hasDst(Id2)) {

885 for

(

int

I = 0,

E

= T1.getNumberOfDescendants(Id1); I <

E

; ++I)

886

M.link(Id1 + I, Id2 + I);

890 for

(NodeId Id1 : H1) {

894 for

(NodeId Id2 : H2) {

904

: T1(T1), T2(T2), Options(Options) {

910

TheMapping = matchTopDown();

911 if

(Options.StopAfterTopDown)

913

matchBottomUp(TheMapping);

918 if

(!M.hasSrc(Id1)) {

919

T1.getMutableNode(Id1).Change =

Delete

;

920

T1.getMutableNode(Id1).Shift -= 1;

924 if

(!M.hasDst(Id2)) {

925

T2.getMutableNode(Id2).Change =

Insert

;

926

T2.getMutableNode(Id2).Shift -= 1;

929 for

(

NodeId

Id1 : T1.NodesBfs) {

930 NodeId

Id2 = M.getDst(Id1);

933 if

(!haveSameParents(M, Id1, Id2) ||

934

T1.findPositionInParent(Id1,

true

) !=

935

T2.findPositionInParent(Id2,

true

)) {

936

T1.getMutableNode(Id1).Shift -= 1;

937

T2.getMutableNode(Id2).Shift -= 1;

940 for

(

NodeId

Id2 : T2.NodesBfs) {

941 NodeId

Id1 = M.getSrc(Id2);

944 Node

&N1 = T1.getMutableNode(Id1);

945 Node

&N2 = T2.getMutableNode(Id2);

948 if

(!haveSameParents(M, Id1, Id2) ||

949

T1.findPositionInParent(Id1,

true

) !=

950

T2.findPositionInParent(Id2,

true

)) {

953 if

(T1.getNodeValue(Id1) != T2.getNodeValue(Id2)) {

961

: DiffImpl(

std

::make_unique<

Impl

>(*T1.TreeImpl, *T2.TreeImpl, Options)) {}

971

this, AST.getTranslationUnitDecl(), AST)) {}

992

std::pair<unsigned, unsigned>

1000 if

(ThisExpr->isImplicit())

1005 return

{

Begin

, End};

llvm::DenseSet< const void * > Visited

llvm::MachO::Record Record

static Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef ID)

Defines the SourceManager interface.

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

DynTypedNodeList getParents(const NodeT &Node)

Forwards to get node parents from the ParentMapContext.

Represents a C++ base or member initializer.

bool isWritten() const

Determine whether this initializer is explicitly written in the source code.

Represents the this expression in C++.

Represents a character-granular source range.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

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

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

DeclContext * getDeclContext()

const T * get() const

Retrieve the stored node as type T.

static DynTypedNode create(const T &Node)

Creates a DynTypedNode from Node.

Expr * IgnoreImplicit() LLVM_READONLY

Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.

static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)

Returns a string for the source that the range encompasses.

static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)

Computes the source location just past the end of the token at this source location.

This represents a decl that may have a name.

std::string getQualifiedNameAsString() const

A (possibly-)qualified type.

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...

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

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

bool TraverseDecl(Decl *D)

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

bool TraverseConstructorInitializer(CXXCtorInitializer *Init)

Recursively visit a constructor initializer.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

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

unsigned getFileOffset(SourceLocation SpellingLoc) const

Returns the offset from the start of the file that the specified SourceLocation represents.

bool isInMainFile(SourceLocation Loc) const

Returns whether the PresumedLoc for a given SourceLocation is in the main file.

SourceLocation getSpellingLoc(SourceLocation Loc) const

Given a SourceLocation object, return the spelling location referenced by the ID.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

QualType getCanonicalTypeInternal() const

static StringRef getOpcodeStr(Opcode Op)

getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...

void computeChangeKinds(Mapping &M)

NodeId getMapped(const std::unique_ptr< SyntaxTree::Impl > &Tree, NodeId Id) const

Impl(SyntaxTree::Impl &T1, SyntaxTree::Impl &T2, const ComparisonOptions &Options)

void computeMapping()

Matches nodes one-by-one based on their similarity.

ASTDiff(SyntaxTree &Src, SyntaxTree &Dst, const ComparisonOptions &Options)

NodeId getMapped(const SyntaxTree &SourceTree, NodeId Id) const

const Node & getNode(SNodeId Id) const

SNodeId getLeftMostDescendant(SNodeId Id) const

Subtree(const SyntaxTree::Impl &Tree, NodeId SubtreeRoot)

std::vector< SNodeId > KeyRoots

NodeId getPostorderOffset() const

Returns the postorder index of the leftmost descendant in the subtree.

NodeId getIdInRoot(SNodeId Id) const

std::string getNodeValue(SNodeId Id) const

Represents the AST of a TranslationUnit.

std::string getRelativeName(const NamedDecl *ND, const DeclContext *Context) const

int getNumberOfDescendants(NodeId Id) const

bool isValidNodeId(NodeId Id) const

std::vector< NodeId > Leaves

bool isInSubtree(NodeId Id, NodeId SubtreeRoot) const

PreorderIterator begin() const

std::vector< Node > Nodes

Nodes in preorder.

PreorderIterator end() const

int findPositionInParent(NodeId Id, bool Shifted=false) const

const Node & getNode(NodeId Id) const

std::string getStmtValue(const Stmt *S) const

std::vector< int > PostorderIds

std::string getNodeValue(NodeId Id) const

Impl(SyntaxTree *Parent, std::enable_if_t< std::is_base_of_v< Decl, T >, T > *Node, ASTContext &AST)

Impl(SyntaxTree *Parent, std::enable_if_t< std::is_base_of_v< Stmt, T >, T > *Node, ASTContext &AST)

std::string getDeclValue(const Decl *D) const

std::vector< NodeId > NodesBfs

Impl(SyntaxTree *Parent, ASTContext &AST)

Node & getMutableNode(NodeId Id)

SyntaxTree objects represent subtrees of the AST.

const Node & getNode(NodeId Id) const

int findPositionInParent(NodeId Id) const

const ASTContext & getASTContext() const

PreorderIterator begin() const

std::pair< unsigned, unsigned > getSourceRangeOffsets(const Node &N) const

SyntaxTree(ASTContext &AST)

Constructs a tree from a translation unit.

std::unique_ptr< Impl > TreeImpl

PreorderIterator end() const

std::string getNodeValue(NodeId Id) const

Serialize the node attributes to a string representation.

Implementation of Zhang and Shasha's Algorithm for tree edit distance.

ZhangShashaMatcher(const ASTDiff::Impl &DiffImpl, const SyntaxTree::Impl &T1, const SyntaxTree::Impl &T2, NodeId Id1, NodeId Id2)

std::vector< std::pair< NodeId, NodeId > > getMatchingNodes()

static bool isSpecializedNodeExcluded(const Decl *D)

static const DeclContext * getEnclosingDeclContext(ASTContext &AST, const Stmt *S)

DynTypedNode DynTypedNode

static std::vector< NodeId > getSubtreePostorder(const SyntaxTree::Impl &Tree, NodeId Root)

static std::vector< NodeId > getSubtreeBfs(const SyntaxTree::Impl &Tree, NodeId Root)

static bool isNodeExcluded(const SourceManager &SrcMgr, T *N)

static std::string getInitializerValue(const CXXCtorInitializer *Init, const PrintingPolicy &TypePP)

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

const FunctionProtoType * T

@ Other

Other implicit parameter.

bool link(llvm::ArrayRef< const char * > args, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput)

Diagnostic wrappers for TextAPI types for error reporting.

Describes how types, statements, expressions, and declarations should be printed.

unsigned AnonymousTagLocations

When printing an anonymous tag name, also print the location of that entity (e.g.,...

Within a tree, this identifies a node by its preorder offset.

Represents a Clang AST node, alongside some additional information.

NodeId RightMostDescendant

std::optional< std::string > getQualifiedIdentifier() const

std::optional< StringRef > getIdentifier() const

ASTNodeKind getType() const

NodeId LeftMostDescendant

StringRef getTypeLabel() const

SmallVector< NodeId, 4 > Children

Identifies a node in a subtree by its postorder offset, starting at 1.

SNodeId operator+(int Other) const


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