10b57cec5SDimitry Andric //===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file defines the TypeLoc subclasses implementations.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
145f757f3fSDimitry Andric #include "clang/AST/ASTConcept.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
16480093f4SDimitry Andric #include "clang/AST/Attr.h"
175f757f3fSDimitry Andric #include "clang/AST/DeclTemplate.h"
180b57cec5SDimitry Andric #include "clang/AST/Expr.h"
190b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
200b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
210b57cec5SDimitry Andric #include "clang/AST/TemplateName.h"
220b57cec5SDimitry Andric #include "clang/AST/TypeLocVisitor.h"
230b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
240b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
250b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
260b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
270b57cec5SDimitry Andric #include <algorithm>
280b57cec5SDimitry Andric #include <cassert>
290b57cec5SDimitry Andric #include <cstdint>
300b57cec5SDimitry Andric #include <cstring>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric using namespace clang;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric static const unsigned TypeLocMaxDataAlign = alignof(void *);
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
370b57cec5SDimitry Andric // TypeLoc Implementation
380b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric namespace {
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
430b57cec5SDimitry Andric public:
440b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
450b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
460b57cec5SDimitry Andric   SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
470b57cec5SDimitry Andric     return TyLoc.getLocalSourceRange(); \
480b57cec5SDimitry Andric   }
490b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
500b57cec5SDimitry Andric };
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric } // namespace
530b57cec5SDimitry Andric 
getLocalSourceRangeImpl(TypeLoc TL)540b57cec5SDimitry Andric SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
550b57cec5SDimitry Andric   if (TL.isNull()) return SourceRange();
560b57cec5SDimitry Andric   return TypeLocRanger().Visit(TL);
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric namespace {
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
620b57cec5SDimitry Andric public:
630b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
640b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
650b57cec5SDimitry Andric   unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
660b57cec5SDimitry Andric     return TyLoc.getLocalDataAlignment(); \
670b57cec5SDimitry Andric   }
680b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
690b57cec5SDimitry Andric };
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric } // namespace
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric /// Returns the alignment of the type source info data block.
getLocalAlignmentForType(QualType Ty)740b57cec5SDimitry Andric unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
750b57cec5SDimitry Andric   if (Ty.isNull()) return 1;
760b57cec5SDimitry Andric   return TypeAligner().Visit(TypeLoc(Ty, nullptr));
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric namespace {
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
820b57cec5SDimitry Andric public:
830b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
840b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
850b57cec5SDimitry Andric   unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
860b57cec5SDimitry Andric     return TyLoc.getLocalDataSize(); \
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
890b57cec5SDimitry Andric };
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric } // namespace
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric /// Returns the size of the type source info data block.
getFullDataSizeForType(QualType Ty)940b57cec5SDimitry Andric unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
950b57cec5SDimitry Andric   unsigned Total = 0;
960b57cec5SDimitry Andric   TypeLoc TyLoc(Ty, nullptr);
970b57cec5SDimitry Andric   unsigned MaxAlign = 1;
980b57cec5SDimitry Andric   while (!TyLoc.isNull()) {
990b57cec5SDimitry Andric     unsigned Align = getLocalAlignmentForType(TyLoc.getType());
1000b57cec5SDimitry Andric     MaxAlign = std::max(Align, MaxAlign);
1010b57cec5SDimitry Andric     Total = llvm::alignTo(Total, Align);
1020b57cec5SDimitry Andric     Total += TypeSizer().Visit(TyLoc);
1030b57cec5SDimitry Andric     TyLoc = TyLoc.getNextTypeLoc();
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric   Total = llvm::alignTo(Total, MaxAlign);
1060b57cec5SDimitry Andric   return Total;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric namespace {
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
1120b57cec5SDimitry Andric public:
1130b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
1140b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
1150b57cec5SDimitry Andric   TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
1160b57cec5SDimitry Andric     return TyLoc.getNextTypeLoc(); \
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
1190b57cec5SDimitry Andric };
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric } // namespace
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
1240b57cec5SDimitry Andric /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
getNextTypeLocImpl(TypeLoc TL)1250b57cec5SDimitry Andric TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
1260b57cec5SDimitry Andric   return NextLoc().Visit(TL);
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric /// Initializes a type location, and all of its children
1300b57cec5SDimitry Andric /// recursively, as if the entire tree had been written in the
1310b57cec5SDimitry Andric /// given location.
initializeImpl(ASTContext & Context,TypeLoc TL,SourceLocation Loc)1320b57cec5SDimitry Andric void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
1330b57cec5SDimitry Andric                              SourceLocation Loc) {
1340b57cec5SDimitry Andric   while (true) {
1350b57cec5SDimitry Andric     switch (TL.getTypeLocClass()) {
1360b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
1370b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT)        \
1380b57cec5SDimitry Andric     case CLASS: {                     \
1390b57cec5SDimitry Andric       CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
1400b57cec5SDimitry Andric       TLCasted.initializeLocal(Context, Loc);  \
1410b57cec5SDimitry Andric       TL = TLCasted.getNextTypeLoc(); \
1420b57cec5SDimitry Andric       if (!TL) return;                \
1430b57cec5SDimitry Andric       continue;                       \
1440b57cec5SDimitry Andric     }
1450b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
1460b57cec5SDimitry Andric     }
1470b57cec5SDimitry Andric   }
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric namespace {
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
1530b57cec5SDimitry Andric   TypeLoc Source;
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric public:
TypeLocCopier(TypeLoc source)1560b57cec5SDimitry Andric   TypeLocCopier(TypeLoc source) : Source(source) {}
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
1590b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT)                          \
1600b57cec5SDimitry Andric   void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \
1610b57cec5SDimitry Andric     dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \
1620b57cec5SDimitry Andric   }
1630b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
1640b57cec5SDimitry Andric };
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric } // namespace
1670b57cec5SDimitry Andric 
copy(TypeLoc other)1680b57cec5SDimitry Andric void TypeLoc::copy(TypeLoc other) {
1690b57cec5SDimitry Andric   assert(getFullDataSize() == other.getFullDataSize());
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   // If both data pointers are aligned to the maximum alignment, we
1720b57cec5SDimitry Andric   // can memcpy because getFullDataSize() accurately reflects the
1730b57cec5SDimitry Andric   // layout of the data.
1740b57cec5SDimitry Andric   if (reinterpret_cast<uintptr_t>(Data) ==
1750b57cec5SDimitry Andric           llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
1760b57cec5SDimitry Andric                         TypeLocMaxDataAlign) &&
1770b57cec5SDimitry Andric       reinterpret_cast<uintptr_t>(other.Data) ==
1780b57cec5SDimitry Andric           llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
1790b57cec5SDimitry Andric                         TypeLocMaxDataAlign)) {
1800b57cec5SDimitry Andric     memcpy(Data, other.Data, getFullDataSize());
1810b57cec5SDimitry Andric     return;
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   // Copy each of the pieces.
1850b57cec5SDimitry Andric   TypeLoc TL(getType(), Data);
1860b57cec5SDimitry Andric   do {
1870b57cec5SDimitry Andric     TypeLocCopier(other).Visit(TL);
1880b57cec5SDimitry Andric     other = other.getNextTypeLoc();
1890b57cec5SDimitry Andric   } while ((TL = TL.getNextTypeLoc()));
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric 
getBeginLoc() const1920b57cec5SDimitry Andric SourceLocation TypeLoc::getBeginLoc() const {
1930b57cec5SDimitry Andric   TypeLoc Cur = *this;
1940b57cec5SDimitry Andric   TypeLoc LeftMost = Cur;
1950b57cec5SDimitry Andric   while (true) {
1960b57cec5SDimitry Andric     switch (Cur.getTypeLocClass()) {
1970b57cec5SDimitry Andric     case Elaborated:
198bdd1243dSDimitry Andric       if (Cur.getLocalSourceRange().getBegin().isValid()) {
1990b57cec5SDimitry Andric         LeftMost = Cur;
2000b57cec5SDimitry Andric         break;
201bdd1243dSDimitry Andric       }
202bdd1243dSDimitry Andric       Cur = Cur.getNextTypeLoc();
203bdd1243dSDimitry Andric       if (Cur.isNull())
204bdd1243dSDimitry Andric         break;
205bdd1243dSDimitry Andric       continue;
2060b57cec5SDimitry Andric     case FunctionProto:
2070b57cec5SDimitry Andric       if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
2080b57cec5SDimitry Andric               ->hasTrailingReturn()) {
2090b57cec5SDimitry Andric         LeftMost = Cur;
2100b57cec5SDimitry Andric         break;
2110b57cec5SDimitry Andric       }
212bdd1243dSDimitry Andric       [[fallthrough]];
2130b57cec5SDimitry Andric     case FunctionNoProto:
2140b57cec5SDimitry Andric     case ConstantArray:
2150b57cec5SDimitry Andric     case DependentSizedArray:
2160b57cec5SDimitry Andric     case IncompleteArray:
2170b57cec5SDimitry Andric     case VariableArray:
2180b57cec5SDimitry Andric       // FIXME: Currently QualifiedTypeLoc does not have a source range
2190b57cec5SDimitry Andric     case Qualified:
2200b57cec5SDimitry Andric       Cur = Cur.getNextTypeLoc();
2210b57cec5SDimitry Andric       continue;
2220b57cec5SDimitry Andric     default:
2230b57cec5SDimitry Andric       if (Cur.getLocalSourceRange().getBegin().isValid())
2240b57cec5SDimitry Andric         LeftMost = Cur;
2250b57cec5SDimitry Andric       Cur = Cur.getNextTypeLoc();
2260b57cec5SDimitry Andric       if (Cur.isNull())
2270b57cec5SDimitry Andric         break;
2280b57cec5SDimitry Andric       continue;
2290b57cec5SDimitry Andric     } // switch
2300b57cec5SDimitry Andric     break;
2310b57cec5SDimitry Andric   } // while
2320b57cec5SDimitry Andric   return LeftMost.getLocalSourceRange().getBegin();
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
getEndLoc() const2350b57cec5SDimitry Andric SourceLocation TypeLoc::getEndLoc() const {
2360b57cec5SDimitry Andric   TypeLoc Cur = *this;
2370b57cec5SDimitry Andric   TypeLoc Last;
2380b57cec5SDimitry Andric   while (true) {
2390b57cec5SDimitry Andric     switch (Cur.getTypeLocClass()) {
2400b57cec5SDimitry Andric     default:
2410b57cec5SDimitry Andric       if (!Last)
2420b57cec5SDimitry Andric         Last = Cur;
2430b57cec5SDimitry Andric       return Last.getLocalSourceRange().getEnd();
2440b57cec5SDimitry Andric     case Paren:
2450b57cec5SDimitry Andric     case ConstantArray:
2460b57cec5SDimitry Andric     case DependentSizedArray:
2470b57cec5SDimitry Andric     case IncompleteArray:
2480b57cec5SDimitry Andric     case VariableArray:
2490b57cec5SDimitry Andric     case FunctionNoProto:
250349cc55cSDimitry Andric       // The innermost type with suffix syntax always determines the end of the
251349cc55cSDimitry Andric       // type.
2520b57cec5SDimitry Andric       Last = Cur;
2530b57cec5SDimitry Andric       break;
2540b57cec5SDimitry Andric     case FunctionProto:
2550b57cec5SDimitry Andric       if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
2560b57cec5SDimitry Andric         Last = TypeLoc();
2570b57cec5SDimitry Andric       else
2580b57cec5SDimitry Andric         Last = Cur;
2590b57cec5SDimitry Andric       break;
260349cc55cSDimitry Andric     case ObjCObjectPointer:
261349cc55cSDimitry Andric       // `id` and `id<...>` have no star location.
262349cc55cSDimitry Andric       if (Cur.castAs<ObjCObjectPointerTypeLoc>().getStarLoc().isInvalid())
263349cc55cSDimitry Andric         break;
264bdd1243dSDimitry Andric       [[fallthrough]];
2650b57cec5SDimitry Andric     case Pointer:
2660b57cec5SDimitry Andric     case BlockPointer:
2670b57cec5SDimitry Andric     case MemberPointer:
2680b57cec5SDimitry Andric     case LValueReference:
2690b57cec5SDimitry Andric     case RValueReference:
2700b57cec5SDimitry Andric     case PackExpansion:
271349cc55cSDimitry Andric       // Types with prefix syntax only determine the end of the type if there
272349cc55cSDimitry Andric       // is no suffix type.
2730b57cec5SDimitry Andric       if (!Last)
2740b57cec5SDimitry Andric         Last = Cur;
2750b57cec5SDimitry Andric       break;
2760b57cec5SDimitry Andric     case Qualified:
2770b57cec5SDimitry Andric     case Elaborated:
2780b57cec5SDimitry Andric       break;
2790b57cec5SDimitry Andric     }
2800b57cec5SDimitry Andric     Cur = Cur.getNextTypeLoc();
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric namespace {
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
2870b57cec5SDimitry Andric   // Overload resolution does the real work for us.
isTypeSpec__anon668ff8b90611::TSTChecker2880b57cec5SDimitry Andric   static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
isTypeSpec__anon668ff8b90611::TSTChecker2890b57cec5SDimitry Andric   static bool isTypeSpec(TypeLoc _) { return false; }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
2920b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
2930b57cec5SDimitry Andric   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
2940b57cec5SDimitry Andric     return isTypeSpec(TyLoc); \
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
2970b57cec5SDimitry Andric };
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric } // namespace
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric /// Determines if the given type loc corresponds to a
3020b57cec5SDimitry Andric /// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
3030b57cec5SDimitry Andric /// the type hierarchy, this is made somewhat complicated.
3040b57cec5SDimitry Andric ///
3050b57cec5SDimitry Andric /// There are a lot of types that currently use TypeSpecTypeLoc
3060b57cec5SDimitry Andric /// because it's a convenient base class.  Ideally we would not accept
3070b57cec5SDimitry Andric /// those here, but ideally we would have better implementations for
3080b57cec5SDimitry Andric /// them.
isKind(const TypeLoc & TL)3090b57cec5SDimitry Andric bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
3100b57cec5SDimitry Andric   if (TL.getType().hasLocalQualifiers()) return false;
3110b57cec5SDimitry Andric   return TSTChecker().Visit(TL);
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
isDefinition() const314480093f4SDimitry Andric bool TagTypeLoc::isDefinition() const {
315480093f4SDimitry Andric   TagDecl *D = getDecl();
316480093f4SDimitry Andric   return D->isCompleteDefinition() &&
317480093f4SDimitry Andric          (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
318480093f4SDimitry Andric }
319480093f4SDimitry Andric 
3200b57cec5SDimitry Andric // Reimplemented to account for GNU/C++ extension
3210b57cec5SDimitry Andric //     typeof unary-expression
3220b57cec5SDimitry Andric // where there are no parentheses.
getLocalSourceRange() const3230b57cec5SDimitry Andric SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
3240b57cec5SDimitry Andric   if (getRParenLoc().isValid())
3250b57cec5SDimitry Andric     return SourceRange(getTypeofLoc(), getRParenLoc());
3260b57cec5SDimitry Andric   else
3270b57cec5SDimitry Andric     return SourceRange(getTypeofLoc(),
3280b57cec5SDimitry Andric                        getUnderlyingExpr()->getSourceRange().getEnd());
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric 
getWrittenTypeSpec() const3320b57cec5SDimitry Andric TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
3330b57cec5SDimitry Andric   if (needsExtraLocalData())
3340b57cec5SDimitry Andric     return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
3350b57cec5SDimitry Andric   switch (getTypePtr()->getKind()) {
3360b57cec5SDimitry Andric   case BuiltinType::Void:
3370b57cec5SDimitry Andric     return TST_void;
3380b57cec5SDimitry Andric   case BuiltinType::Bool:
3390b57cec5SDimitry Andric     return TST_bool;
3400b57cec5SDimitry Andric   case BuiltinType::Char_U:
3410b57cec5SDimitry Andric   case BuiltinType::Char_S:
3420b57cec5SDimitry Andric     return TST_char;
3430b57cec5SDimitry Andric   case BuiltinType::Char8:
3440b57cec5SDimitry Andric     return TST_char8;
3450b57cec5SDimitry Andric   case BuiltinType::Char16:
3460b57cec5SDimitry Andric     return TST_char16;
3470b57cec5SDimitry Andric   case BuiltinType::Char32:
3480b57cec5SDimitry Andric     return TST_char32;
3490b57cec5SDimitry Andric   case BuiltinType::WChar_S:
3500b57cec5SDimitry Andric   case BuiltinType::WChar_U:
3510b57cec5SDimitry Andric     return TST_wchar;
3520b57cec5SDimitry Andric   case BuiltinType::UChar:
3530b57cec5SDimitry Andric   case BuiltinType::UShort:
3540b57cec5SDimitry Andric   case BuiltinType::UInt:
3550b57cec5SDimitry Andric   case BuiltinType::ULong:
3560b57cec5SDimitry Andric   case BuiltinType::ULongLong:
3570b57cec5SDimitry Andric   case BuiltinType::UInt128:
3580b57cec5SDimitry Andric   case BuiltinType::SChar:
3590b57cec5SDimitry Andric   case BuiltinType::Short:
3600b57cec5SDimitry Andric   case BuiltinType::Int:
3610b57cec5SDimitry Andric   case BuiltinType::Long:
3620b57cec5SDimitry Andric   case BuiltinType::LongLong:
3630b57cec5SDimitry Andric   case BuiltinType::Int128:
3640b57cec5SDimitry Andric   case BuiltinType::Half:
3650b57cec5SDimitry Andric   case BuiltinType::Float:
3660b57cec5SDimitry Andric   case BuiltinType::Double:
3670b57cec5SDimitry Andric   case BuiltinType::LongDouble:
3680b57cec5SDimitry Andric   case BuiltinType::Float16:
3690b57cec5SDimitry Andric   case BuiltinType::Float128:
370349cc55cSDimitry Andric   case BuiltinType::Ibm128:
3710b57cec5SDimitry Andric   case BuiltinType::ShortAccum:
3720b57cec5SDimitry Andric   case BuiltinType::Accum:
3730b57cec5SDimitry Andric   case BuiltinType::LongAccum:
3740b57cec5SDimitry Andric   case BuiltinType::UShortAccum:
3750b57cec5SDimitry Andric   case BuiltinType::UAccum:
3760b57cec5SDimitry Andric   case BuiltinType::ULongAccum:
3770b57cec5SDimitry Andric   case BuiltinType::ShortFract:
3780b57cec5SDimitry Andric   case BuiltinType::Fract:
3790b57cec5SDimitry Andric   case BuiltinType::LongFract:
3800b57cec5SDimitry Andric   case BuiltinType::UShortFract:
3810b57cec5SDimitry Andric   case BuiltinType::UFract:
3820b57cec5SDimitry Andric   case BuiltinType::ULongFract:
3830b57cec5SDimitry Andric   case BuiltinType::SatShortAccum:
3840b57cec5SDimitry Andric   case BuiltinType::SatAccum:
3850b57cec5SDimitry Andric   case BuiltinType::SatLongAccum:
3860b57cec5SDimitry Andric   case BuiltinType::SatUShortAccum:
3870b57cec5SDimitry Andric   case BuiltinType::SatUAccum:
3880b57cec5SDimitry Andric   case BuiltinType::SatULongAccum:
3890b57cec5SDimitry Andric   case BuiltinType::SatShortFract:
3900b57cec5SDimitry Andric   case BuiltinType::SatFract:
3910b57cec5SDimitry Andric   case BuiltinType::SatLongFract:
3920b57cec5SDimitry Andric   case BuiltinType::SatUShortFract:
3930b57cec5SDimitry Andric   case BuiltinType::SatUFract:
3940b57cec5SDimitry Andric   case BuiltinType::SatULongFract:
3955ffd83dbSDimitry Andric   case BuiltinType::BFloat16:
3960b57cec5SDimitry Andric     llvm_unreachable("Builtin type needs extra local data!");
3970b57cec5SDimitry Andric     // Fall through, if the impossible happens.
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric   case BuiltinType::NullPtr:
4000b57cec5SDimitry Andric   case BuiltinType::Overload:
4010b57cec5SDimitry Andric   case BuiltinType::Dependent:
4020b57cec5SDimitry Andric   case BuiltinType::BoundMember:
4030b57cec5SDimitry Andric   case BuiltinType::UnknownAny:
4040b57cec5SDimitry Andric   case BuiltinType::ARCUnbridgedCast:
4050b57cec5SDimitry Andric   case BuiltinType::PseudoObject:
4060b57cec5SDimitry Andric   case BuiltinType::ObjCId:
4070b57cec5SDimitry Andric   case BuiltinType::ObjCClass:
4080b57cec5SDimitry Andric   case BuiltinType::ObjCSel:
4090b57cec5SDimitry Andric #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
4100b57cec5SDimitry Andric   case BuiltinType::Id:
4110b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def"
4120b57cec5SDimitry Andric #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
4130b57cec5SDimitry Andric   case BuiltinType::Id:
4140b57cec5SDimitry Andric #include "clang/Basic/OpenCLExtensionTypes.def"
4150b57cec5SDimitry Andric   case BuiltinType::OCLSampler:
4160b57cec5SDimitry Andric   case BuiltinType::OCLEvent:
4170b57cec5SDimitry Andric   case BuiltinType::OCLClkEvent:
4180b57cec5SDimitry Andric   case BuiltinType::OCLQueue:
4190b57cec5SDimitry Andric   case BuiltinType::OCLReserveID:
420a7dea167SDimitry Andric #define SVE_TYPE(Name, Id, SingletonId) \
421a7dea167SDimitry Andric   case BuiltinType::Id:
422a7dea167SDimitry Andric #include "clang/Basic/AArch64SVEACLETypes.def"
423e8d8bef9SDimitry Andric #define PPC_VECTOR_TYPE(Name, Id, Size) \
424e8d8bef9SDimitry Andric   case BuiltinType::Id:
425e8d8bef9SDimitry Andric #include "clang/Basic/PPCTypes.def"
426fe6060f1SDimitry Andric #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
427fe6060f1SDimitry Andric #include "clang/Basic/RISCVVTypes.def"
42806c3fb27SDimitry Andric #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
42906c3fb27SDimitry Andric #include "clang/Basic/WebAssemblyReferenceTypes.def"
4300b57cec5SDimitry Andric   case BuiltinType::BuiltinFn:
4315ffd83dbSDimitry Andric   case BuiltinType::IncompleteMatrixIdx:
4320b57cec5SDimitry Andric   case BuiltinType::OMPArraySection:
4335ffd83dbSDimitry Andric   case BuiltinType::OMPArrayShaping:
4345ffd83dbSDimitry Andric   case BuiltinType::OMPIterator:
4350b57cec5SDimitry Andric     return TST_unspecified;
4360b57cec5SDimitry Andric   }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric   llvm_unreachable("Invalid BuiltinType Kind!");
4390b57cec5SDimitry Andric }
4400b57cec5SDimitry Andric 
IgnoreParensImpl(TypeLoc TL)4410b57cec5SDimitry Andric TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
4420b57cec5SDimitry Andric   while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
4430b57cec5SDimitry Andric     TL = PTL.getInnerLoc();
4440b57cec5SDimitry Andric   return TL;
4450b57cec5SDimitry Andric }
4460b57cec5SDimitry Andric 
findNullabilityLoc() const4470b57cec5SDimitry Andric SourceLocation TypeLoc::findNullabilityLoc() const {
4480b57cec5SDimitry Andric   if (auto ATL = getAs<AttributedTypeLoc>()) {
4490b57cec5SDimitry Andric     const Attr *A = ATL.getAttr();
4500b57cec5SDimitry Andric     if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||
4510b57cec5SDimitry Andric               isa<TypeNullUnspecifiedAttr>(A)))
4520b57cec5SDimitry Andric       return A->getLocation();
4530b57cec5SDimitry Andric   }
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   return {};
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
findExplicitQualifierLoc() const4580b57cec5SDimitry Andric TypeLoc TypeLoc::findExplicitQualifierLoc() const {
4590b57cec5SDimitry Andric   // Qualified types.
4600b57cec5SDimitry Andric   if (auto qual = getAs<QualifiedTypeLoc>())
4610b57cec5SDimitry Andric     return qual;
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   TypeLoc loc = IgnoreParens();
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // Attributed types.
4660b57cec5SDimitry Andric   if (auto attr = loc.getAs<AttributedTypeLoc>()) {
4670b57cec5SDimitry Andric     if (attr.isQualifier()) return attr;
4680b57cec5SDimitry Andric     return attr.getModifiedLoc().findExplicitQualifierLoc();
4690b57cec5SDimitry Andric   }
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   // C11 _Atomic types.
4720b57cec5SDimitry Andric   if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
4730b57cec5SDimitry Andric     return atomic;
4740b57cec5SDimitry Andric   }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric   return {};
4770b57cec5SDimitry Andric }
4780b57cec5SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)4790b57cec5SDimitry Andric void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
4800b57cec5SDimitry Andric                                            SourceLocation Loc) {
4810b57cec5SDimitry Andric   setNameLoc(Loc);
4820b57cec5SDimitry Andric   if (!getNumProtocols()) return;
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   setProtocolLAngleLoc(Loc);
4850b57cec5SDimitry Andric   setProtocolRAngleLoc(Loc);
4860b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
4870b57cec5SDimitry Andric     setProtocolLoc(i, Loc);
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)4900b57cec5SDimitry Andric void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
4910b57cec5SDimitry Andric                                         SourceLocation Loc) {
4920b57cec5SDimitry Andric   setHasBaseTypeAsWritten(true);
4930b57cec5SDimitry Andric   setTypeArgsLAngleLoc(Loc);
4940b57cec5SDimitry Andric   setTypeArgsRAngleLoc(Loc);
4950b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
4960b57cec5SDimitry Andric     setTypeArgTInfo(i,
4970b57cec5SDimitry Andric                    Context.getTrivialTypeSourceInfo(
4980b57cec5SDimitry Andric                      getTypePtr()->getTypeArgsAsWritten()[i], Loc));
4990b57cec5SDimitry Andric   }
5000b57cec5SDimitry Andric   setProtocolLAngleLoc(Loc);
5010b57cec5SDimitry Andric   setProtocolRAngleLoc(Loc);
5020b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
5030b57cec5SDimitry Andric     setProtocolLoc(i, Loc);
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric 
getLocalSourceRange() const506480093f4SDimitry Andric SourceRange AttributedTypeLoc::getLocalSourceRange() const {
507480093f4SDimitry Andric   // Note that this does *not* include the range of the attribute
508480093f4SDimitry Andric   // enclosure, e.g.:
509480093f4SDimitry Andric   //    __attribute__((foo(bar)))
510480093f4SDimitry Andric   //    ^~~~~~~~~~~~~~~        ~~
511480093f4SDimitry Andric   // or
512480093f4SDimitry Andric   //    [[foo(bar)]]
513480093f4SDimitry Andric   //    ^~        ~~
514480093f4SDimitry Andric   // That enclosure doesn't necessarily belong to a single attribute
515480093f4SDimitry Andric   // anyway.
516480093f4SDimitry Andric   return getAttr() ? getAttr()->getRange() : SourceRange();
517480093f4SDimitry Andric }
518480093f4SDimitry Andric 
getLocalSourceRange() const51981ad6265SDimitry Andric SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const {
52081ad6265SDimitry Andric   return getAttr() ? getAttr()->getRange() : SourceRange();
52181ad6265SDimitry Andric }
52281ad6265SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)5230b57cec5SDimitry Andric void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
5240b57cec5SDimitry Andric                                        SourceLocation Loc) {
5250b57cec5SDimitry Andric   TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
5260b57cec5SDimitry Andric       ::initializeLocal(Context, Loc);
527bdd1243dSDimitry Andric   this->getLocalData()->UnmodifiedTInfo =
528bdd1243dSDimitry Andric       Context.getTrivialTypeSourceInfo(getUnmodifiedType(), Loc);
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)5310b57cec5SDimitry Andric void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,
5320b57cec5SDimitry Andric                                        SourceLocation Loc) {
5330b57cec5SDimitry Andric     setKWLoc(Loc);
5340b57cec5SDimitry Andric     setRParenLoc(Loc);
5350b57cec5SDimitry Andric     setLParenLoc(Loc);
5360b57cec5SDimitry Andric     this->setUnderlyingTInfo(
5370b57cec5SDimitry Andric         Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)5400b57cec5SDimitry Andric void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
5410b57cec5SDimitry Andric                                         SourceLocation Loc) {
542bdd1243dSDimitry Andric   if (isEmpty())
543bdd1243dSDimitry Andric     return;
5440b57cec5SDimitry Andric   setElaboratedKeywordLoc(Loc);
5450b57cec5SDimitry Andric   NestedNameSpecifierLocBuilder Builder;
5460b57cec5SDimitry Andric   Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
5470b57cec5SDimitry Andric   setQualifierLoc(Builder.getWithLocInContext(Context));
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)5500b57cec5SDimitry Andric void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
5510b57cec5SDimitry Andric                                            SourceLocation Loc) {
5520b57cec5SDimitry Andric   setElaboratedKeywordLoc(Loc);
5530b57cec5SDimitry Andric   NestedNameSpecifierLocBuilder Builder;
5540b57cec5SDimitry Andric   Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
5550b57cec5SDimitry Andric   setQualifierLoc(Builder.getWithLocInContext(Context));
5560b57cec5SDimitry Andric   setNameLoc(Loc);
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric void
initializeLocal(ASTContext & Context,SourceLocation Loc)5600b57cec5SDimitry Andric DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
5610b57cec5SDimitry Andric                                                         SourceLocation Loc) {
5620b57cec5SDimitry Andric   setElaboratedKeywordLoc(Loc);
5630b57cec5SDimitry Andric   if (getTypePtr()->getQualifier()) {
5640b57cec5SDimitry Andric     NestedNameSpecifierLocBuilder Builder;
5650b57cec5SDimitry Andric     Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
5660b57cec5SDimitry Andric     setQualifierLoc(Builder.getWithLocInContext(Context));
5670b57cec5SDimitry Andric   } else {
5680b57cec5SDimitry Andric     setQualifierLoc(NestedNameSpecifierLoc());
5690b57cec5SDimitry Andric   }
5700b57cec5SDimitry Andric   setTemplateKeywordLoc(Loc);
5710b57cec5SDimitry Andric   setTemplateNameLoc(Loc);
5720b57cec5SDimitry Andric   setLAngleLoc(Loc);
5730b57cec5SDimitry Andric   setRAngleLoc(Loc);
574bdd1243dSDimitry Andric   TemplateSpecializationTypeLoc::initializeArgLocs(
575bdd1243dSDimitry Andric       Context, getTypePtr()->template_arguments(), getArgInfos(), Loc);
5760b57cec5SDimitry Andric }
5770b57cec5SDimitry Andric 
initializeArgLocs(ASTContext & Context,ArrayRef<TemplateArgument> Args,TemplateArgumentLocInfo * ArgInfos,SourceLocation Loc)578bdd1243dSDimitry Andric void TemplateSpecializationTypeLoc::initializeArgLocs(
579bdd1243dSDimitry Andric     ASTContext &Context, ArrayRef<TemplateArgument> Args,
580bdd1243dSDimitry Andric     TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) {
581bdd1243dSDimitry Andric   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
5820b57cec5SDimitry Andric     switch (Args[i].getKind()) {
5830b57cec5SDimitry Andric     case TemplateArgument::Null:
5840b57cec5SDimitry Andric       llvm_unreachable("Impossible TemplateArgument");
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric     case TemplateArgument::Integral:
5870b57cec5SDimitry Andric     case TemplateArgument::Declaration:
5880b57cec5SDimitry Andric     case TemplateArgument::NullPtr:
5897a6dacacSDimitry Andric     case TemplateArgument::StructuralValue:
5900b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo();
5910b57cec5SDimitry Andric       break;
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric     case TemplateArgument::Expression:
5940b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
5950b57cec5SDimitry Andric       break;
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric     case TemplateArgument::Type:
5980b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo(
5990b57cec5SDimitry Andric                           Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
6000b57cec5SDimitry Andric                                                            Loc));
6010b57cec5SDimitry Andric       break;
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric     case TemplateArgument::Template:
6040b57cec5SDimitry Andric     case TemplateArgument::TemplateExpansion: {
6050b57cec5SDimitry Andric       NestedNameSpecifierLocBuilder Builder;
6060b57cec5SDimitry Andric       TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
6070b57cec5SDimitry Andric       if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
6080b57cec5SDimitry Andric         Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
6090b57cec5SDimitry Andric       else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
6100b57cec5SDimitry Andric         Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo(
613e8d8bef9SDimitry Andric           Context, Builder.getWithLocInContext(Context), Loc,
6140b57cec5SDimitry Andric           Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
6150b57cec5SDimitry Andric                                                           : Loc);
6160b57cec5SDimitry Andric       break;
6170b57cec5SDimitry Andric     }
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric     case TemplateArgument::Pack:
6200b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo();
6210b57cec5SDimitry Andric       break;
6220b57cec5SDimitry Andric     }
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric }
62555e4f9d5SDimitry Andric 
6265f757f3fSDimitry Andric // Builds a ConceptReference where all locations point at the same token,
6275f757f3fSDimitry Andric // for use in trivial TypeSourceInfo for constrained AutoType
createTrivialConceptReference(ASTContext & Context,SourceLocation Loc,const AutoType * AT)6285f757f3fSDimitry Andric static ConceptReference *createTrivialConceptReference(ASTContext &Context,
6295f757f3fSDimitry Andric                                                        SourceLocation Loc,
6305f757f3fSDimitry Andric                                                        const AutoType *AT) {
6315f757f3fSDimitry Andric   DeclarationNameInfo DNI =
6325f757f3fSDimitry Andric       DeclarationNameInfo(AT->getTypeConstraintConcept()->getDeclName(), Loc,
6335f757f3fSDimitry Andric                           AT->getTypeConstraintConcept()->getDeclName());
6345f757f3fSDimitry Andric   unsigned size = AT->getTypeConstraintArguments().size();
6355f757f3fSDimitry Andric   TemplateArgumentLocInfo *TALI = new TemplateArgumentLocInfo[size];
6365f757f3fSDimitry Andric   TemplateSpecializationTypeLoc::initializeArgLocs(
6375f757f3fSDimitry Andric       Context, AT->getTypeConstraintArguments(), TALI, Loc);
6385f757f3fSDimitry Andric   TemplateArgumentListInfo TAListI;
6395f757f3fSDimitry Andric   for (unsigned i = 0; i < size; ++i) {
6405f757f3fSDimitry Andric     TAListI.addArgument(
6415f757f3fSDimitry Andric         TemplateArgumentLoc(AT->getTypeConstraintArguments()[i],
6425f757f3fSDimitry Andric                             TALI[i])); // TemplateArgumentLocInfo()
6435f757f3fSDimitry Andric   }
6445f757f3fSDimitry Andric 
6455f757f3fSDimitry Andric   auto *ConceptRef = ConceptReference::Create(
6465f757f3fSDimitry Andric       Context, NestedNameSpecifierLoc{}, Loc, DNI, nullptr,
6475f757f3fSDimitry Andric       AT->getTypeConstraintConcept(),
6485f757f3fSDimitry Andric       ASTTemplateArgumentListInfo::Create(Context, TAListI));
6495f757f3fSDimitry Andric   delete[] TALI;
6505f757f3fSDimitry Andric   return ConceptRef;
65155e4f9d5SDimitry Andric }
65255e4f9d5SDimitry Andric 
initializeLocal(ASTContext & Context,SourceLocation Loc)65355e4f9d5SDimitry Andric void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
65404eeddc0SDimitry Andric   setRParenLoc(Loc);
65555e4f9d5SDimitry Andric   setNameLoc(Loc);
6565f757f3fSDimitry Andric   setConceptReference(nullptr);
6575f757f3fSDimitry Andric   if (getTypePtr()->isConstrained()) {
6585f757f3fSDimitry Andric     setConceptReference(
6595f757f3fSDimitry Andric         createTrivialConceptReference(Context, Loc, getTypePtr()));
66055e4f9d5SDimitry Andric   }
6615f757f3fSDimitry Andric }
66255e4f9d5SDimitry Andric 
66355e4f9d5SDimitry Andric namespace {
66455e4f9d5SDimitry Andric 
66555e4f9d5SDimitry Andric   class GetContainedAutoTypeLocVisitor :
66655e4f9d5SDimitry Andric     public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> {
66755e4f9d5SDimitry Andric   public:
66855e4f9d5SDimitry Andric     using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit;
66955e4f9d5SDimitry Andric 
VisitAutoTypeLoc(AutoTypeLoc TL)67055e4f9d5SDimitry Andric     TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) {
67155e4f9d5SDimitry Andric       return TL;
67255e4f9d5SDimitry Andric     }
67355e4f9d5SDimitry Andric 
67455e4f9d5SDimitry Andric     // Only these types can contain the desired 'auto' type.
67555e4f9d5SDimitry Andric 
VisitElaboratedTypeLoc(ElaboratedTypeLoc T)67655e4f9d5SDimitry Andric     TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) {
67755e4f9d5SDimitry Andric       return Visit(T.getNamedTypeLoc());
67855e4f9d5SDimitry Andric     }
67955e4f9d5SDimitry Andric 
VisitQualifiedTypeLoc(QualifiedTypeLoc T)68055e4f9d5SDimitry Andric     TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {
68155e4f9d5SDimitry Andric       return Visit(T.getUnqualifiedLoc());
68255e4f9d5SDimitry Andric     }
68355e4f9d5SDimitry Andric 
VisitPointerTypeLoc(PointerTypeLoc T)68455e4f9d5SDimitry Andric     TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) {
68555e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
68655e4f9d5SDimitry Andric     }
68755e4f9d5SDimitry Andric 
VisitBlockPointerTypeLoc(BlockPointerTypeLoc T)68855e4f9d5SDimitry Andric     TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
68955e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
69055e4f9d5SDimitry Andric     }
69155e4f9d5SDimitry Andric 
VisitReferenceTypeLoc(ReferenceTypeLoc T)69255e4f9d5SDimitry Andric     TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) {
69355e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
69455e4f9d5SDimitry Andric     }
69555e4f9d5SDimitry Andric 
VisitMemberPointerTypeLoc(MemberPointerTypeLoc T)69655e4f9d5SDimitry Andric     TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
69755e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
69855e4f9d5SDimitry Andric     }
69955e4f9d5SDimitry Andric 
VisitArrayTypeLoc(ArrayTypeLoc T)70055e4f9d5SDimitry Andric     TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) {
70155e4f9d5SDimitry Andric       return Visit(T.getElementLoc());
70255e4f9d5SDimitry Andric     }
70355e4f9d5SDimitry Andric 
VisitFunctionTypeLoc(FunctionTypeLoc T)70455e4f9d5SDimitry Andric     TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) {
70555e4f9d5SDimitry Andric       return Visit(T.getReturnLoc());
70655e4f9d5SDimitry Andric     }
70755e4f9d5SDimitry Andric 
VisitParenTypeLoc(ParenTypeLoc T)70855e4f9d5SDimitry Andric     TypeLoc VisitParenTypeLoc(ParenTypeLoc T) {
70955e4f9d5SDimitry Andric       return Visit(T.getInnerLoc());
71055e4f9d5SDimitry Andric     }
71155e4f9d5SDimitry Andric 
VisitAttributedTypeLoc(AttributedTypeLoc T)71255e4f9d5SDimitry Andric     TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) {
71355e4f9d5SDimitry Andric       return Visit(T.getModifiedLoc());
71455e4f9d5SDimitry Andric     }
71555e4f9d5SDimitry Andric 
VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T)71681ad6265SDimitry Andric     TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) {
71781ad6265SDimitry Andric       return Visit(T.getWrappedLoc());
71881ad6265SDimitry Andric     }
71981ad6265SDimitry Andric 
VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T)72055e4f9d5SDimitry Andric     TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
72155e4f9d5SDimitry Andric       return Visit(T.getInnerLoc());
72255e4f9d5SDimitry Andric     }
72355e4f9d5SDimitry Andric 
VisitAdjustedTypeLoc(AdjustedTypeLoc T)72455e4f9d5SDimitry Andric     TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) {
72555e4f9d5SDimitry Andric       return Visit(T.getOriginalLoc());
72655e4f9d5SDimitry Andric     }
72755e4f9d5SDimitry Andric 
VisitPackExpansionTypeLoc(PackExpansionTypeLoc T)72855e4f9d5SDimitry Andric     TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) {
72955e4f9d5SDimitry Andric       return Visit(T.getPatternLoc());
73055e4f9d5SDimitry Andric     }
73155e4f9d5SDimitry Andric   };
73255e4f9d5SDimitry Andric 
73355e4f9d5SDimitry Andric } // namespace
73455e4f9d5SDimitry Andric 
getContainedAutoTypeLoc() const73555e4f9d5SDimitry Andric AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
73655e4f9d5SDimitry Andric   TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this);
73755e4f9d5SDimitry Andric   if (Res.isNull())
73855e4f9d5SDimitry Andric     return AutoTypeLoc();
73955e4f9d5SDimitry Andric   return Res.getAs<AutoTypeLoc>();
74055e4f9d5SDimitry Andric }
741