TypeLoc.cpp revision 198112
1198092Srdivacky//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
2198092Srdivacky//
3198092Srdivacky//                     The LLVM Compiler Infrastructure
4198092Srdivacky//
5198092Srdivacky// This file is distributed under the University of Illinois Open Source
6198092Srdivacky// License. See LICENSE.TXT for details.
7198092Srdivacky//
8198092Srdivacky//===----------------------------------------------------------------------===//
9198092Srdivacky//
10198092Srdivacky//  This file defines the TypeLoc subclasses implementations.
11198092Srdivacky//
12198092Srdivacky//===----------------------------------------------------------------------===//
13198092Srdivacky
14198112Srdivacky#include "llvm/Support/raw_ostream.h"
15198092Srdivacky#include "clang/AST/TypeLocVisitor.h"
16198092Srdivackyusing namespace clang;
17198092Srdivacky
18198092Srdivacky//===----------------------------------------------------------------------===//
19198092Srdivacky// TypeLoc Implementation
20198092Srdivacky//===----------------------------------------------------------------------===//
21198092Srdivacky
22198092Srdivackynamespace {
23198092Srdivacky
24198092Srdivacky/// \brief Return the source range for the visited TypeSpecLoc.
25198092Srdivackyclass TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
26198092Srdivackypublic:
27198092Srdivacky#define ABSTRACT_TYPELOC(CLASS)
28198112Srdivacky#define TYPELOC(CLASS, PARENT) \
29198092Srdivacky    SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); }
30198092Srdivacky#include "clang/AST/TypeLocNodes.def"
31198092Srdivacky
32198092Srdivacky  SourceRange VisitTypeLoc(TypeLoc TyLoc) {
33198092Srdivacky    assert(0 && "A typeloc wrapper was not handled!");
34198092Srdivacky    return SourceRange();
35198092Srdivacky  }
36198092Srdivacky};
37198092Srdivacky
38198092Srdivacky}
39198092Srdivacky
40198092SrdivackySourceRange TypeLoc::getSourceRange() const {
41198092Srdivacky  if (isNull())
42198092Srdivacky    return SourceRange();
43198092Srdivacky  return TypeLocRanger().Visit(*this);
44198092Srdivacky}
45198092Srdivacky
46198092Srdivacky/// \brief Find the TypeSpecLoc that is part of this TypeLoc.
47198092SrdivackyTypeSpecLoc TypeLoc::getTypeSpecLoc() const {
48198092Srdivacky  if (isNull())
49198092Srdivacky    return TypeSpecLoc();
50198112Srdivacky  UnqualTypeLoc Cur = getUnqualifiedLoc();
51198112Srdivacky  if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(&Cur))
52198092Srdivacky    return DL->getTypeSpecLoc();
53198112Srdivacky  return cast<TypeSpecLoc>(Cur);
54198092Srdivacky}
55198092Srdivacky
56198092Srdivackynamespace {
57198092Srdivacky
58198092Srdivacky/// \brief Report the full source info data size for the visited TypeLoc.
59198092Srdivackyclass TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
60198092Srdivackypublic:
61198092Srdivacky#define ABSTRACT_TYPELOC(CLASS)
62198112Srdivacky#define TYPELOC(CLASS, PARENT) \
63198092Srdivacky    unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); }
64198092Srdivacky#include "clang/AST/TypeLocNodes.def"
65198092Srdivacky
66198092Srdivacky  unsigned VisitTypeLoc(TypeLoc TyLoc) {
67198092Srdivacky    assert(0 && "A type loc wrapper was not handled!");
68198092Srdivacky    return 0;
69198092Srdivacky  }
70198092Srdivacky};
71198092Srdivacky
72198092Srdivacky}
73198092Srdivacky
74198092Srdivacky/// \brief Returns the size of the type source info data block.
75198112Srdivackyunsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
76198112Srdivacky  if (Ty.isNull()) return 0;
77198112Srdivacky  return TypeSizer().Visit(TypeLoc(Ty, 0));
78198092Srdivacky}
79198092Srdivacky
80198092Srdivackynamespace {
81198092Srdivacky
82198092Srdivacky/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the
83198092Srdivacky/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
84198092Srdivackyclass NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
85198092Srdivackypublic:
86198112Srdivacky#define TYPELOC(CLASS, PARENT)
87198092Srdivacky#define DECLARATOR_TYPELOC(CLASS, TYPE) \
88198112Srdivacky  TypeLoc Visit##CLASS(CLASS TyLoc);
89198092Srdivacky#include "clang/AST/TypeLocNodes.def"
90198092Srdivacky
91198092Srdivacky  TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); }
92198092Srdivacky  TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
93198112Srdivacky  TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
94198112Srdivacky    return TyLoc.getUnqualifiedLoc();
95198112Srdivacky  }
96198092Srdivacky
97198092Srdivacky  TypeLoc VisitTypeLoc(TypeLoc TyLoc) {
98198092Srdivacky    assert(0 && "A declarator loc wrapper was not handled!");
99198092Srdivacky    return TypeLoc();
100198092Srdivacky  }
101198092Srdivacky};
102198092Srdivacky
103198092Srdivacky}
104198092Srdivacky
105198092SrdivackyTypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) {
106198092Srdivacky  return TL.getBaseTypeLoc();
107198092Srdivacky}
108198092Srdivacky
109198092SrdivackyTypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) {
110198092Srdivacky  return TL.getPointeeLoc();
111198092Srdivacky}
112198092SrdivackyTypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) {
113198092Srdivacky  return TL.getPointeeLoc();
114198092Srdivacky}
115198092SrdivackyTypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) {
116198092Srdivacky  return TL.getPointeeLoc();
117198092Srdivacky}
118198092SrdivackyTypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) {
119198092Srdivacky  return TL.getPointeeLoc();
120198092Srdivacky}
121198092SrdivackyTypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) {
122198092Srdivacky  return TL.getResultLoc();
123198092Srdivacky}
124198092SrdivackyTypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) {
125198092Srdivacky  return TL.getElementLoc();
126198092Srdivacky}
127198092Srdivacky
128198092Srdivacky/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
129198092Srdivacky/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
130198092SrdivackyTypeLoc TypeLoc::getNextTypeLoc() const {
131198112Srdivacky  //llvm::errs() << "getNextTypeLoc: Ty=" << Ty << ", Data=" << Data << "\n";
132198112Srdivacky  TypeLoc Tmp = NextLoc().Visit(*this);
133198112Srdivacky  //llvm::errs() << "  result: Ty=" << Tmp.Ty << ", Data=" << Tmp.Data << "\n";
134198112Srdivacky  return Tmp;
135198092Srdivacky}
136198092Srdivacky
137198092Srdivacky//===----------------------------------------------------------------------===//
138198092Srdivacky// TypeSpecLoc Implementation
139198092Srdivacky//===----------------------------------------------------------------------===//
140198092Srdivacky
141198092Srdivackynamespace {
142198092Srdivackyclass TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> {
143198092Srdivackypublic:
144198092Srdivacky  bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; }
145198092Srdivacky};
146198092Srdivacky
147198092Srdivacky}
148198092Srdivacky
149198112Srdivackybool TypeSpecLoc::classof(const UnqualTypeLoc *TL) {
150198092Srdivacky  return TypeSpecChecker().Visit(*TL);
151198092Srdivacky}
152198092Srdivacky
153198092Srdivacky//===----------------------------------------------------------------------===//
154198092Srdivacky// DeclaratorLoc Implementation
155198092Srdivacky//===----------------------------------------------------------------------===//
156198092Srdivacky
157198092Srdivackynamespace {
158198092Srdivacky
159198092Srdivacky/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc.
160198092Srdivackyclass TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> {
161198092Srdivackypublic:
162198112Srdivacky#define TYPELOC(CLASS, PARENT)
163198092Srdivacky#define DECLARATOR_TYPELOC(CLASS, TYPE) \
164198092Srdivacky    TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); }
165198092Srdivacky#include "clang/AST/TypeLocNodes.def"
166198092Srdivacky
167198092Srdivacky  TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) {
168198092Srdivacky    assert(0 && "A declarator loc wrapper was not handled!");
169198092Srdivacky    return TypeSpecLoc();
170198092Srdivacky  }
171198112Srdivacky
172198112Srdivacky  TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
173198112Srdivacky    return Visit(TyLoc.getUnqualifiedLoc());
174198112Srdivacky  }
175198092Srdivacky};
176198092Srdivacky
177198092Srdivacky}
178198092Srdivacky
179198092Srdivacky/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
180198092SrdivackyTypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const {
181198092Srdivacky  return TypeSpecGetter().Visit(*this);
182198092Srdivacky}
183198092Srdivacky
184198092Srdivackynamespace {
185198092Srdivacky
186198092Srdivackyclass DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> {
187198092Srdivackypublic:
188198092Srdivacky  bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; }
189198092Srdivacky};
190198092Srdivacky
191198092Srdivacky}
192198092Srdivacky
193198112Srdivackybool DeclaratorLoc::classof(const UnqualTypeLoc *TL) {
194198092Srdivacky  return DeclaratorLocChecker().Visit(*TL);
195198092Srdivacky}
196198092Srdivacky
197198092Srdivacky//===----------------------------------------------------------------------===//
198198092Srdivacky// DefaultTypeSpecLoc Implementation
199198092Srdivacky//===----------------------------------------------------------------------===//
200198092Srdivacky
201198092Srdivackynamespace {
202198092Srdivacky
203198092Srdivackyclass DefaultTypeSpecLocChecker :
204198092Srdivacky                        public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> {
205198092Srdivackypublic:
206198092Srdivacky  bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; }
207198092Srdivacky};
208198092Srdivacky
209198092Srdivacky}
210198092Srdivacky
211198112Srdivackybool DefaultTypeSpecLoc::classofType(const Type *Ty) {
212198112Srdivacky  return
213198112Srdivacky    DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0));
214198092Srdivacky}
215198112Srdivacky
216