blob: f99f4ae84d6efe2df75cfc804c86bd65a1296b52 [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 Kyrtzidis80ede1d2009-07-21 00:05:38 +000038 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000039 void VisitStmt(Stmt *Node);
40};
41
42class VISIBILITY_HIDDEN DeclMapper : public DeclVisitor<DeclMapper> {
43 DeclReferenceMap::MapTy &Map;
44
45public:
46 DeclMapper(DeclReferenceMap::MapTy &map)
47 : Map(map) { }
48
49 void VisitDeclContext(DeclContext *DC);
50 void VisitVarDecl(VarDecl *D);
51 void VisitFunctionDecl(FunctionDecl *D);
Argyrios Kyrtzidis80ede1d2009-07-21 00:05:38 +000052 void VisitObjCMethodDecl(ObjCMethodDecl *D);
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000053 void VisitBlockDecl(BlockDecl *D);
54 void VisitDecl(Decl *D);
55};
56
57} // anonymous namespace
58
59//===----------------------------------------------------------------------===//
60// StmtMapper Implementation
61//===----------------------------------------------------------------------===//
62
63void StmtMapper::VisitDeclStmt(DeclStmt *Node) {
64 DeclMapper Mapper(Map);
65 for (DeclStmt::decl_iterator
66 I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I)
67 Mapper.Visit(*I);
68}
69
70void StmtMapper::VisitDeclRefExpr(DeclRefExpr *Node) {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +000071 NamedDecl *PrimD = cast<NamedDecl>(Node->getDecl()->getCanonicalDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +000072 Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node)));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000073}
74
Argyrios Kyrtzidis9e6bc062009-07-14 03:18:09 +000075void StmtMapper::VisitMemberExpr(MemberExpr *Node) {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +000076 NamedDecl *PrimD = cast<NamedDecl>(Node->getMemberDecl()->getCanonicalDecl());
Argyrios Kyrtzidis9e6bc062009-07-14 03:18:09 +000077 Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node)));
78}
79
Argyrios Kyrtzidis80ede1d2009-07-21 00:05:38 +000080void StmtMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
81 Map.insert(std::make_pair(Node->getDecl(), ASTLocation(Parent, Node)));
82}
83
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000084void StmtMapper::VisitStmt(Stmt *Node) {
85 for (Stmt::child_iterator
86 I = Node->child_begin(), E = Node->child_end(); I != E; ++I)
87 Visit(*I);
88}
89
90//===----------------------------------------------------------------------===//
91// DeclMapper Implementation
92//===----------------------------------------------------------------------===//
93
94void DeclMapper::VisitDeclContext(DeclContext *DC) {
95 for (DeclContext::decl_iterator
96 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
97 Visit(*I);
98}
99
100void DeclMapper::VisitFunctionDecl(FunctionDecl *D) {
Argyrios Kyrtzidis80ede1d2009-07-21 00:05:38 +0000101 if (D->isThisDeclarationADefinition())
102 StmtMapper(Map, D).Visit(D->getBody());
103}
104
105void DeclMapper::VisitObjCMethodDecl(ObjCMethodDecl *D) {
106 if (D->getBody())
107 StmtMapper(Map, D).Visit(D->getBody());
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000108}
109
110void DeclMapper::VisitBlockDecl(BlockDecl *D) {
111 StmtMapper(Map, D).Visit(D->getBody());
112}
113
114void DeclMapper::VisitVarDecl(VarDecl *D) {
115 if (Expr *Init = D->getInit())
116 StmtMapper(Map, D).Visit(Init);
117}
118
119void DeclMapper::VisitDecl(Decl *D) {
120 if (DeclContext *DC = dyn_cast<DeclContext>(D))
121 VisitDeclContext(DC);
122}
123
124//===----------------------------------------------------------------------===//
125// DeclReferenceMap Implementation
126//===----------------------------------------------------------------------===//
127
128DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) {
129 DeclMapper(Map).Visit(Ctx.getTranslationUnitDecl());
130}
131
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000132DeclReferenceMap::astlocation_iterator
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000133DeclReferenceMap::refs_begin(NamedDecl *D) const {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +0000134 NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000135 return astlocation_iterator(Map.lower_bound(Prim));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000136}
137
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000138DeclReferenceMap::astlocation_iterator
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000139DeclReferenceMap::refs_end(NamedDecl *D) const {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +0000140 NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000141 return astlocation_iterator(Map.upper_bound(Prim));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000142}
143
144bool DeclReferenceMap::refs_empty(NamedDecl *D) const {
Argyrios Kyrtzidisb57a4fe2009-07-18 00:34:07 +0000145 NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000146 return refs_begin(Prim) == refs_end(Prim);
147}