 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
0.0% |
0 / 0 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
0.0% |
0 / 0 |
| |
|
Line Coverage: |
100.0% |
1 / 1 |
| |
 |
|
 |
1 : //===--- ASTLocation.h - A <Decl, Stmt> pair --------------------*- C++ -*-===//
2 : //
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 : //
10 : // ASTLocation is Decl or a Stmt and its immediate Decl parent.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_INDEX_ASTLOCATION_H
15 : #define LLVM_CLANG_INDEX_ASTLOCATION_H
16 :
17 : #include "clang/AST/TypeLoc.h"
18 : #include "llvm/ADT/PointerIntPair.h"
19 :
20 : namespace llvm {
21 : class raw_ostream;
22 : }
23 :
24 : namespace clang {
25 : class Decl;
26 : class Stmt;
27 : class NamedDecl;
28 :
29 : namespace idx {
30 : class TranslationUnit;
31 :
32 : /// \brief Represents a Decl or a Stmt and its immediate Decl parent. It's
33 : /// immutable.
34 : ///
35 : /// ASTLocation is intended to be used as a "pointer" into the AST. It is either
36 : /// just a Decl, or a Stmt and its Decl parent. Since a single Stmt is devoid
37 : /// of context, its parent Decl provides all the additional missing information
38 : /// like the declaration context, ASTContext, etc.
39 : ///
40 : class ASTLocation {
41 : public:
42 : enum NodeKind {
43 : N_Decl, N_NamedRef, N_Stmt, N_Type
44 : };
45 :
46 : struct NamedRef {
47 : NamedDecl *ND;
48 : SourceLocation Loc;
49 :
50 : NamedRef() : ND(0) { }
51 : NamedRef(NamedDecl *nd, SourceLocation loc) : ND(nd), Loc(loc) { }
52 : };
53 :
54 : private:
55 : llvm::PointerIntPair<Decl *, 2, NodeKind> ParentDecl;
56 :
57 : union {
58 : Decl *D;
59 : Stmt *Stm;
60 : struct {
61 : NamedDecl *ND;
62 : unsigned RawLoc;
63 : } NDRef;
64 : struct {
65 : void *TyPtr;
66 : void *Data;
67 : } Ty;
68 : };
69 :
70 : public:
71 22: ASTLocation() { }
72 :
73 : explicit ASTLocation(const Decl *d)
74 : : ParentDecl(const_cast<Decl*>(d), N_Decl), D(const_cast<Decl*>(d)) { }
75 :
76 : ASTLocation(const Decl *parentDecl, const Stmt *stm)
77 : : ParentDecl(const_cast<Decl*>(parentDecl), N_Stmt),
78 : Stm(const_cast<Stmt*>(stm)) {
79 : if (!stm) ParentDecl.setPointer(0);
80 : }
81 :
82 : ASTLocation(const Decl *parentDecl, NamedDecl *ndRef, SourceLocation loc)
83 : : ParentDecl(const_cast<Decl*>(parentDecl), N_NamedRef) {
84 : if (ndRef) {
85 : NDRef.ND = ndRef;
86 : NDRef.RawLoc = loc.getRawEncoding();
87 : } else
88 : ParentDecl.setPointer(0);
89 : }
90 :
91 : ASTLocation(const Decl *parentDecl, TypeLoc tyLoc)
92 : : ParentDecl(const_cast<Decl*>(parentDecl), N_Type) {
93 : if (tyLoc) {
94 : Ty.TyPtr = tyLoc.getType().getAsOpaquePtr();
95 : Ty.Data = tyLoc.getOpaqueData();
96 : } else
97 : ParentDecl.setPointer(0);
98 : }
99 :
100 : bool isValid() const { return ParentDecl.getPointer() != 0; }
101 : bool isInvalid() const { return !isValid(); }
102 :
103 : NodeKind getKind() const {
104 : assert(isValid());
105 : return (NodeKind)ParentDecl.getInt();
106 : }
107 :
108 : Decl *getParentDecl() const { return ParentDecl.getPointer(); }
109 :
110 : Decl *AsDecl() const {
111 : assert(getKind() == N_Decl);
112 : return D;
113 : }
114 : Stmt *AsStmt() const {
115 : assert(getKind() == N_Stmt);
116 : return Stm;
117 : }
118 : NamedRef AsNamedRef() const {
119 : assert(getKind() == N_NamedRef);
120 : return NamedRef(NDRef.ND, SourceLocation::getFromRawEncoding(NDRef.RawLoc));
121 : }
122 : TypeLoc AsTypeLoc() const {
123 : assert(getKind() == N_Type);
124 : return TypeLoc(QualType::getFromOpaquePtr(Ty.TyPtr), Ty.Data);
125 : }
126 :
127 : Decl *dyn_AsDecl() const { return isValid() && getKind() == N_Decl ? D : 0; }
128 : Stmt *dyn_AsStmt() const { return isValid() && getKind() == N_Stmt ? Stm : 0; }
129 : NamedRef dyn_AsNamedRef() const {
130 : return getKind() == N_Type ? AsNamedRef() : NamedRef();
131 : }
132 : TypeLoc dyn_AsTypeLoc() const {
133 : return getKind() == N_Type ? AsTypeLoc() : TypeLoc();
134 : }
135 :
136 : bool isDecl() const { return isValid() && getKind() == N_Decl; }
137 : bool isStmt() const { return isValid() && getKind() == N_Stmt; }
138 : bool isNamedRef() const { return isValid() && getKind() == N_NamedRef; }
139 : bool isType() const { return isValid() && getKind() == N_Type; }
140 :
141 : /// \brief Returns the declaration that this ASTLocation references.
142 : ///
143 : /// If this points to a Decl, that Decl is returned.
144 : /// If this points to an Expr that references a Decl, that Decl is returned,
145 : /// otherwise it returns NULL.
146 : Decl *getReferencedDecl();
147 : const Decl *getReferencedDecl() const {
148 : return const_cast<ASTLocation*>(this)->getReferencedDecl();
149 : }
150 :
151 : SourceRange getSourceRange() const;
152 :
153 : void print(llvm::raw_ostream &OS) const;
154 : };
155 :
156 : /// \brief Like ASTLocation but also contains the TranslationUnit that the
157 : /// ASTLocation originated from.
158 : class TULocation : public ASTLocation {
159 : TranslationUnit *TU;
160 :
161 : public:
162 : TULocation(TranslationUnit *tu, ASTLocation astLoc)
163 : : ASTLocation(astLoc), TU(tu) {
164 : assert(tu && "Passed null translation unit");
165 : }
166 :
167 : TranslationUnit *getTU() const { return TU; }
168 : };
169 :
170 : } // namespace idx
171 :
172 : } // namespace clang
173 :
174 : #endif
Generated: 2010-02-10 01:31 by zcov