blob: 2e5e7c389a1ab76606e20e3de5742d78b1cad3cf [file] [log] [blame]
Chris Lattnerc3a65402009-07-12 22:33:12 +00001//===--- DeclReferenceMap.cpp - Map Decls to their references -------------===//
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +000010// DeclReferenceMap creates a mapping from Decls to the ASTLocations that
11// reference them.
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000012//
13//===----------------------------------------------------------------------===//
14
Argyrios Kyrtzidisccbcb702009-07-06 21:34:47 +000015#include "clang/Index/DeclReferenceMap.h"
16#include "clang/Index/ASTLocation.h"
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000017#include "clang/AST/Decl.h"
18#include "clang/AST/Stmt.h"
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000019#include "clang/AST/DeclVisitor.h"
20#include "clang/AST/StmtVisitor.h"
21#include "llvm/Support/Compiler.h"
22using namespace clang;
Argyrios Kyrtzidisccbcb702009-07-06 21:34:47 +000023using namespace idx;
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000024
25namespace {
26
27class VISIBILITY_HIDDEN StmtMapper : public StmtVisitor<StmtMapper> {
28 DeclReferenceMap::MapTy &Map;
29 Decl *Parent;
30
31public:
32 StmtMapper(DeclReferenceMap::MapTy &map, Decl *parent)
33 : Map(map), Parent(parent) { }
34
35 void VisitDeclStmt(DeclStmt *Node);
36 void VisitDeclRefExpr(DeclRefExpr *Node);
Argyrios Kyrtzidis9e6bc062009-07-14 03:18:09 +000037 void VisitMemberExpr(MemberExpr *Node);
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000038 void VisitStmt(Stmt *Node);
39};
40
41class VISIBILITY_HIDDEN DeclMapper : public DeclVisitor<DeclMapper> {
42 DeclReferenceMap::MapTy &Map;
43
44public:
45 DeclMapper(DeclReferenceMap::MapTy &map)
46 : Map(map) { }
47
48 void VisitDeclContext(DeclContext *DC);
49 void VisitVarDecl(VarDecl *D);
50 void VisitFunctionDecl(FunctionDecl *D);
51 void VisitBlockDecl(BlockDecl *D);
52 void VisitDecl(Decl *D);
53};
54
55} // anonymous namespace
56
57//===----------------------------------------------------------------------===//
58// StmtMapper Implementation
59//===----------------------------------------------------------------------===//
60
61void StmtMapper::VisitDeclStmt(DeclStmt *Node) {
62 DeclMapper Mapper(Map);
63 for (DeclStmt::decl_iterator
64 I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I)
65 Mapper.Visit(*I);
66}
67
68void StmtMapper::VisitDeclRefExpr(DeclRefExpr *Node) {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +000069 NamedDecl *PrimD = cast<NamedDecl>(Node->getDecl()->getCanonicalDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +000070 Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node)));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000071}
72
Argyrios Kyrtzidis9e6bc062009-07-14 03:18:09 +000073void StmtMapper::VisitMemberExpr(MemberExpr *Node) {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +000074 NamedDecl *PrimD = cast<NamedDecl>(Node->getMemberDecl()->getCanonicalDecl());
Argyrios Kyrtzidis9e6bc062009-07-14 03:18:09 +000075 Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node)));
76}
77
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000078void StmtMapper::VisitStmt(Stmt *Node) {
79 for (Stmt::child_iterator
80 I = Node->child_begin(), E = Node->child_end(); I != E; ++I)
81 Visit(*I);
82}
83
84//===----------------------------------------------------------------------===//
85// DeclMapper Implementation
86//===----------------------------------------------------------------------===//
87
88void DeclMapper::VisitDeclContext(DeclContext *DC) {
89 for (DeclContext::decl_iterator
90 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
91 Visit(*I);
92}
93
94void DeclMapper::VisitFunctionDecl(FunctionDecl *D) {
95 if (!D->isThisDeclarationADefinition())
96 return;
97
98 StmtMapper(Map, D).Visit(D->getBody());
99}
100
101void DeclMapper::VisitBlockDecl(BlockDecl *D) {
102 StmtMapper(Map, D).Visit(D->getBody());
103}
104
105void DeclMapper::VisitVarDecl(VarDecl *D) {
106 if (Expr *Init = D->getInit())
107 StmtMapper(Map, D).Visit(Init);
108}
109
110void DeclMapper::VisitDecl(Decl *D) {
111 if (DeclContext *DC = dyn_cast<DeclContext>(D))
112 VisitDeclContext(DC);
113}
114
115//===----------------------------------------------------------------------===//
116// DeclReferenceMap Implementation
117//===----------------------------------------------------------------------===//
118
119DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) {
120 DeclMapper(Map).Visit(Ctx.getTranslationUnitDecl());
121}
122
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000123DeclReferenceMap::astlocation_iterator
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000124DeclReferenceMap::refs_begin(NamedDecl *D) const {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +0000125 NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000126 return astlocation_iterator(Map.lower_bound(Prim));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000127}
128
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000129DeclReferenceMap::astlocation_iterator
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000130DeclReferenceMap::refs_end(NamedDecl *D) const {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +0000131 NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000132 return astlocation_iterator(Map.upper_bound(Prim));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000133}
134
135bool DeclReferenceMap::refs_empty(NamedDecl *D) const {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +0000136 NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000137 return refs_begin(Prim) == refs_end(Prim);
138}