clang  6.0.0svn
TypeLoc.cpp
Go to the documentation of this file.
1 //===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- 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 // This file defines the TypeLoc subclasses implementations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/TypeLoc.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Expr.h"
18 #include "llvm/Support/ErrorHandling.h"
19 using namespace clang;
20 
21 static const unsigned TypeLocMaxDataAlign = alignof(void *);
22 
23 //===----------------------------------------------------------------------===//
24 // TypeLoc Implementation
25 //===----------------------------------------------------------------------===//
26 
27 namespace {
28  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
29  public:
30 #define ABSTRACT_TYPELOC(CLASS, PARENT)
31 #define TYPELOC(CLASS, PARENT) \
32  SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
33  return TyLoc.getLocalSourceRange(); \
34  }
35 #include "clang/AST/TypeLocNodes.def"
36  };
37 }
38 
39 SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
40  if (TL.isNull()) return SourceRange();
41  return TypeLocRanger().Visit(TL);
42 }
43 
44 namespace {
45  class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
46  public:
47 #define ABSTRACT_TYPELOC(CLASS, PARENT)
48 #define TYPELOC(CLASS, PARENT) \
49  unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
50  return TyLoc.getLocalDataAlignment(); \
51  }
52 #include "clang/AST/TypeLocNodes.def"
53  };
54 }
55 
56 /// \brief Returns the alignment of the type source info data block.
58  if (Ty.isNull()) return 1;
59  return TypeAligner().Visit(TypeLoc(Ty, nullptr));
60 }
61 
62 namespace {
63  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
64  public:
65 #define ABSTRACT_TYPELOC(CLASS, PARENT)
66 #define TYPELOC(CLASS, PARENT) \
67  unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
68  return TyLoc.getLocalDataSize(); \
69  }
70 #include "clang/AST/TypeLocNodes.def"
71  };
72 }
73 
74 /// \brief Returns the size of the type source info data block.
76  unsigned Total = 0;
77  TypeLoc TyLoc(Ty, nullptr);
78  unsigned MaxAlign = 1;
79  while (!TyLoc.isNull()) {
80  unsigned Align = getLocalAlignmentForType(TyLoc.getType());
81  MaxAlign = std::max(Align, MaxAlign);
82  Total = llvm::alignTo(Total, Align);
83  Total += TypeSizer().Visit(TyLoc);
84  TyLoc = TyLoc.getNextTypeLoc();
85  }
86  Total = llvm::alignTo(Total, MaxAlign);
87  return Total;
88 }
89 
90 namespace {
91  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
92  public:
93 #define ABSTRACT_TYPELOC(CLASS, PARENT)
94 #define TYPELOC(CLASS, PARENT) \
95  TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
96  return TyLoc.getNextTypeLoc(); \
97  }
98 #include "clang/AST/TypeLocNodes.def"
99  };
100 }
101 
102 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
103 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
104 TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
105  return NextLoc().Visit(TL);
106 }
107 
108 /// \brief Initializes a type location, and all of its children
109 /// recursively, as if the entire tree had been written in the
110 /// given location.
111 void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
112  SourceLocation Loc) {
113  while (true) {
114  switch (TL.getTypeLocClass()) {
115 #define ABSTRACT_TYPELOC(CLASS, PARENT)
116 #define TYPELOC(CLASS, PARENT) \
117  case CLASS: { \
118  CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
119  TLCasted.initializeLocal(Context, Loc); \
120  TL = TLCasted.getNextTypeLoc(); \
121  if (!TL) return; \
122  continue; \
123  }
124 #include "clang/AST/TypeLocNodes.def"
125  }
126  }
127 }
128 
129 namespace {
130  class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
131  TypeLoc Source;
132  public:
133  TypeLocCopier(TypeLoc source) : Source(source) { }
134 
135 #define ABSTRACT_TYPELOC(CLASS, PARENT)
136 #define TYPELOC(CLASS, PARENT) \
137  void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) { \
138  dest.copyLocal(Source.castAs<CLASS##TypeLoc>()); \
139  }
140 #include "clang/AST/TypeLocNodes.def"
141  };
142 }
143 
144 
145 void TypeLoc::copy(TypeLoc other) {
146  assert(getFullDataSize() == other.getFullDataSize());
147 
148  // If both data pointers are aligned to the maximum alignment, we
149  // can memcpy because getFullDataSize() accurately reflects the
150  // layout of the data.
151  if (reinterpret_cast<uintptr_t>(Data) ==
152  llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
154  reinterpret_cast<uintptr_t>(other.Data) ==
155  llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
157  memcpy(Data, other.Data, getFullDataSize());
158  return;
159  }
160 
161  // Copy each of the pieces.
162  TypeLoc TL(getType(), Data);
163  do {
164  TypeLocCopier(other).Visit(TL);
165  other = other.getNextTypeLoc();
166  } while ((TL = TL.getNextTypeLoc()));
167 }
168 
170  TypeLoc Cur = *this;
171  TypeLoc LeftMost = Cur;
172  while (true) {
173  switch (Cur.getTypeLocClass()) {
174  case Elaborated:
175  LeftMost = Cur;
176  break;
177  case FunctionProto:
179  ->hasTrailingReturn()) {
180  LeftMost = Cur;
181  break;
182  }
183  /* Fall through */
184  case FunctionNoProto:
185  case ConstantArray:
186  case DependentSizedArray:
187  case IncompleteArray:
188  case VariableArray:
189  // FIXME: Currently QualifiedTypeLoc does not have a source range
190  case Qualified:
191  Cur = Cur.getNextTypeLoc();
192  continue;
193  default:
194  if (Cur.getLocalSourceRange().getBegin().isValid())
195  LeftMost = Cur;
196  Cur = Cur.getNextTypeLoc();
197  if (Cur.isNull())
198  break;
199  continue;
200  } // switch
201  break;
202  } // while
203  return LeftMost.getLocalSourceRange().getBegin();
204 }
205 
207  TypeLoc Cur = *this;
208  TypeLoc Last;
209  while (true) {
210  switch (Cur.getTypeLocClass()) {
211  default:
212  if (!Last)
213  Last = Cur;
214  return Last.getLocalSourceRange().getEnd();
215  case Paren:
216  case ConstantArray:
217  case DependentSizedArray:
218  case IncompleteArray:
219  case VariableArray:
220  case FunctionNoProto:
221  Last = Cur;
222  break;
223  case FunctionProto:
225  Last = TypeLoc();
226  else
227  Last = Cur;
228  break;
229  case Pointer:
230  case BlockPointer:
231  case MemberPointer:
232  case LValueReference:
233  case RValueReference:
234  case PackExpansion:
235  if (!Last)
236  Last = Cur;
237  break;
238  case Qualified:
239  case Elaborated:
240  break;
241  }
242  Cur = Cur.getNextTypeLoc();
243  }
244 }
245 
246 
247 namespace {
248  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
249  // Overload resolution does the real work for us.
250  static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
251  static bool isTypeSpec(TypeLoc _) { return false; }
252 
253 #define ABSTRACT_TYPELOC(CLASS, PARENT)
254 #define TYPELOC(CLASS, PARENT) \
255  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
256  return isTypeSpec(TyLoc); \
257  }
258 #include "clang/AST/TypeLocNodes.def"
259  };
260 }
261 
262 
263 /// \brief Determines if the given type loc corresponds to a
264 /// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in
265 /// the type hierarchy, this is made somewhat complicated.
266 ///
267 /// There are a lot of types that currently use TypeSpecTypeLoc
268 /// because it's a convenient base class. Ideally we would not accept
269 /// those here, but ideally we would have better implementations for
270 /// them.
271 bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
272  if (TL.getType().hasLocalQualifiers()) return false;
273  return TSTChecker().Visit(TL);
274 }
275 
276 // Reimplemented to account for GNU/C++ extension
277 // typeof unary-expression
278 // where there are no parentheses.
280  if (getRParenLoc().isValid())
281  return SourceRange(getTypeofLoc(), getRParenLoc());
282  else
283  return SourceRange(getTypeofLoc(),
284  getUnderlyingExpr()->getSourceRange().getEnd());
285 }
286 
287 
289  if (needsExtraLocalData())
290  return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
291  switch (getTypePtr()->getKind()) {
292  case BuiltinType::Void:
293  return TST_void;
294  case BuiltinType::Bool:
295  return TST_bool;
296  case BuiltinType::Char_U:
297  case BuiltinType::Char_S:
298  return TST_char;
299  case BuiltinType::Char16:
300  return TST_char16;
301  case BuiltinType::Char32:
302  return TST_char32;
303  case BuiltinType::WChar_S:
304  case BuiltinType::WChar_U:
305  return TST_wchar;
306  case BuiltinType::UChar:
307  case BuiltinType::UShort:
308  case BuiltinType::UInt:
309  case BuiltinType::ULong:
310  case BuiltinType::ULongLong:
311  case BuiltinType::UInt128:
312  case BuiltinType::SChar:
313  case BuiltinType::Short:
314  case BuiltinType::Int:
315  case BuiltinType::Long:
316  case BuiltinType::LongLong:
317  case BuiltinType::Int128:
318  case BuiltinType::Half:
319  case BuiltinType::Float:
320  case BuiltinType::Double:
321  case BuiltinType::LongDouble:
322  case BuiltinType::Float16:
323  case BuiltinType::Float128:
324  llvm_unreachable("Builtin type needs extra local data!");
325  // Fall through, if the impossible happens.
326 
327  case BuiltinType::NullPtr:
328  case BuiltinType::Overload:
329  case BuiltinType::Dependent:
330  case BuiltinType::BoundMember:
331  case BuiltinType::UnknownAny:
332  case BuiltinType::ARCUnbridgedCast:
333  case BuiltinType::PseudoObject:
334  case BuiltinType::ObjCId:
335  case BuiltinType::ObjCClass:
336  case BuiltinType::ObjCSel:
337 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
338  case BuiltinType::Id:
339 #include "clang/Basic/OpenCLImageTypes.def"
340  case BuiltinType::OCLSampler:
341  case BuiltinType::OCLEvent:
342  case BuiltinType::OCLClkEvent:
343  case BuiltinType::OCLQueue:
344  case BuiltinType::OCLReserveID:
345  case BuiltinType::BuiltinFn:
346  case BuiltinType::OMPArraySection:
347  return TST_unspecified;
348  }
349 
350  llvm_unreachable("Invalid BuiltinType Kind!");
351 }
352 
353 TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
354  while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
355  TL = PTL.getInnerLoc();
356  return TL;
357 }
358 
360  if (auto attributedLoc = getAs<AttributedTypeLoc>()) {
361  if (attributedLoc.getAttrKind() == AttributedType::attr_nullable ||
362  attributedLoc.getAttrKind() == AttributedType::attr_nonnull ||
363  attributedLoc.getAttrKind() == AttributedType::attr_null_unspecified)
364  return attributedLoc.getAttrNameLoc();
365  }
366 
367  return SourceLocation();
368 }
369 
371  // Qualified types.
372  if (auto qual = getAs<QualifiedTypeLoc>())
373  return qual;
374 
375  TypeLoc loc = IgnoreParens();
376 
377  // Attributed types.
378  if (auto attr = loc.getAs<AttributedTypeLoc>()) {
379  if (attr.isQualifier()) return attr;
380  return attr.getModifiedLoc().findExplicitQualifierLoc();
381  }
382 
383  // C11 _Atomic types.
384  if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
385  return atomic;
386  }
387 
388  return TypeLoc();
389 }
390 
392  SourceLocation Loc) {
393  setNameLoc(Loc);
394  if (!getNumProtocols()) return;
395 
396  setProtocolLAngleLoc(Loc);
397  setProtocolRAngleLoc(Loc);
398  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
399  setProtocolLoc(i, Loc);
400 }
401 
403  SourceLocation Loc) {
404  setHasBaseTypeAsWritten(true);
405  setTypeArgsLAngleLoc(Loc);
406  setTypeArgsRAngleLoc(Loc);
407  for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
408  setTypeArgTInfo(i,
409  Context.getTrivialTypeSourceInfo(
410  getTypePtr()->getTypeArgsAsWritten()[i], Loc));
411  }
412  setProtocolLAngleLoc(Loc);
413  setProtocolRAngleLoc(Loc);
414  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
415  setProtocolLoc(i, Loc);
416 }
417 
419  SourceLocation Loc) {
421  ::initializeLocal(Context, Loc);
422  this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo(
423  getUnderlyingType(), Loc);
424 }
425 
427  SourceLocation Loc) {
428  setElaboratedKeywordLoc(Loc);
430  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
431  setQualifierLoc(Builder.getWithLocInContext(Context));
432 }
433 
435  SourceLocation Loc) {
436  setElaboratedKeywordLoc(Loc);
438  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
439  setQualifierLoc(Builder.getWithLocInContext(Context));
440  setNameLoc(Loc);
441 }
442 
443 void
445  SourceLocation Loc) {
446  setElaboratedKeywordLoc(Loc);
447  if (getTypePtr()->getQualifier()) {
449  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
450  setQualifierLoc(Builder.getWithLocInContext(Context));
451  } else {
452  setQualifierLoc(NestedNameSpecifierLoc());
453  }
454  setTemplateKeywordLoc(Loc);
455  setTemplateNameLoc(Loc);
456  setLAngleLoc(Loc);
457  setRAngleLoc(Loc);
459  getTypePtr()->getArgs(),
460  getArgInfos(), Loc);
461 }
462 
464  unsigned NumArgs,
465  const TemplateArgument *Args,
466  TemplateArgumentLocInfo *ArgInfos,
467  SourceLocation Loc) {
468  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
469  switch (Args[i].getKind()) {
471  llvm_unreachable("Impossible TemplateArgument");
472 
476  ArgInfos[i] = TemplateArgumentLocInfo();
477  break;
478 
480  ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
481  break;
482 
484  ArgInfos[i] = TemplateArgumentLocInfo(
485  Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
486  Loc));
487  break;
488 
492  TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
494  Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
495  else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
496  Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
497 
498  ArgInfos[i] = TemplateArgumentLocInfo(
499  Builder.getWithLocInContext(Context), Loc,
501  : Loc);
502  break;
503  }
504 
506  ArgInfos[i] = TemplateArgumentLocInfo();
507  break;
508  }
509  }
510 }
Defines the clang::ASTContext interface.
static unsigned getFullDataSizeForType(QualType Ty)
Returns the size of type source info data block for the given type.
Definition: TypeLoc.cpp:75
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.h:1820
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:480
A (possibly-)qualified type.
Definition: Type.h:614
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
TypeLoc getNextTypeLoc() const
Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the TypeLoc is a PointerLoc and next Typ...
Definition: TypeLoc.h:152
The template argument is an expression, and we&#39;ve not resolved it to one of the other forms yet...
Definition: TemplateBase.h:69
RetTy Visit(TypeLoc TyLoc)
The template argument is a declaration that was provided for a pointer, reference, or pointer to member non-type template parameter.
Definition: TemplateBase.h:51
SourceLocation getEndLoc() const
Get the end source location.
Definition: TypeLoc.cpp:206
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.cpp:444
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:46
TypeSpecifierType
Specifies the kind of type.
Definition: Specifiers.h:45
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
void * Data
Definition: TypeLoc.h:45
A reasonable base class for TypeLocs that correspond to types that are written as a type-specifier...
Definition: TypeLoc.h:492
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:40
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
A C++ nested-name-specifier augmented with source location information.
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:417
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:57
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.cpp:426
bool isNull() const
Definition: TypeLoc.h:102
SourceLocation findNullabilityLoc() const
Find the location of the nullability specifier (__nonnull, __nullable, or __null_unspecifier), if there is one.
Definition: TypeLoc.cpp:359
Class that aids in the construction of nested-name-specifiers along with source-location information ...
SourceRange getLocalSourceRange() const
Get the local source range.
Definition: TypeLoc.h:141
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:169
Type source information for an attributed type.
Definition: TypeLoc.h:827
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:54
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:64
Represents a C++ template name within the type system.
Definition: TemplateName.h:176
Defines the clang::TypeLoc interface and its subclasses.
SourceLocation getEnd() const
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.cpp:418
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:681
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Definition: opencl-c.h:82
bool hasTrailingReturn() const
Definition: Type.h:3507
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.cpp:391
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.cpp:434
Encodes a location in the source.
void initializeLocal(ASTContext &Context, SourceLocation Loc)
Definition: TypeLoc.cpp:402
static QualType getUnderlyingType(const SubRegion *R)
static const unsigned TypeLocMaxDataAlign
Definition: TypeLoc.cpp:21
TypeLoc findExplicitQualifierLoc() const
Find a type with the location of an explicit type qualifier.
Definition: TypeLoc.cpp:370
unsigned getFullDataSize() const
Returns the size of the type source info data block.
Definition: TypeLoc.h:146
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Represents a template argument.
Definition: TemplateBase.h:40
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:360
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition: TypeLoc.h:114
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:63
SourceRange getSourceRange(const SourceRange &Range)
Returns the SourceRange of a SourceRange.
Definition: FixIt.h:34
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Definition: Type.h:718
SourceRange getLocalSourceRange() const
Definition: TypeLoc.cpp:279
static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, const TemplateArgument *Args, TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc)
Definition: TypeLoc.cpp:463
TypeLocClass getTypeLocClass() const
Definition: TypeLoc.h:97
The template argument is a type.
Definition: TemplateBase.h:48
The template argument is actually a parameter pack.
Definition: TemplateBase.h:72
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:213
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
The template argument is a template name that was provided for a template template parameter...
Definition: TemplateBase.h:60
static unsigned getLocalAlignmentForType(QualType Ty)
Returns the alignment of type source info data block for the given type.
Definition: TypeLoc.cpp:57
Location information for a TemplateArgument.
Definition: TemplateBase.h:369
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:896
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:235
void copy(TypeLoc other)
Copies the other type loc into this one.
Definition: TypeLoc.cpp:145
TypeSpecifierType getWrittenTypeSpec() const
Definition: TypeLoc.cpp:288
A trivial tuple used to represent a source range.
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type...
Definition: TypeLoc.h:53
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion, return the pattern as a template name.
Definition: TemplateBase.h:266
SourceLocation getBegin() const