TypeLoc.cpp revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  This file defines the TypeLoc subclasses implementations.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/AST/TypeLoc.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TypeLoc Implementation
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// \brief Returns the size of type source info data block for the given type.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TypeLoc(Ty, 0).getFullDataSize();
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// \brief Find the TypeSpecLoc that is part of this TypeLoc.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TypeSpecLoc TypeLoc::getTypeSpecLoc() const {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (isNull())
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TypeSpecLoc();
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(this))
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DL->getTypeSpecLoc();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cast<TypeSpecLoc>(*this);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35
36/// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its
37/// SourceRange.
38SourceRange TypeLoc::getTypeSpecRange() const {
39  return getTypeSpecLoc().getSourceRange();
40}
41
42namespace {
43
44/// \brief Report the full source info data size for the visited TypeLoc.
45class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
46public:
47#define ABSTRACT_TYPELOC(CLASS)
48#define TYPELOC(CLASS, PARENT, TYPE) \
49    unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); }
50#include "clang/AST/TypeLocNodes.def"
51
52  unsigned VisitTypeLoc(TypeLoc TyLoc) {
53    assert(0 && "A type loc wrapper was not handled!");
54    return 0;
55  }
56};
57
58}
59
60/// \brief Returns the size of the type source info data block.
61unsigned TypeLoc::getFullDataSize() const {
62  return TypeSizer().Visit(*this);
63}
64
65namespace {
66
67/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the
68/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
69class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
70public:
71#define TYPELOC(CLASS, PARENT, TYPE)
72#define DECLARATOR_TYPELOC(CLASS, TYPE) \
73    TypeLoc Visit##CLASS(CLASS TyLoc);
74#include "clang/AST/TypeLocNodes.def"
75
76  TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); }
77
78  TypeLoc VisitTypeLoc(TypeLoc TyLoc) {
79    assert(0 && "A declarator loc wrapper was not handled!");
80    return TypeLoc();
81  }
82};
83
84}
85
86TypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) {
87  return TL.getPointeeLoc();
88}
89TypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) {
90  return TL.getPointeeLoc();
91}
92TypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) {
93  return TL.getPointeeLoc();
94}
95TypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) {
96  return TL.getPointeeLoc();
97}
98TypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) {
99  return TL.getResultLoc();
100}
101TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) {
102  return TL.getElementLoc();
103}
104
105/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
106/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
107TypeLoc TypeLoc::getNextTypeLoc() const {
108  return NextLoc().Visit(*this);
109}
110
111//===----------------------------------------------------------------------===//
112// TypeSpecLoc Implementation
113//===----------------------------------------------------------------------===//
114
115namespace {
116
117/// \brief Return the source range for the visited TypeSpecLoc.
118class TypeSpecRanger : public TypeLocVisitor<TypeSpecRanger, SourceRange> {
119public:
120#define TYPELOC(CLASS, PARENT, TYPE)
121#define TYPESPEC_TYPELOC(CLASS, TYPE) \
122    SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); }
123#include "clang/AST/TypeLocNodes.def"
124
125  SourceRange VisitTypeLoc(TypeLoc TyLoc) {
126    assert(0 && "A typespec loc wrapper was not handled!");
127    return SourceRange();
128  }
129};
130
131}
132
133SourceRange TypeSpecLoc::getSourceRange() const {
134  if (isNull())
135    return SourceRange();
136  return TypeSpecRanger().Visit(*this);
137}
138
139namespace {
140class TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> {
141public:
142  bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; }
143};
144
145}
146
147bool TypeSpecLoc::classof(const TypeLoc *TL) {
148  return TypeSpecChecker().Visit(*TL);
149}
150
151//===----------------------------------------------------------------------===//
152// DeclaratorLoc Implementation
153//===----------------------------------------------------------------------===//
154
155namespace {
156
157/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc.
158class TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> {
159public:
160#define TYPELOC(CLASS, PARENT, TYPE)
161#define DECLARATOR_TYPELOC(CLASS, TYPE) \
162    TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); }
163#include "clang/AST/TypeLocNodes.def"
164
165  TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) {
166    assert(0 && "A declarator loc wrapper was not handled!");
167    return TypeSpecLoc();
168  }
169};
170
171}
172
173/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
174TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const {
175  return TypeSpecGetter().Visit(*this);
176}
177
178namespace {
179
180class DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> {
181public:
182  bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; }
183};
184
185}
186
187bool DeclaratorLoc::classof(const TypeLoc *TL) {
188  return DeclaratorLocChecker().Visit(*TL);
189}
190
191//===----------------------------------------------------------------------===//
192// DefaultTypeSpecLoc Implementation
193//===----------------------------------------------------------------------===//
194
195namespace {
196
197class DefaultTypeSpecLocChecker :
198                        public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> {
199public:
200  bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; }
201};
202
203}
204
205bool DefaultTypeSpecLoc::classof(const TypeLoc *TL) {
206  return DefaultTypeSpecLocChecker().Visit(*TL);
207}
208
209//===----------------------------------------------------------------------===//
210// TypedefLoc Implementation
211//===----------------------------------------------------------------------===//
212
213namespace {
214
215class TypedefLocChecker : public TypeLocVisitor<TypedefLocChecker, bool> {
216public:
217  bool VisitTypedefLoc(TypedefLoc TyLoc) { return true; }
218};
219
220}
221
222bool TypedefLoc::classof(const TypeLoc *TL) {
223  return TypedefLocChecker().Visit(*TL);
224}
225
226//===----------------------------------------------------------------------===//
227// PointerLoc Implementation
228//===----------------------------------------------------------------------===//
229
230namespace {
231
232class PointerLocChecker : public TypeLocVisitor<PointerLocChecker, bool> {
233public:
234  bool VisitPointerLoc(PointerLoc TyLoc) { return true; }
235};
236
237}
238
239bool PointerLoc::classof(const TypeLoc *TL) {
240  return PointerLocChecker().Visit(*TL);
241}
242
243//===----------------------------------------------------------------------===//
244// BlockPointerLoc Implementation
245//===----------------------------------------------------------------------===//
246
247namespace {
248
249class BlockPointerLocChecker :
250           public TypeLocVisitor<BlockPointerLocChecker, bool> {
251public:
252  bool VisitBlockPointerLoc(BlockPointerLoc TyLoc) { return true; }
253};
254
255}
256
257bool BlockPointerLoc::classof(const TypeLoc *TL) {
258  return BlockPointerLocChecker().Visit(*TL);
259}
260
261//===----------------------------------------------------------------------===//
262// MemberPointerLoc Implementation
263//===----------------------------------------------------------------------===//
264
265namespace {
266
267class MemberPointerLocChecker :
268           public TypeLocVisitor<MemberPointerLocChecker, bool> {
269public:
270  bool VisitMemberPointerLoc(MemberPointerLoc TyLoc) { return true; }
271};
272
273}
274
275bool MemberPointerLoc::classof(const TypeLoc *TL) {
276  return MemberPointerLocChecker().Visit(*TL);
277}
278
279//===----------------------------------------------------------------------===//
280// ReferenceLoc Implementation
281//===----------------------------------------------------------------------===//
282
283namespace {
284
285class ReferenceLocChecker : public TypeLocVisitor<ReferenceLocChecker, bool> {
286public:
287  bool VisitReferenceLoc(ReferenceLoc TyLoc) { return true; }
288};
289
290}
291
292bool ReferenceLoc::classof(const TypeLoc *TL) {
293  return ReferenceLocChecker().Visit(*TL);
294}
295
296//===----------------------------------------------------------------------===//
297// FunctionLoc Implementation
298//===----------------------------------------------------------------------===//
299
300namespace {
301
302class FunctionLocChecker : public TypeLocVisitor<FunctionLocChecker, bool> {
303public:
304  bool VisitFunctionLoc(FunctionLoc TyLoc) { return true; }
305};
306
307}
308
309bool FunctionLoc::classof(const TypeLoc *TL) {
310  return FunctionLocChecker().Visit(*TL);
311}
312
313//===----------------------------------------------------------------------===//
314// ArrayLoc Implementation
315//===----------------------------------------------------------------------===//
316
317namespace {
318
319class ArrayLocChecker : public TypeLocVisitor<ArrayLocChecker, bool> {
320public:
321  bool VisitArrayLoc(ArrayLoc TyLoc) { return true; }
322};
323
324}
325
326bool ArrayLoc::classof(const TypeLoc *TL) {
327  return ArrayLocChecker().Visit(*TL);
328}
329