1327952Sdim//===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//
2198092Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6198092Srdivacky//
7198092Srdivacky//===----------------------------------------------------------------------===//
8198092Srdivacky//
9198092Srdivacky//  This file defines the TypeLoc subclasses implementations.
10198092Srdivacky//
11198092Srdivacky//===----------------------------------------------------------------------===//
12198092Srdivacky
13249423Sdim#include "clang/AST/TypeLoc.h"
14360784Sdim#include "clang/AST/DeclTemplate.h"
15239462Sdim#include "clang/AST/ASTContext.h"
16360784Sdim#include "clang/AST/Attr.h"
17202379Srdivacky#include "clang/AST/Expr.h"
18327952Sdim#include "clang/AST/NestedNameSpecifier.h"
19327952Sdim#include "clang/AST/TemplateBase.h"
20327952Sdim#include "clang/AST/TemplateName.h"
21249423Sdim#include "clang/AST/TypeLocVisitor.h"
22327952Sdim#include "clang/Basic/SourceLocation.h"
23327952Sdim#include "clang/Basic/Specifiers.h"
24202879Srdivacky#include "llvm/Support/ErrorHandling.h"
25327952Sdim#include "llvm/Support/MathExtras.h"
26327952Sdim#include <algorithm>
27327952Sdim#include <cassert>
28327952Sdim#include <cstdint>
29327952Sdim#include <cstring>
30327952Sdim
31198092Srdivackyusing namespace clang;
32198092Srdivacky
33314564Sdimstatic const unsigned TypeLocMaxDataAlign = alignof(void *);
34288943Sdim
35198092Srdivacky//===----------------------------------------------------------------------===//
36198092Srdivacky// TypeLoc Implementation
37198092Srdivacky//===----------------------------------------------------------------------===//
38198092Srdivacky
39198092Srdivackynamespace {
40327952Sdim
41327952Sdimclass TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
42327952Sdimpublic:
43198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
44198112Srdivacky#define TYPELOC(CLASS, PARENT) \
45327952Sdim  SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
46327952Sdim    return TyLoc.getLocalSourceRange(); \
47327952Sdim  }
48198092Srdivacky#include "clang/AST/TypeLocNodes.def"
49327952Sdim};
50198092Srdivacky
51327952Sdim} // namespace
52327952Sdim
53208600SrdivackySourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
54198398Srdivacky  if (TL.isNull()) return SourceRange();
55198398Srdivacky  return TypeLocRanger().Visit(TL);
56198092Srdivacky}
57198092Srdivacky
58198092Srdivackynamespace {
59327952Sdim
60327952Sdimclass TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
61327952Sdimpublic:
62261991Sdim#define ABSTRACT_TYPELOC(CLASS, PARENT)
63261991Sdim#define TYPELOC(CLASS, PARENT) \
64327952Sdim  unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
65327952Sdim    return TyLoc.getLocalDataAlignment(); \
66327952Sdim  }
67261991Sdim#include "clang/AST/TypeLocNodes.def"
68327952Sdim};
69261991Sdim
70327952Sdim} // namespace
71327952Sdim
72341825Sdim/// Returns the alignment of the type source info data block.
73261991Sdimunsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
74261991Sdim  if (Ty.isNull()) return 1;
75276479Sdim  return TypeAligner().Visit(TypeLoc(Ty, nullptr));
76261991Sdim}
77261991Sdim
78261991Sdimnamespace {
79327952Sdim
80327952Sdimclass TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
81327952Sdimpublic:
82198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
83198112Srdivacky#define TYPELOC(CLASS, PARENT) \
84327952Sdim  unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
85327952Sdim    return TyLoc.getLocalDataSize(); \
86327952Sdim  }
87198092Srdivacky#include "clang/AST/TypeLocNodes.def"
88327952Sdim};
89198092Srdivacky
90327952Sdim} // namespace
91327952Sdim
92341825Sdim/// Returns the size of the type source info data block.
93198112Srdivackyunsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
94261991Sdim  unsigned Total = 0;
95276479Sdim  TypeLoc TyLoc(Ty, nullptr);
96261991Sdim  unsigned MaxAlign = 1;
97261991Sdim  while (!TyLoc.isNull()) {
98261991Sdim    unsigned Align = getLocalAlignmentForType(TyLoc.getType());
99261991Sdim    MaxAlign = std::max(Align, MaxAlign);
100309124Sdim    Total = llvm::alignTo(Total, Align);
101261991Sdim    Total += TypeSizer().Visit(TyLoc);
102261991Sdim    TyLoc = TyLoc.getNextTypeLoc();
103261991Sdim  }
104309124Sdim  Total = llvm::alignTo(Total, MaxAlign);
105261991Sdim  return Total;
106198092Srdivacky}
107198092Srdivacky
108198092Srdivackynamespace {
109327952Sdim
110327952Sdimclass NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
111327952Sdimpublic:
112198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
113198398Srdivacky#define TYPELOC(CLASS, PARENT) \
114327952Sdim  TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
115327952Sdim    return TyLoc.getNextTypeLoc(); \
116327952Sdim  }
117198092Srdivacky#include "clang/AST/TypeLocNodes.def"
118327952Sdim};
119198092Srdivacky
120327952Sdim} // namespace
121327952Sdim
122341825Sdim/// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
123198092Srdivacky/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
124198398SrdivackyTypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
125198398Srdivacky  return NextLoc().Visit(TL);
126198092Srdivacky}
127198092Srdivacky
128341825Sdim/// Initializes a type location, and all of its children
129198398Srdivacky/// recursively, as if the entire tree had been written in the
130198398Srdivacky/// given location.
131341825Sdimvoid TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
132218893Sdim                             SourceLocation Loc) {
133208600Srdivacky  while (true) {
134208600Srdivacky    switch (TL.getTypeLocClass()) {
135208600Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
136208600Srdivacky#define TYPELOC(CLASS, PARENT)        \
137208600Srdivacky    case CLASS: {                     \
138249423Sdim      CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
139218893Sdim      TLCasted.initializeLocal(Context, Loc);  \
140208600Srdivacky      TL = TLCasted.getNextTypeLoc(); \
141208600Srdivacky      if (!TL) return;                \
142208600Srdivacky      continue;                       \
143208600Srdivacky    }
144208600Srdivacky#include "clang/AST/TypeLocNodes.def"
145208600Srdivacky    }
146208600Srdivacky  }
147198092Srdivacky}
148200583Srdivacky
149288943Sdimnamespace {
150288943Sdim
151327952Sdimclass TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
152327952Sdim  TypeLoc Source;
153327952Sdim
154327952Sdimpublic:
155327952Sdim  TypeLocCopier(TypeLoc source) : Source(source) {}
156327952Sdim
157288943Sdim#define ABSTRACT_TYPELOC(CLASS, PARENT)
158288943Sdim#define TYPELOC(CLASS, PARENT)                          \
159327952Sdim  void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \
160327952Sdim    dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \
161327952Sdim  }
162288943Sdim#include "clang/AST/TypeLocNodes.def"
163327952Sdim};
164288943Sdim
165327952Sdim} // namespace
166288943Sdim
167288943Sdimvoid TypeLoc::copy(TypeLoc other) {
168288943Sdim  assert(getFullDataSize() == other.getFullDataSize());
169288943Sdim
170288943Sdim  // If both data pointers are aligned to the maximum alignment, we
171288943Sdim  // can memcpy because getFullDataSize() accurately reflects the
172288943Sdim  // layout of the data.
173309124Sdim  if (reinterpret_cast<uintptr_t>(Data) ==
174309124Sdim          llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
175309124Sdim                        TypeLocMaxDataAlign) &&
176309124Sdim      reinterpret_cast<uintptr_t>(other.Data) ==
177309124Sdim          llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
178309124Sdim                        TypeLocMaxDataAlign)) {
179288943Sdim    memcpy(Data, other.Data, getFullDataSize());
180288943Sdim    return;
181288943Sdim  }
182288943Sdim
183288943Sdim  // Copy each of the pieces.
184288943Sdim  TypeLoc TL(getType(), Data);
185288943Sdim  do {
186288943Sdim    TypeLocCopier(other).Visit(TL);
187288943Sdim    other = other.getNextTypeLoc();
188288943Sdim  } while ((TL = TL.getNextTypeLoc()));
189288943Sdim}
190288943Sdim
191208600SrdivackySourceLocation TypeLoc::getBeginLoc() const {
192208600Srdivacky  TypeLoc Cur = *this;
193243830Sdim  TypeLoc LeftMost = Cur;
194208600Srdivacky  while (true) {
195208600Srdivacky    switch (Cur.getTypeLocClass()) {
196208600Srdivacky    case Elaborated:
197243830Sdim      LeftMost = Cur;
198208600Srdivacky      break;
199243830Sdim    case FunctionProto:
200249423Sdim      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
201249423Sdim              ->hasTrailingReturn()) {
202243830Sdim        LeftMost = Cur;
203243830Sdim        break;
204243830Sdim      }
205327952Sdim      LLVM_FALLTHROUGH;
206243830Sdim    case FunctionNoProto:
207243830Sdim    case ConstantArray:
208243830Sdim    case DependentSizedArray:
209243830Sdim    case IncompleteArray:
210243830Sdim    case VariableArray:
211243830Sdim      // FIXME: Currently QualifiedTypeLoc does not have a source range
212243830Sdim    case Qualified:
213243830Sdim      Cur = Cur.getNextTypeLoc();
214243830Sdim      continue;
215208600Srdivacky    default:
216296417Sdim      if (Cur.getLocalSourceRange().getBegin().isValid())
217243830Sdim        LeftMost = Cur;
218243830Sdim      Cur = Cur.getNextTypeLoc();
219243830Sdim      if (Cur.isNull())
220243830Sdim        break;
221208600Srdivacky      continue;
222243830Sdim    } // switch
223208600Srdivacky    break;
224243830Sdim  } // while
225243830Sdim  return LeftMost.getLocalSourceRange().getBegin();
226208600Srdivacky}
227208600Srdivacky
228208600SrdivackySourceLocation TypeLoc::getEndLoc() const {
229208600Srdivacky  TypeLoc Cur = *this;
230221345Sdim  TypeLoc Last;
231208600Srdivacky  while (true) {
232208600Srdivacky    switch (Cur.getTypeLocClass()) {
233208600Srdivacky    default:
234221345Sdim      if (!Last)
235314564Sdim        Last = Cur;
236221345Sdim      return Last.getLocalSourceRange().getEnd();
237221345Sdim    case Paren:
238221345Sdim    case ConstantArray:
239221345Sdim    case DependentSizedArray:
240221345Sdim    case IncompleteArray:
241221345Sdim    case VariableArray:
242221345Sdim    case FunctionNoProto:
243221345Sdim      Last = Cur;
244208600Srdivacky      break;
245243830Sdim    case FunctionProto:
246249423Sdim      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
247243830Sdim        Last = TypeLoc();
248243830Sdim      else
249243830Sdim        Last = Cur;
250243830Sdim      break;
251221345Sdim    case Pointer:
252221345Sdim    case BlockPointer:
253221345Sdim    case MemberPointer:
254221345Sdim    case LValueReference:
255221345Sdim    case RValueReference:
256221345Sdim    case PackExpansion:
257221345Sdim      if (!Last)
258341825Sdim        Last = Cur;
259221345Sdim      break;
260208600Srdivacky    case Qualified:
261208600Srdivacky    case Elaborated:
262221345Sdim      break;
263208600Srdivacky    }
264221345Sdim    Cur = Cur.getNextTypeLoc();
265208600Srdivacky  }
266208600Srdivacky}
267208600Srdivacky
268200583Srdivackynamespace {
269200583Srdivacky
270327952Sdimstruct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
271327952Sdim  // Overload resolution does the real work for us.
272327952Sdim  static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
273327952Sdim  static bool isTypeSpec(TypeLoc _) { return false; }
274327952Sdim
275200583Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
276200583Srdivacky#define TYPELOC(CLASS, PARENT) \
277327952Sdim  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
278327952Sdim    return isTypeSpec(TyLoc); \
279327952Sdim  }
280200583Srdivacky#include "clang/AST/TypeLocNodes.def"
281327952Sdim};
282200583Srdivacky
283327952Sdim} // namespace
284200583Srdivacky
285341825Sdim/// Determines if the given type loc corresponds to a
286200583Srdivacky/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
287200583Srdivacky/// the type hierarchy, this is made somewhat complicated.
288200583Srdivacky///
289200583Srdivacky/// There are a lot of types that currently use TypeSpecTypeLoc
290200583Srdivacky/// because it's a convenient base class.  Ideally we would not accept
291200583Srdivacky/// those here, but ideally we would have better implementations for
292200583Srdivacky/// them.
293249423Sdimbool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
294249423Sdim  if (TL.getType().hasLocalQualifiers()) return false;
295249423Sdim  return TSTChecker().Visit(TL);
296200583Srdivacky}
297202379Srdivacky
298360784Sdimbool TagTypeLoc::isDefinition() const {
299360784Sdim  TagDecl *D = getDecl();
300360784Sdim  return D->isCompleteDefinition() &&
301360784Sdim         (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
302360784Sdim}
303360784Sdim
304202379Srdivacky// Reimplemented to account for GNU/C++ extension
305202379Srdivacky//     typeof unary-expression
306202379Srdivacky// where there are no parentheses.
307208600SrdivackySourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
308202379Srdivacky  if (getRParenLoc().isValid())
309202379Srdivacky    return SourceRange(getTypeofLoc(), getRParenLoc());
310202379Srdivacky  else
311202379Srdivacky    return SourceRange(getTypeofLoc(),
312202379Srdivacky                       getUnderlyingExpr()->getSourceRange().getEnd());
313202379Srdivacky}
314202879Srdivacky
315202879Srdivacky
316202879SrdivackyTypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
317202879Srdivacky  if (needsExtraLocalData())
318202879Srdivacky    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
319234353Sdim  switch (getTypePtr()->getKind()) {
320234353Sdim  case BuiltinType::Void:
321234353Sdim    return TST_void;
322234353Sdim  case BuiltinType::Bool:
323234353Sdim    return TST_bool;
324234353Sdim  case BuiltinType::Char_U:
325234353Sdim  case BuiltinType::Char_S:
326234353Sdim    return TST_char;
327341825Sdim  case BuiltinType::Char8:
328341825Sdim    return TST_char8;
329234353Sdim  case BuiltinType::Char16:
330234353Sdim    return TST_char16;
331234353Sdim  case BuiltinType::Char32:
332234353Sdim    return TST_char32;
333234353Sdim  case BuiltinType::WChar_S:
334234353Sdim  case BuiltinType::WChar_U:
335234353Sdim    return TST_wchar;
336234353Sdim  case BuiltinType::UChar:
337234353Sdim  case BuiltinType::UShort:
338234353Sdim  case BuiltinType::UInt:
339234353Sdim  case BuiltinType::ULong:
340234353Sdim  case BuiltinType::ULongLong:
341234353Sdim  case BuiltinType::UInt128:
342234353Sdim  case BuiltinType::SChar:
343234353Sdim  case BuiltinType::Short:
344234353Sdim  case BuiltinType::Int:
345234353Sdim  case BuiltinType::Long:
346234353Sdim  case BuiltinType::LongLong:
347234353Sdim  case BuiltinType::Int128:
348234353Sdim  case BuiltinType::Half:
349234353Sdim  case BuiltinType::Float:
350234353Sdim  case BuiltinType::Double:
351234353Sdim  case BuiltinType::LongDouble:
352327952Sdim  case BuiltinType::Float16:
353309124Sdim  case BuiltinType::Float128:
354341825Sdim  case BuiltinType::ShortAccum:
355341825Sdim  case BuiltinType::Accum:
356341825Sdim  case BuiltinType::LongAccum:
357341825Sdim  case BuiltinType::UShortAccum:
358341825Sdim  case BuiltinType::UAccum:
359341825Sdim  case BuiltinType::ULongAccum:
360341825Sdim  case BuiltinType::ShortFract:
361341825Sdim  case BuiltinType::Fract:
362341825Sdim  case BuiltinType::LongFract:
363341825Sdim  case BuiltinType::UShortFract:
364341825Sdim  case BuiltinType::UFract:
365341825Sdim  case BuiltinType::ULongFract:
366341825Sdim  case BuiltinType::SatShortAccum:
367341825Sdim  case BuiltinType::SatAccum:
368341825Sdim  case BuiltinType::SatLongAccum:
369341825Sdim  case BuiltinType::SatUShortAccum:
370341825Sdim  case BuiltinType::SatUAccum:
371341825Sdim  case BuiltinType::SatULongAccum:
372341825Sdim  case BuiltinType::SatShortFract:
373341825Sdim  case BuiltinType::SatFract:
374341825Sdim  case BuiltinType::SatLongFract:
375341825Sdim  case BuiltinType::SatUShortFract:
376341825Sdim  case BuiltinType::SatUFract:
377341825Sdim  case BuiltinType::SatULongFract:
378234353Sdim    llvm_unreachable("Builtin type needs extra local data!");
379234353Sdim    // Fall through, if the impossible happens.
380341825Sdim
381234353Sdim  case BuiltinType::NullPtr:
382234353Sdim  case BuiltinType::Overload:
383234353Sdim  case BuiltinType::Dependent:
384234353Sdim  case BuiltinType::BoundMember:
385234353Sdim  case BuiltinType::UnknownAny:
386234353Sdim  case BuiltinType::ARCUnbridgedCast:
387234353Sdim  case BuiltinType::PseudoObject:
388234353Sdim  case BuiltinType::ObjCId:
389234353Sdim  case BuiltinType::ObjCClass:
390234353Sdim  case BuiltinType::ObjCSel:
391309124Sdim#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
392309124Sdim  case BuiltinType::Id:
393309124Sdim#include "clang/Basic/OpenCLImageTypes.def"
394344779Sdim#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
395344779Sdim  case BuiltinType::Id:
396344779Sdim#include "clang/Basic/OpenCLExtensionTypes.def"
397249423Sdim  case BuiltinType::OCLSampler:
398249423Sdim  case BuiltinType::OCLEvent:
399296417Sdim  case BuiltinType::OCLClkEvent:
400296417Sdim  case BuiltinType::OCLQueue:
401296417Sdim  case BuiltinType::OCLReserveID:
402360784Sdim#define SVE_TYPE(Name, Id, SingletonId) \
403360784Sdim  case BuiltinType::Id:
404360784Sdim#include "clang/Basic/AArch64SVEACLETypes.def"
405243830Sdim  case BuiltinType::BuiltinFn:
406296417Sdim  case BuiltinType::OMPArraySection:
407234353Sdim    return TST_unspecified;
408234353Sdim  }
409218893Sdim
410234353Sdim  llvm_unreachable("Invalid BuiltinType Kind!");
411202879Srdivacky}
412218893Sdim
413218893SdimTypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
414249423Sdim  while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
415249423Sdim    TL = PTL.getInnerLoc();
416218893Sdim  return TL;
417218893Sdim}
418218893Sdim
419288943SdimSourceLocation TypeLoc::findNullabilityLoc() const {
420344779Sdim  if (auto ATL = getAs<AttributedTypeLoc>()) {
421344779Sdim    const Attr *A = ATL.getAttr();
422344779Sdim    if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||
423344779Sdim              isa<TypeNullUnspecifiedAttr>(A)))
424344779Sdim      return A->getLocation();
425288943Sdim  }
426288943Sdim
427327952Sdim  return {};
428288943Sdim}
429288943Sdim
430296417SdimTypeLoc TypeLoc::findExplicitQualifierLoc() const {
431296417Sdim  // Qualified types.
432296417Sdim  if (auto qual = getAs<QualifiedTypeLoc>())
433296417Sdim    return qual;
434296417Sdim
435296417Sdim  TypeLoc loc = IgnoreParens();
436296417Sdim
437296417Sdim  // Attributed types.
438296417Sdim  if (auto attr = loc.getAs<AttributedTypeLoc>()) {
439296417Sdim    if (attr.isQualifier()) return attr;
440296417Sdim    return attr.getModifiedLoc().findExplicitQualifierLoc();
441296417Sdim  }
442296417Sdim
443296417Sdim  // C11 _Atomic types.
444296417Sdim  if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
445296417Sdim    return atomic;
446296417Sdim  }
447296417Sdim
448327952Sdim  return {};
449296417Sdim}
450296417Sdim
451314564Sdimvoid ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
452314564Sdim                                           SourceLocation Loc) {
453314564Sdim  setNameLoc(Loc);
454314564Sdim  if (!getNumProtocols()) return;
455314564Sdim
456314564Sdim  setProtocolLAngleLoc(Loc);
457314564Sdim  setProtocolRAngleLoc(Loc);
458314564Sdim  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
459314564Sdim    setProtocolLoc(i, Loc);
460314564Sdim}
461314564Sdim
462341825Sdimvoid ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
463288943Sdim                                        SourceLocation Loc) {
464288943Sdim  setHasBaseTypeAsWritten(true);
465288943Sdim  setTypeArgsLAngleLoc(Loc);
466288943Sdim  setTypeArgsRAngleLoc(Loc);
467288943Sdim  for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
468341825Sdim    setTypeArgTInfo(i,
469288943Sdim                   Context.getTrivialTypeSourceInfo(
470288943Sdim                     getTypePtr()->getTypeArgsAsWritten()[i], Loc));
471288943Sdim  }
472288943Sdim  setProtocolLAngleLoc(Loc);
473288943Sdim  setProtocolRAngleLoc(Loc);
474288943Sdim  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
475288943Sdim    setProtocolLoc(i, Loc);
476288943Sdim}
477288943Sdim
478360784SdimSourceRange AttributedTypeLoc::getLocalSourceRange() const {
479360784Sdim  // Note that this does *not* include the range of the attribute
480360784Sdim  // enclosure, e.g.:
481360784Sdim  //    __attribute__((foo(bar)))
482360784Sdim  //    ^~~~~~~~~~~~~~~        ~~
483360784Sdim  // or
484360784Sdim  //    [[foo(bar)]]
485360784Sdim  //    ^~        ~~
486360784Sdim  // That enclosure doesn't necessarily belong to a single attribute
487360784Sdim  // anyway.
488360784Sdim  return getAttr() ? getAttr()->getRange() : SourceRange();
489360784Sdim}
490360784Sdim
491280031Sdimvoid TypeOfTypeLoc::initializeLocal(ASTContext &Context,
492280031Sdim                                       SourceLocation Loc) {
493280031Sdim  TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
494280031Sdim      ::initializeLocal(Context, Loc);
495280031Sdim  this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo(
496280031Sdim      getUnderlyingType(), Loc);
497280031Sdim}
498280031Sdim
499327952Sdimvoid UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,
500327952Sdim                                       SourceLocation Loc) {
501327952Sdim    setKWLoc(Loc);
502327952Sdim    setRParenLoc(Loc);
503327952Sdim    setLParenLoc(Loc);
504327952Sdim    this->setUnderlyingTInfo(
505327952Sdim        Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));
506327952Sdim}
507327952Sdim
508341825Sdimvoid ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
509221345Sdim                                        SourceLocation Loc) {
510234353Sdim  setElaboratedKeywordLoc(Loc);
511221345Sdim  NestedNameSpecifierLocBuilder Builder;
512221345Sdim  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
513221345Sdim  setQualifierLoc(Builder.getWithLocInContext(Context));
514221345Sdim}
515221345Sdim
516341825Sdimvoid DependentNameTypeLoc::initializeLocal(ASTContext &Context,
517221345Sdim                                           SourceLocation Loc) {
518234353Sdim  setElaboratedKeywordLoc(Loc);
519221345Sdim  NestedNameSpecifierLocBuilder Builder;
520221345Sdim  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
521221345Sdim  setQualifierLoc(Builder.getWithLocInContext(Context));
522221345Sdim  setNameLoc(Loc);
523221345Sdim}
524221345Sdim
525234353Sdimvoid
526234353SdimDependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
527221345Sdim                                                        SourceLocation Loc) {
528234353Sdim  setElaboratedKeywordLoc(Loc);
529221345Sdim  if (getTypePtr()->getQualifier()) {
530221345Sdim    NestedNameSpecifierLocBuilder Builder;
531221345Sdim    Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
532221345Sdim    setQualifierLoc(Builder.getWithLocInContext(Context));
533221345Sdim  } else {
534221345Sdim    setQualifierLoc(NestedNameSpecifierLoc());
535221345Sdim  }
536234353Sdim  setTemplateKeywordLoc(Loc);
537234353Sdim  setTemplateNameLoc(Loc);
538221345Sdim  setLAngleLoc(Loc);
539221345Sdim  setRAngleLoc(Loc);
540221345Sdim  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
541221345Sdim                                                   getTypePtr()->getArgs(),
542221345Sdim                                                   getArgInfos(), Loc);
543221345Sdim}
544221345Sdim
545341825Sdimvoid TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
546218893Sdim                                                      unsigned NumArgs,
547218893Sdim                                                  const TemplateArgument *Args,
548218893Sdim                                              TemplateArgumentLocInfo *ArgInfos,
549218893Sdim                                                      SourceLocation Loc) {
550218893Sdim  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
551218893Sdim    switch (Args[i].getKind()) {
552341825Sdim    case TemplateArgument::Null:
553261991Sdim      llvm_unreachable("Impossible TemplateArgument");
554261991Sdim
555261991Sdim    case TemplateArgument::Integral:
556218893Sdim    case TemplateArgument::Declaration:
557243830Sdim    case TemplateArgument::NullPtr:
558261991Sdim      ArgInfos[i] = TemplateArgumentLocInfo();
559261991Sdim      break;
560243830Sdim
561218893Sdim    case TemplateArgument::Expression:
562234353Sdim      ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
563218893Sdim      break;
564341825Sdim
565218893Sdim    case TemplateArgument::Type:
566218893Sdim      ArgInfos[i] = TemplateArgumentLocInfo(
567341825Sdim                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
568218893Sdim                                                           Loc));
569218893Sdim      break;
570243830Sdim
571218893Sdim    case TemplateArgument::Template:
572221345Sdim    case TemplateArgument::TemplateExpansion: {
573221345Sdim      NestedNameSpecifierLocBuilder Builder;
574261991Sdim      TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
575221345Sdim      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
576221345Sdim        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
577221345Sdim      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
578221345Sdim        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
579261991Sdim
580221345Sdim      ArgInfos[i] = TemplateArgumentLocInfo(
581261991Sdim          Builder.getWithLocInContext(Context), Loc,
582261991Sdim          Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
583261991Sdim                                                          : Loc);
584218893Sdim      break;
585218893Sdim    }
586243830Sdim
587243830Sdim    case TemplateArgument::Pack:
588243830Sdim      ArgInfos[i] = TemplateArgumentLocInfo();
589243830Sdim      break;
590243830Sdim    }
591218893Sdim  }
592218893Sdim}
593360784Sdim
594360784SdimDeclarationNameInfo AutoTypeLoc::getConceptNameInfo() const {
595360784Sdim  return DeclarationNameInfo(getNamedConcept()->getDeclName(),
596360784Sdim                             getLocalData()->ConceptNameLoc);
597360784Sdim}
598360784Sdim
599360784Sdimvoid AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
600360784Sdim  setNestedNameSpecifierLoc(NestedNameSpecifierLoc());
601360784Sdim  setTemplateKWLoc(Loc);
602360784Sdim  setConceptNameLoc(Loc);
603360784Sdim  setFoundDecl(nullptr);
604360784Sdim  setRAngleLoc(Loc);
605360784Sdim  setLAngleLoc(Loc);
606360784Sdim  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
607360784Sdim                                                   getTypePtr()->getArgs(),
608360784Sdim                                                   getArgInfos(), Loc);
609360784Sdim  setNameLoc(Loc);
610360784Sdim}
611360784Sdim
612360784Sdim
613360784Sdimnamespace {
614360784Sdim
615360784Sdim  class GetContainedAutoTypeLocVisitor :
616360784Sdim    public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> {
617360784Sdim  public:
618360784Sdim    using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit;
619360784Sdim
620360784Sdim    TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) {
621360784Sdim      return TL;
622360784Sdim    }
623360784Sdim
624360784Sdim    // Only these types can contain the desired 'auto' type.
625360784Sdim
626360784Sdim    TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) {
627360784Sdim      return Visit(T.getNamedTypeLoc());
628360784Sdim    }
629360784Sdim
630360784Sdim    TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {
631360784Sdim      return Visit(T.getUnqualifiedLoc());
632360784Sdim    }
633360784Sdim
634360784Sdim    TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) {
635360784Sdim      return Visit(T.getPointeeLoc());
636360784Sdim    }
637360784Sdim
638360784Sdim    TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
639360784Sdim      return Visit(T.getPointeeLoc());
640360784Sdim    }
641360784Sdim
642360784Sdim    TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) {
643360784Sdim      return Visit(T.getPointeeLoc());
644360784Sdim    }
645360784Sdim
646360784Sdim    TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
647360784Sdim      return Visit(T.getPointeeLoc());
648360784Sdim    }
649360784Sdim
650360784Sdim    TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) {
651360784Sdim      return Visit(T.getElementLoc());
652360784Sdim    }
653360784Sdim
654360784Sdim    TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) {
655360784Sdim      return Visit(T.getReturnLoc());
656360784Sdim    }
657360784Sdim
658360784Sdim    TypeLoc VisitParenTypeLoc(ParenTypeLoc T) {
659360784Sdim      return Visit(T.getInnerLoc());
660360784Sdim    }
661360784Sdim
662360784Sdim    TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) {
663360784Sdim      return Visit(T.getModifiedLoc());
664360784Sdim    }
665360784Sdim
666360784Sdim    TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
667360784Sdim      return Visit(T.getInnerLoc());
668360784Sdim    }
669360784Sdim
670360784Sdim    TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) {
671360784Sdim      return Visit(T.getOriginalLoc());
672360784Sdim    }
673360784Sdim
674360784Sdim    TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) {
675360784Sdim      return Visit(T.getPatternLoc());
676360784Sdim    }
677360784Sdim  };
678360784Sdim
679360784Sdim} // namespace
680360784Sdim
681360784SdimAutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
682360784Sdim  TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this);
683360784Sdim  if (Res.isNull())
684360784Sdim    return AutoTypeLoc();
685360784Sdim  return Res.getAs<AutoTypeLoc>();
686360784Sdim}
687