xref: /freebsd/contrib/llvm-project/clang/lib/AST/TypeLoc.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file defines the TypeLoc subclasses implementations.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/TypeLoc.h"
14 #include "clang/AST/ASTConcept.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Attr.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/NestedNameSpecifier.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/TemplateName.h"
22 #include "clang/AST/TypeLocVisitor.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/MathExtras.h"
28 #include <algorithm>
29 #include <cassert>
30 #include <cstdint>
31 #include <cstring>
32 
33 using namespace clang;
34 
35 static const unsigned TypeLocMaxDataAlign = alignof(void *);
36 
37 //===----------------------------------------------------------------------===//
38 // TypeLoc Implementation
39 //===----------------------------------------------------------------------===//
40 
41 namespace {
42 
43 class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
44 public:
45 #define ABSTRACT_TYPELOC(CLASS, PARENT)
46 #define TYPELOC(CLASS, PARENT) \
47   SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
48     return TyLoc.getLocalSourceRange(); \
49   }
50 #include "clang/AST/TypeLocNodes.def"
51 };
52 
53 } // namespace
54 
getLocalSourceRangeImpl(TypeLoc TL)55 SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
56   if (TL.isNull()) return SourceRange();
57   return TypeLocRanger().Visit(TL);
58 }
59 
60 namespace {
61 
62 class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
63 public:
64 #define ABSTRACT_TYPELOC(CLASS, PARENT)
65 #define TYPELOC(CLASS, PARENT) \
66   unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
67     return TyLoc.getLocalDataAlignment(); \
68   }
69 #include "clang/AST/TypeLocNodes.def"
70 };
71 
72 } // namespace
73 
74 /// Returns the alignment of the type source info data block.
getLocalAlignmentForType(QualType Ty)75 unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
76   if (Ty.isNull()) return 1;
77   return TypeAligner().Visit(TypeLoc(Ty, nullptr));
78 }
79 
80 namespace {
81 
82 class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
83 public:
84 #define ABSTRACT_TYPELOC(CLASS, PARENT)
85 #define TYPELOC(CLASS, PARENT) \
86   unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
87     return TyLoc.getLocalDataSize(); \
88   }
89 #include "clang/AST/TypeLocNodes.def"
90 };
91 
92 } // namespace
93 
94 /// Returns the size of the type source info data block.
getFullDataSizeForType(QualType Ty)95 unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
96   unsigned Total = 0;
97   TypeLoc TyLoc(Ty, nullptr);
98   unsigned MaxAlign = 1;
99   while (!TyLoc.isNull()) {
100     unsigned Align = getLocalAlignmentForType(TyLoc.getType());
101     MaxAlign = std::max(Align, MaxAlign);
102     Total = llvm::alignTo(Total, Align);
103     Total += TypeSizer().Visit(TyLoc);
104     TyLoc = TyLoc.getNextTypeLoc();
105   }
106   Total = llvm::alignTo(Total, MaxAlign);
107   return Total;
108 }
109 
110 namespace {
111 
112 class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
113 public:
114 #define ABSTRACT_TYPELOC(CLASS, PARENT)
115 #define TYPELOC(CLASS, PARENT) \
116   TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
117     return TyLoc.getNextTypeLoc(); \
118   }
119 #include "clang/AST/TypeLocNodes.def"
120 };
121 
122 } // namespace
123 
124 /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
125 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
getNextTypeLocImpl(TypeLoc TL)126 TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
127   return NextLoc().Visit(TL);
128 }
129 
130 /// Initializes a type location, and all of its children
131 /// recursively, as if the entire tree had been written in the
132 /// given location.
initializeImpl(ASTContext & Context,TypeLoc TL,SourceLocation Loc)133 void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
134                              SourceLocation Loc) {
135   while (true) {
136     switch (TL.getTypeLocClass()) {
137 #define ABSTRACT_TYPELOC(CLASS, PARENT)
138 #define TYPELOC(CLASS, PARENT)        \
139     case CLASS: {                     \
140       CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
141       TLCasted.initializeLocal(Context, Loc);  \
142       TL = TLCasted.getNextTypeLoc(); \
143       if (!TL) return;                \
144       continue;                       \
145     }
146 #include "clang/AST/TypeLocNodes.def"
147     }
148   }
149 }
150 
151 namespace {
152 
153 class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
154   TypeLoc Source;
155 
156 public:
TypeLocCopier(TypeLoc source)157   TypeLocCopier(TypeLoc source) : Source(source) {}
158 
159 #define ABSTRACT_TYPELOC(CLASS, PARENT)
160 #define TYPELOC(CLASS, PARENT)                          \
161   void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \
162     dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \
163   }
164 #include "clang/AST/TypeLocNodes.def"
165 };
166 
167 } // namespace
168 
copy(TypeLoc other)169 void TypeLoc::copy(TypeLoc other) {
170   assert(getFullDataSize() == other.getFullDataSize());
171 
172   // If both data pointers are aligned to the maximum alignment, we
173   // can memcpy because getFullDataSize() accurately reflects the
174   // layout of the data.
175   if (reinterpret_cast<uintptr_t>(Data) ==
176           llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
177                         TypeLocMaxDataAlign) &&
178       reinterpret_cast<uintptr_t>(other.Data) ==
179           llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
180                         TypeLocMaxDataAlign)) {
181     memcpy(Data, other.Data, getFullDataSize());
182     return;
183   }
184 
185   // Copy each of the pieces.
186   TypeLoc TL(getType(), Data);
187   do {
188     TypeLocCopier(other).Visit(TL);
189     other = other.getNextTypeLoc();
190   } while ((TL = TL.getNextTypeLoc()));
191 }
192 
getBeginLoc() const193 SourceLocation TypeLoc::getBeginLoc() const {
194   TypeLoc Cur = *this;
195   TypeLoc LeftMost = Cur;
196   while (true) {
197     switch (Cur.getTypeLocClass()) {
198     case Elaborated:
199       if (Cur.getLocalSourceRange().getBegin().isValid()) {
200         LeftMost = Cur;
201         break;
202       }
203       Cur = Cur.getNextTypeLoc();
204       if (Cur.isNull())
205         break;
206       continue;
207     case FunctionProto:
208       if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
209               ->hasTrailingReturn()) {
210         LeftMost = Cur;
211         break;
212       }
213       [[fallthrough]];
214     case FunctionNoProto:
215     case ConstantArray:
216     case DependentSizedArray:
217     case IncompleteArray:
218     case VariableArray:
219       // FIXME: Currently QualifiedTypeLoc does not have a source range
220     case Qualified:
221       Cur = Cur.getNextTypeLoc();
222       continue;
223     default:
224       if (Cur.getLocalSourceRange().getBegin().isValid())
225         LeftMost = Cur;
226       Cur = Cur.getNextTypeLoc();
227       if (Cur.isNull())
228         break;
229       continue;
230     } // switch
231     break;
232   } // while
233   return LeftMost.getLocalSourceRange().getBegin();
234 }
235 
getEndLoc() const236 SourceLocation TypeLoc::getEndLoc() const {
237   TypeLoc Cur = *this;
238   TypeLoc Last;
239   while (true) {
240     switch (Cur.getTypeLocClass()) {
241     default:
242       if (!Last)
243         Last = Cur;
244       return Last.getLocalSourceRange().getEnd();
245     case Paren:
246     case ConstantArray:
247     case DependentSizedArray:
248     case IncompleteArray:
249     case VariableArray:
250     case FunctionNoProto:
251       // The innermost type with suffix syntax always determines the end of the
252       // type.
253       Last = Cur;
254       break;
255     case FunctionProto:
256       if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
257         Last = TypeLoc();
258       else
259         Last = Cur;
260       break;
261     case ObjCObjectPointer:
262       // `id` and `id<...>` have no star location.
263       if (Cur.castAs<ObjCObjectPointerTypeLoc>().getStarLoc().isInvalid())
264         break;
265       [[fallthrough]];
266     case Pointer:
267     case BlockPointer:
268     case MemberPointer:
269     case LValueReference:
270     case RValueReference:
271     case PackExpansion:
272       // Types with prefix syntax only determine the end of the type if there
273       // is no suffix type.
274       if (!Last)
275         Last = Cur;
276       break;
277     case Qualified:
278     case Elaborated:
279       break;
280     }
281     Cur = Cur.getNextTypeLoc();
282   }
283 }
284 
285 namespace {
286 
287 struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
288   // Overload resolution does the real work for us.
isTypeSpec__anon350557f10611::TSTChecker289   static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
isTypeSpec__anon350557f10611::TSTChecker290   static bool isTypeSpec(TypeLoc _) { return false; }
291 
292 #define ABSTRACT_TYPELOC(CLASS, PARENT)
293 #define TYPELOC(CLASS, PARENT) \
294   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
295     return isTypeSpec(TyLoc); \
296   }
297 #include "clang/AST/TypeLocNodes.def"
298 };
299 
300 } // namespace
301 
302 /// Determines if the given type loc corresponds to a
303 /// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
304 /// the type hierarchy, this is made somewhat complicated.
305 ///
306 /// There are a lot of types that currently use TypeSpecTypeLoc
307 /// because it's a convenient base class.  Ideally we would not accept
308 /// those here, but ideally we would have better implementations for
309 /// them.
isKind(const TypeLoc & TL)310 bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
311   if (TL.getType().hasLocalQualifiers()) return false;
312   return TSTChecker().Visit(TL);
313 }
314 
isDefinition() const315 bool TagTypeLoc::isDefinition() const {
316   TagDecl *D = getDecl();
317   return D->isCompleteDefinition() &&
318          (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
319 }
320 
321 // Reimplemented to account for GNU/C++ extension
322 //     typeof unary-expression
323 // where there are no parentheses.
getLocalSourceRange() const324 SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
325   if (getRParenLoc().isValid())
326     return SourceRange(getTypeofLoc(), getRParenLoc());
327   else
328     return SourceRange(getTypeofLoc(),
329                        getUnderlyingExpr()->getSourceRange().getEnd());
330 }
331 
332 
getWrittenTypeSpec() const333 TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
334   if (needsExtraLocalData())
335     return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
336   switch (getTypePtr()->getKind()) {
337   case BuiltinType::Void:
338     return TST_void;
339   case BuiltinType::Bool:
340     return TST_bool;
341   case BuiltinType::Char_U:
342   case BuiltinType::Char_S:
343     return TST_char;
344   case BuiltinType::Char8:
345     return TST_char8;
346   case BuiltinType::Char16:
347     return TST_char16;
348   case BuiltinType::Char32:
349     return TST_char32;
350   case BuiltinType::WChar_S:
351   case BuiltinType::WChar_U:
352     return TST_wchar;
353   case BuiltinType::UChar:
354   case BuiltinType::UShort:
355   case BuiltinType::UInt:
356   case BuiltinType::ULong:
357   case BuiltinType::ULongLong:
358   case BuiltinType::UInt128:
359   case BuiltinType::SChar:
360   case BuiltinType::Short:
361   case BuiltinType::Int:
362   case BuiltinType::Long:
363   case BuiltinType::LongLong:
364   case BuiltinType::Int128:
365   case BuiltinType::Half:
366   case BuiltinType::Float:
367   case BuiltinType::Double:
368   case BuiltinType::LongDouble:
369   case BuiltinType::Float16:
370   case BuiltinType::Float128:
371   case BuiltinType::Ibm128:
372   case BuiltinType::ShortAccum:
373   case BuiltinType::Accum:
374   case BuiltinType::LongAccum:
375   case BuiltinType::UShortAccum:
376   case BuiltinType::UAccum:
377   case BuiltinType::ULongAccum:
378   case BuiltinType::ShortFract:
379   case BuiltinType::Fract:
380   case BuiltinType::LongFract:
381   case BuiltinType::UShortFract:
382   case BuiltinType::UFract:
383   case BuiltinType::ULongFract:
384   case BuiltinType::SatShortAccum:
385   case BuiltinType::SatAccum:
386   case BuiltinType::SatLongAccum:
387   case BuiltinType::SatUShortAccum:
388   case BuiltinType::SatUAccum:
389   case BuiltinType::SatULongAccum:
390   case BuiltinType::SatShortFract:
391   case BuiltinType::SatFract:
392   case BuiltinType::SatLongFract:
393   case BuiltinType::SatUShortFract:
394   case BuiltinType::SatUFract:
395   case BuiltinType::SatULongFract:
396   case BuiltinType::BFloat16:
397     llvm_unreachable("Builtin type needs extra local data!");
398     // Fall through, if the impossible happens.
399 
400   case BuiltinType::NullPtr:
401   case BuiltinType::Overload:
402   case BuiltinType::Dependent:
403   case BuiltinType::UnresolvedTemplate:
404   case BuiltinType::BoundMember:
405   case BuiltinType::UnknownAny:
406   case BuiltinType::ARCUnbridgedCast:
407   case BuiltinType::PseudoObject:
408   case BuiltinType::ObjCId:
409   case BuiltinType::ObjCClass:
410   case BuiltinType::ObjCSel:
411 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
412   case BuiltinType::Id:
413 #include "clang/Basic/OpenCLImageTypes.def"
414 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
415   case BuiltinType::Id:
416 #include "clang/Basic/OpenCLExtensionTypes.def"
417   case BuiltinType::OCLSampler:
418   case BuiltinType::OCLEvent:
419   case BuiltinType::OCLClkEvent:
420   case BuiltinType::OCLQueue:
421   case BuiltinType::OCLReserveID:
422 #define SVE_TYPE(Name, Id, SingletonId) \
423   case BuiltinType::Id:
424 #include "clang/Basic/AArch64ACLETypes.def"
425 #define PPC_VECTOR_TYPE(Name, Id, Size) \
426   case BuiltinType::Id:
427 #include "clang/Basic/PPCTypes.def"
428 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
429 #include "clang/Basic/RISCVVTypes.def"
430 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
431 #include "clang/Basic/WebAssemblyReferenceTypes.def"
432 #define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
433 #include "clang/Basic/AMDGPUTypes.def"
434 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
435 #include "clang/Basic/HLSLIntangibleTypes.def"
436   case BuiltinType::BuiltinFn:
437   case BuiltinType::IncompleteMatrixIdx:
438   case BuiltinType::ArraySection:
439   case BuiltinType::OMPArrayShaping:
440   case BuiltinType::OMPIterator:
441     return TST_unspecified;
442   }
443 
444   llvm_unreachable("Invalid BuiltinType Kind!");
445 }
446 
IgnoreParensImpl(TypeLoc TL)447 TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
448   while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
449     TL = PTL.getInnerLoc();
450   return TL;
451 }
452 
findNullabilityLoc() const453 SourceLocation TypeLoc::findNullabilityLoc() const {
454   if (auto ATL = getAs<AttributedTypeLoc>()) {
455     const Attr *A = ATL.getAttr();
456     if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||
457               isa<TypeNullUnspecifiedAttr>(A)))
458       return A->getLocation();
459   }
460 
461   return {};
462 }
463 
findExplicitQualifierLoc() const464 TypeLoc TypeLoc::findExplicitQualifierLoc() const {
465   // Qualified types.
466   if (auto qual = getAs<QualifiedTypeLoc>())
467     return qual;
468 
469   TypeLoc loc = IgnoreParens();
470 
471   // Attributed types.
472   if (auto attr = loc.getAs<AttributedTypeLoc>()) {
473     if (attr.isQualifier()) return attr;
474     return attr.getModifiedLoc().findExplicitQualifierLoc();
475   }
476 
477   // C11 _Atomic types.
478   if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
479     return atomic;
480   }
481 
482   return {};
483 }
484 
initializeLocal(ASTContext & Context,SourceLocation Loc)485 void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
486                                            SourceLocation Loc) {
487   setNameLoc(Loc);
488   if (!getNumProtocols()) return;
489 
490   setProtocolLAngleLoc(Loc);
491   setProtocolRAngleLoc(Loc);
492   for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
493     setProtocolLoc(i, Loc);
494 }
495 
initializeLocal(ASTContext & Context,SourceLocation Loc)496 void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
497                                         SourceLocation Loc) {
498   setHasBaseTypeAsWritten(true);
499   setTypeArgsLAngleLoc(Loc);
500   setTypeArgsRAngleLoc(Loc);
501   for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
502     setTypeArgTInfo(i,
503                    Context.getTrivialTypeSourceInfo(
504                      getTypePtr()->getTypeArgsAsWritten()[i], Loc));
505   }
506   setProtocolLAngleLoc(Loc);
507   setProtocolRAngleLoc(Loc);
508   for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
509     setProtocolLoc(i, Loc);
510 }
511 
getLocalSourceRange() const512 SourceRange AttributedTypeLoc::getLocalSourceRange() const {
513   // Note that this does *not* include the range of the attribute
514   // enclosure, e.g.:
515   //    __attribute__((foo(bar)))
516   //    ^~~~~~~~~~~~~~~        ~~
517   // or
518   //    [[foo(bar)]]
519   //    ^~        ~~
520   // That enclosure doesn't necessarily belong to a single attribute
521   // anyway.
522   return getAttr() ? getAttr()->getRange() : SourceRange();
523 }
524 
getLocalSourceRange() const525 SourceRange CountAttributedTypeLoc::getLocalSourceRange() const {
526   return getCountExpr() ? getCountExpr()->getSourceRange() : SourceRange();
527 }
528 
getLocalSourceRange() const529 SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const {
530   return getAttr() ? getAttr()->getRange() : SourceRange();
531 }
532 
initializeLocal(ASTContext & Context,SourceLocation Loc)533 void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
534                                        SourceLocation Loc) {
535   TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
536       ::initializeLocal(Context, Loc);
537   this->getLocalData()->UnmodifiedTInfo =
538       Context.getTrivialTypeSourceInfo(getUnmodifiedType(), Loc);
539 }
540 
initializeLocal(ASTContext & Context,SourceLocation Loc)541 void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,
542                                        SourceLocation Loc) {
543     setKWLoc(Loc);
544     setRParenLoc(Loc);
545     setLParenLoc(Loc);
546     this->setUnderlyingTInfo(
547         Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));
548 }
549 
550 template <class TL>
initializeElaboratedKeyword(TL T,SourceLocation Loc)551 static void initializeElaboratedKeyword(TL T, SourceLocation Loc) {
552   T.setElaboratedKeywordLoc(T.getTypePtr()->getKeyword() !=
553                                     ElaboratedTypeKeyword::None
554                                 ? Loc
555                                 : SourceLocation());
556 }
557 
558 static NestedNameSpecifierLoc
initializeQualifier(ASTContext & Context,NestedNameSpecifier * Qualifier,SourceLocation Loc)559 initializeQualifier(ASTContext &Context, NestedNameSpecifier *Qualifier,
560                     SourceLocation Loc) {
561   if (!Qualifier)
562     return NestedNameSpecifierLoc();
563   NestedNameSpecifierLocBuilder Builder;
564   Builder.MakeTrivial(Context, Qualifier, Loc);
565   return Builder.getWithLocInContext(Context);
566 }
567 
initializeLocal(ASTContext & Context,SourceLocation Loc)568 void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
569                                         SourceLocation Loc) {
570   if (isEmpty())
571     return;
572   initializeElaboratedKeyword(*this, Loc);
573   setQualifierLoc(
574       initializeQualifier(Context, getTypePtr()->getQualifier(), Loc));
575 }
576 
initializeLocal(ASTContext & Context,SourceLocation Loc)577 void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
578                                            SourceLocation Loc) {
579   initializeElaboratedKeyword(*this, Loc);
580   setQualifierLoc(
581       initializeQualifier(Context, getTypePtr()->getQualifier(), Loc));
582   setNameLoc(Loc);
583 }
584 
585 void
initializeLocal(ASTContext & Context,SourceLocation Loc)586 DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
587                                                         SourceLocation Loc) {
588   initializeElaboratedKeyword(*this, Loc);
589   setQualifierLoc(initializeQualifier(
590       Context, getTypePtr()->getDependentTemplateName().getQualifier(), Loc));
591   setTemplateKeywordLoc(Loc);
592   setTemplateNameLoc(Loc);
593   setLAngleLoc(Loc);
594   setRAngleLoc(Loc);
595   TemplateSpecializationTypeLoc::initializeArgLocs(
596       Context, getTypePtr()->template_arguments(), getArgInfos(), Loc);
597 }
598 
initializeArgLocs(ASTContext & Context,ArrayRef<TemplateArgument> Args,TemplateArgumentLocInfo * ArgInfos,SourceLocation Loc)599 void TemplateSpecializationTypeLoc::initializeArgLocs(
600     ASTContext &Context, ArrayRef<TemplateArgument> Args,
601     TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) {
602   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
603     switch (Args[i].getKind()) {
604     case TemplateArgument::Null:
605       llvm_unreachable("Impossible TemplateArgument");
606 
607     case TemplateArgument::Integral:
608     case TemplateArgument::Declaration:
609     case TemplateArgument::NullPtr:
610     case TemplateArgument::StructuralValue:
611       ArgInfos[i] = TemplateArgumentLocInfo();
612       break;
613 
614     case TemplateArgument::Expression:
615       ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
616       break;
617 
618     case TemplateArgument::Type:
619       ArgInfos[i] = TemplateArgumentLocInfo(
620                           Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
621                                                            Loc));
622       break;
623 
624     case TemplateArgument::Template:
625     case TemplateArgument::TemplateExpansion: {
626       NestedNameSpecifierLocBuilder Builder;
627       TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
628       if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
629         Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
630       else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
631         Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
632 
633       ArgInfos[i] = TemplateArgumentLocInfo(
634           Context, Builder.getWithLocInContext(Context), Loc,
635           Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
636                                                           : Loc);
637       break;
638     }
639 
640     case TemplateArgument::Pack:
641       ArgInfos[i] = TemplateArgumentLocInfo();
642       break;
643     }
644   }
645 }
646 
647 // Builds a ConceptReference where all locations point at the same token,
648 // for use in trivial TypeSourceInfo for constrained AutoType
createTrivialConceptReference(ASTContext & Context,SourceLocation Loc,const AutoType * AT)649 static ConceptReference *createTrivialConceptReference(ASTContext &Context,
650                                                        SourceLocation Loc,
651                                                        const AutoType *AT) {
652   DeclarationNameInfo DNI =
653       DeclarationNameInfo(AT->getTypeConstraintConcept()->getDeclName(), Loc,
654                           AT->getTypeConstraintConcept()->getDeclName());
655   unsigned size = AT->getTypeConstraintArguments().size();
656   llvm::SmallVector<TemplateArgumentLocInfo, 8> TALI(size);
657   TemplateSpecializationTypeLoc::initializeArgLocs(
658       Context, AT->getTypeConstraintArguments(), TALI.data(), Loc);
659   TemplateArgumentListInfo TAListI;
660   for (unsigned i = 0; i < size; ++i) {
661     TAListI.addArgument(
662         TemplateArgumentLoc(AT->getTypeConstraintArguments()[i],
663                             TALI[i])); // TemplateArgumentLocInfo()
664   }
665 
666   auto *ConceptRef = ConceptReference::Create(
667       Context, NestedNameSpecifierLoc{}, Loc, DNI, nullptr,
668       AT->getTypeConstraintConcept(),
669       ASTTemplateArgumentListInfo::Create(Context, TAListI));
670   return ConceptRef;
671 }
672 
initializeLocal(ASTContext & Context,SourceLocation Loc)673 void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
674   setRParenLoc(Loc);
675   setNameLoc(Loc);
676   setConceptReference(nullptr);
677   if (getTypePtr()->isConstrained()) {
678     setConceptReference(
679         createTrivialConceptReference(Context, Loc, getTypePtr()));
680   }
681 }
682 
683 namespace {
684 
685   class GetContainedAutoTypeLocVisitor :
686     public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> {
687   public:
688     using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit;
689 
VisitAutoTypeLoc(AutoTypeLoc TL)690     TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) {
691       return TL;
692     }
693 
694     // Only these types can contain the desired 'auto' type.
695 
VisitElaboratedTypeLoc(ElaboratedTypeLoc T)696     TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) {
697       return Visit(T.getNamedTypeLoc());
698     }
699 
VisitQualifiedTypeLoc(QualifiedTypeLoc T)700     TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {
701       return Visit(T.getUnqualifiedLoc());
702     }
703 
VisitPointerTypeLoc(PointerTypeLoc T)704     TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) {
705       return Visit(T.getPointeeLoc());
706     }
707 
VisitBlockPointerTypeLoc(BlockPointerTypeLoc T)708     TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
709       return Visit(T.getPointeeLoc());
710     }
711 
VisitReferenceTypeLoc(ReferenceTypeLoc T)712     TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) {
713       return Visit(T.getPointeeLoc());
714     }
715 
VisitMemberPointerTypeLoc(MemberPointerTypeLoc T)716     TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
717       return Visit(T.getPointeeLoc());
718     }
719 
VisitArrayTypeLoc(ArrayTypeLoc T)720     TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) {
721       return Visit(T.getElementLoc());
722     }
723 
VisitFunctionTypeLoc(FunctionTypeLoc T)724     TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) {
725       return Visit(T.getReturnLoc());
726     }
727 
VisitParenTypeLoc(ParenTypeLoc T)728     TypeLoc VisitParenTypeLoc(ParenTypeLoc T) {
729       return Visit(T.getInnerLoc());
730     }
731 
VisitAttributedTypeLoc(AttributedTypeLoc T)732     TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) {
733       return Visit(T.getModifiedLoc());
734     }
735 
VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T)736     TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) {
737       return Visit(T.getWrappedLoc());
738     }
739 
740     TypeLoc
VisitHLSLAttributedResourceTypeLoc(HLSLAttributedResourceTypeLoc T)741     VisitHLSLAttributedResourceTypeLoc(HLSLAttributedResourceTypeLoc T) {
742       return Visit(T.getWrappedLoc());
743     }
744 
VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T)745     TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
746       return Visit(T.getInnerLoc());
747     }
748 
VisitAdjustedTypeLoc(AdjustedTypeLoc T)749     TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) {
750       return Visit(T.getOriginalLoc());
751     }
752 
VisitPackExpansionTypeLoc(PackExpansionTypeLoc T)753     TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) {
754       return Visit(T.getPatternLoc());
755     }
756   };
757 
758 } // namespace
759 
getContainedAutoTypeLoc() const760 AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
761   TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this);
762   if (Res.isNull())
763     return AutoTypeLoc();
764   return Res.getAs<AutoTypeLoc>();
765 }
766 
getTemplateKeywordLoc() const767 SourceLocation TypeLoc::getTemplateKeywordLoc() const {
768   if (const auto TSTL = getAsAdjusted<TemplateSpecializationTypeLoc>())
769     return TSTL.getTemplateKeywordLoc();
770   if (const auto DTSTL =
771           getAsAdjusted<DependentTemplateSpecializationTypeLoc>())
772     return DTSTL.getTemplateKeywordLoc();
773   return SourceLocation();
774 }
775