blob: 841d7fb2fb7914a8a3dd7d892bad53b41bb2da88 [file] [log] [blame]
Argyrios Kyrtzidisccbcb702009-07-06 21:34:47 +00001//===--- DeclReferenceMap.cpp - Map Decls to their references ---*- C++ -*-===//
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);
37 void VisitStmt(Stmt *Node);
38};
39
40class VISIBILITY_HIDDEN DeclMapper : public DeclVisitor<DeclMapper> {
41 DeclReferenceMap::MapTy &Map;
42
43public:
44 DeclMapper(DeclReferenceMap::MapTy &map)
45 : Map(map) { }
46
47 void VisitDeclContext(DeclContext *DC);
48 void VisitVarDecl(VarDecl *D);
49 void VisitFunctionDecl(FunctionDecl *D);
50 void VisitBlockDecl(BlockDecl *D);
51 void VisitDecl(Decl *D);
52};
53
54} // anonymous namespace
55
56//===----------------------------------------------------------------------===//
57// StmtMapper Implementation
58//===----------------------------------------------------------------------===//
59
60void StmtMapper::VisitDeclStmt(DeclStmt *Node) {
61 DeclMapper Mapper(Map);
62 for (DeclStmt::decl_iterator
63 I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I)
64 Mapper.Visit(*I);
65}
66
67void StmtMapper::VisitDeclRefExpr(DeclRefExpr *Node) {
68 NamedDecl *PrimD = cast<NamedDecl>(Node->getDecl()->getPrimaryDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +000069 Map.insert(std::make_pair(PrimD, ASTLocation(Parent, Node)));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +000070}
71
72void StmtMapper::VisitStmt(Stmt *Node) {
73 for (Stmt::child_iterator
74 I = Node->child_begin(), E = Node->child_end(); I != E; ++I)
75 Visit(*I);
76}
77
78//===----------------------------------------------------------------------===//
79// DeclMapper Implementation
80//===----------------------------------------------------------------------===//
81
82void DeclMapper::VisitDeclContext(DeclContext *DC) {
83 for (DeclContext::decl_iterator
84 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
85 Visit(*I);
86}
87
88void DeclMapper::VisitFunctionDecl(FunctionDecl *D) {
89 if (!D->isThisDeclarationADefinition())
90 return;
91
92 StmtMapper(Map, D).Visit(D->getBody());
93}
94
95void DeclMapper::VisitBlockDecl(BlockDecl *D) {
96 StmtMapper(Map, D).Visit(D->getBody());
97}
98
99void DeclMapper::VisitVarDecl(VarDecl *D) {
100 if (Expr *Init = D->getInit())
101 StmtMapper(Map, D).Visit(Init);
102}
103
104void DeclMapper::VisitDecl(Decl *D) {
105 if (DeclContext *DC = dyn_cast<DeclContext>(D))
106 VisitDeclContext(DC);
107}
108
109//===----------------------------------------------------------------------===//
110// DeclReferenceMap Implementation
111//===----------------------------------------------------------------------===//
112
113DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) {
114 DeclMapper(Map).Visit(Ctx.getTranslationUnitDecl());
115}
116
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000117DeclReferenceMap::astlocation_iterator
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000118DeclReferenceMap::refs_begin(NamedDecl *D) const {
119 NamedDecl *Prim = cast<NamedDecl>(D->getPrimaryDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000120 return astlocation_iterator(Map.lower_bound(Prim));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000121}
122
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000123DeclReferenceMap::astlocation_iterator
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000124DeclReferenceMap::refs_end(NamedDecl *D) const {
125 NamedDecl *Prim = cast<NamedDecl>(D->getPrimaryDecl());
Argyrios Kyrtzidis874012b2009-07-06 21:34:20 +0000126 return astlocation_iterator(Map.upper_bound(Prim));
Argyrios Kyrtzidis2c2ba3e2009-07-05 22:22:06 +0000127}
128
129bool DeclReferenceMap::refs_empty(NamedDecl *D) const {
130 NamedDecl *Prim = cast<NamedDecl>(D->getPrimaryDecl());
131 return refs_begin(Prim) == refs_end(Prim);
132}