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"
1455e4f9d5SDimitry Andric #include "clang/AST/DeclTemplate.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
16480093f4SDimitry Andric #include "clang/AST/Attr.h"
170b57cec5SDimitry Andric #include "clang/AST/Expr.h"
180b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
190b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
200b57cec5SDimitry Andric #include "clang/AST/TemplateName.h"
210b57cec5SDimitry Andric #include "clang/AST/TypeLocVisitor.h"
220b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
230b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
250b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
260b57cec5SDimitry Andric #include <algorithm>
270b57cec5SDimitry Andric #include <cassert>
280b57cec5SDimitry Andric #include <cstdint>
290b57cec5SDimitry Andric #include <cstring>
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace clang;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric static const unsigned TypeLocMaxDataAlign = alignof(void *);
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
360b57cec5SDimitry Andric // TypeLoc Implementation
370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric namespace {
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
420b57cec5SDimitry Andric public:
430b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
440b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
450b57cec5SDimitry Andric   SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
460b57cec5SDimitry Andric     return TyLoc.getLocalSourceRange(); \
470b57cec5SDimitry Andric   }
480b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
490b57cec5SDimitry Andric };
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric } // namespace
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
540b57cec5SDimitry Andric   if (TL.isNull()) return SourceRange();
550b57cec5SDimitry Andric   return TypeLocRanger().Visit(TL);
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric namespace {
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
610b57cec5SDimitry Andric public:
620b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
630b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
640b57cec5SDimitry Andric   unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
650b57cec5SDimitry Andric     return TyLoc.getLocalDataAlignment(); \
660b57cec5SDimitry Andric   }
670b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
680b57cec5SDimitry Andric };
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric } // namespace
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric /// Returns the alignment of the type source info data block.
730b57cec5SDimitry Andric unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
740b57cec5SDimitry Andric   if (Ty.isNull()) return 1;
750b57cec5SDimitry Andric   return TypeAligner().Visit(TypeLoc(Ty, nullptr));
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric namespace {
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
810b57cec5SDimitry Andric public:
820b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
830b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
840b57cec5SDimitry Andric   unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
850b57cec5SDimitry Andric     return TyLoc.getLocalDataSize(); \
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
880b57cec5SDimitry Andric };
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric } // namespace
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric /// Returns the size of the type source info data block.
930b57cec5SDimitry Andric unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
940b57cec5SDimitry Andric   unsigned Total = 0;
950b57cec5SDimitry Andric   TypeLoc TyLoc(Ty, nullptr);
960b57cec5SDimitry Andric   unsigned MaxAlign = 1;
970b57cec5SDimitry Andric   while (!TyLoc.isNull()) {
980b57cec5SDimitry Andric     unsigned Align = getLocalAlignmentForType(TyLoc.getType());
990b57cec5SDimitry Andric     MaxAlign = std::max(Align, MaxAlign);
1000b57cec5SDimitry Andric     Total = llvm::alignTo(Total, Align);
1010b57cec5SDimitry Andric     Total += TypeSizer().Visit(TyLoc);
1020b57cec5SDimitry Andric     TyLoc = TyLoc.getNextTypeLoc();
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric   Total = llvm::alignTo(Total, MaxAlign);
1050b57cec5SDimitry Andric   return Total;
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric namespace {
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
1110b57cec5SDimitry Andric public:
1120b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
1130b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
1140b57cec5SDimitry Andric   TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
1150b57cec5SDimitry Andric     return TyLoc.getNextTypeLoc(); \
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
1180b57cec5SDimitry Andric };
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric } // namespace
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
1230b57cec5SDimitry Andric /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
1240b57cec5SDimitry Andric TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
1250b57cec5SDimitry Andric   return NextLoc().Visit(TL);
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric /// Initializes a type location, and all of its children
1290b57cec5SDimitry Andric /// recursively, as if the entire tree had been written in the
1300b57cec5SDimitry Andric /// given location.
1310b57cec5SDimitry Andric void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
1320b57cec5SDimitry Andric                              SourceLocation Loc) {
1330b57cec5SDimitry Andric   while (true) {
1340b57cec5SDimitry Andric     switch (TL.getTypeLocClass()) {
1350b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
1360b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT)        \
1370b57cec5SDimitry Andric     case CLASS: {                     \
1380b57cec5SDimitry Andric       CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
1390b57cec5SDimitry Andric       TLCasted.initializeLocal(Context, Loc);  \
1400b57cec5SDimitry Andric       TL = TLCasted.getNextTypeLoc(); \
1410b57cec5SDimitry Andric       if (!TL) return;                \
1420b57cec5SDimitry Andric       continue;                       \
1430b57cec5SDimitry Andric     }
1440b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
1450b57cec5SDimitry Andric     }
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric namespace {
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
1520b57cec5SDimitry Andric   TypeLoc Source;
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric public:
1550b57cec5SDimitry Andric   TypeLocCopier(TypeLoc source) : Source(source) {}
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
1580b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT)                          \
1590b57cec5SDimitry Andric   void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \
1600b57cec5SDimitry Andric     dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
1630b57cec5SDimitry Andric };
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric } // namespace
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric void TypeLoc::copy(TypeLoc other) {
1680b57cec5SDimitry Andric   assert(getFullDataSize() == other.getFullDataSize());
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   // If both data pointers are aligned to the maximum alignment, we
1710b57cec5SDimitry Andric   // can memcpy because getFullDataSize() accurately reflects the
1720b57cec5SDimitry Andric   // layout of the data.
1730b57cec5SDimitry Andric   if (reinterpret_cast<uintptr_t>(Data) ==
1740b57cec5SDimitry Andric           llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
1750b57cec5SDimitry Andric                         TypeLocMaxDataAlign) &&
1760b57cec5SDimitry Andric       reinterpret_cast<uintptr_t>(other.Data) ==
1770b57cec5SDimitry Andric           llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
1780b57cec5SDimitry Andric                         TypeLocMaxDataAlign)) {
1790b57cec5SDimitry Andric     memcpy(Data, other.Data, getFullDataSize());
1800b57cec5SDimitry Andric     return;
1810b57cec5SDimitry Andric   }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   // Copy each of the pieces.
1840b57cec5SDimitry Andric   TypeLoc TL(getType(), Data);
1850b57cec5SDimitry Andric   do {
1860b57cec5SDimitry Andric     TypeLocCopier(other).Visit(TL);
1870b57cec5SDimitry Andric     other = other.getNextTypeLoc();
1880b57cec5SDimitry Andric   } while ((TL = TL.getNextTypeLoc()));
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric SourceLocation TypeLoc::getBeginLoc() const {
1920b57cec5SDimitry Andric   TypeLoc Cur = *this;
1930b57cec5SDimitry Andric   TypeLoc LeftMost = Cur;
1940b57cec5SDimitry Andric   while (true) {
1950b57cec5SDimitry Andric     switch (Cur.getTypeLocClass()) {
1960b57cec5SDimitry Andric     case Elaborated:
197bdd1243dSDimitry Andric       if (Cur.getLocalSourceRange().getBegin().isValid()) {
1980b57cec5SDimitry Andric         LeftMost = Cur;
1990b57cec5SDimitry Andric         break;
200bdd1243dSDimitry Andric       }
201bdd1243dSDimitry Andric       Cur = Cur.getNextTypeLoc();
202bdd1243dSDimitry Andric       if (Cur.isNull())
203bdd1243dSDimitry Andric         break;
204bdd1243dSDimitry Andric       continue;
2050b57cec5SDimitry Andric     case FunctionProto:
2060b57cec5SDimitry Andric       if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
2070b57cec5SDimitry Andric               ->hasTrailingReturn()) {
2080b57cec5SDimitry Andric         LeftMost = Cur;
2090b57cec5SDimitry Andric         break;
2100b57cec5SDimitry Andric       }
211bdd1243dSDimitry Andric       [[fallthrough]];
2120b57cec5SDimitry Andric     case FunctionNoProto:
2130b57cec5SDimitry Andric     case ConstantArray:
2140b57cec5SDimitry Andric     case DependentSizedArray:
2150b57cec5SDimitry Andric     case IncompleteArray:
2160b57cec5SDimitry Andric     case VariableArray:
2170b57cec5SDimitry Andric       // FIXME: Currently QualifiedTypeLoc does not have a source range
2180b57cec5SDimitry Andric     case Qualified:
2190b57cec5SDimitry Andric       Cur = Cur.getNextTypeLoc();
2200b57cec5SDimitry Andric       continue;
2210b57cec5SDimitry Andric     default:
2220b57cec5SDimitry Andric       if (Cur.getLocalSourceRange().getBegin().isValid())
2230b57cec5SDimitry Andric         LeftMost = Cur;
2240b57cec5SDimitry Andric       Cur = Cur.getNextTypeLoc();
2250b57cec5SDimitry Andric       if (Cur.isNull())
2260b57cec5SDimitry Andric         break;
2270b57cec5SDimitry Andric       continue;
2280b57cec5SDimitry Andric     } // switch
2290b57cec5SDimitry Andric     break;
2300b57cec5SDimitry Andric   } // while
2310b57cec5SDimitry Andric   return LeftMost.getLocalSourceRange().getBegin();
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric SourceLocation TypeLoc::getEndLoc() const {
2350b57cec5SDimitry Andric   TypeLoc Cur = *this;
2360b57cec5SDimitry Andric   TypeLoc Last;
2370b57cec5SDimitry Andric   while (true) {
2380b57cec5SDimitry Andric     switch (Cur.getTypeLocClass()) {
2390b57cec5SDimitry Andric     default:
2400b57cec5SDimitry Andric       if (!Last)
2410b57cec5SDimitry Andric         Last = Cur;
2420b57cec5SDimitry Andric       return Last.getLocalSourceRange().getEnd();
2430b57cec5SDimitry Andric     case Paren:
2440b57cec5SDimitry Andric     case ConstantArray:
2450b57cec5SDimitry Andric     case DependentSizedArray:
2460b57cec5SDimitry Andric     case IncompleteArray:
2470b57cec5SDimitry Andric     case VariableArray:
2480b57cec5SDimitry Andric     case FunctionNoProto:
249349cc55cSDimitry Andric       // The innermost type with suffix syntax always determines the end of the
250349cc55cSDimitry Andric       // type.
2510b57cec5SDimitry Andric       Last = Cur;
2520b57cec5SDimitry Andric       break;
2530b57cec5SDimitry Andric     case FunctionProto:
2540b57cec5SDimitry Andric       if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
2550b57cec5SDimitry Andric         Last = TypeLoc();
2560b57cec5SDimitry Andric       else
2570b57cec5SDimitry Andric         Last = Cur;
2580b57cec5SDimitry Andric       break;
259349cc55cSDimitry Andric     case ObjCObjectPointer:
260349cc55cSDimitry Andric       // `id` and `id<...>` have no star location.
261349cc55cSDimitry Andric       if (Cur.castAs<ObjCObjectPointerTypeLoc>().getStarLoc().isInvalid())
262349cc55cSDimitry Andric         break;
263bdd1243dSDimitry Andric       [[fallthrough]];
2640b57cec5SDimitry Andric     case Pointer:
2650b57cec5SDimitry Andric     case BlockPointer:
2660b57cec5SDimitry Andric     case MemberPointer:
2670b57cec5SDimitry Andric     case LValueReference:
2680b57cec5SDimitry Andric     case RValueReference:
2690b57cec5SDimitry Andric     case PackExpansion:
270349cc55cSDimitry Andric       // Types with prefix syntax only determine the end of the type if there
271349cc55cSDimitry Andric       // is no suffix type.
2720b57cec5SDimitry Andric       if (!Last)
2730b57cec5SDimitry Andric         Last = Cur;
2740b57cec5SDimitry Andric       break;
2750b57cec5SDimitry Andric     case Qualified:
2760b57cec5SDimitry Andric     case Elaborated:
2770b57cec5SDimitry Andric       break;
2780b57cec5SDimitry Andric     }
2790b57cec5SDimitry Andric     Cur = Cur.getNextTypeLoc();
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric namespace {
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
2860b57cec5SDimitry Andric   // Overload resolution does the real work for us.
2870b57cec5SDimitry Andric   static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
2880b57cec5SDimitry Andric   static bool isTypeSpec(TypeLoc _) { return false; }
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT)
2910b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \
2920b57cec5SDimitry Andric   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
2930b57cec5SDimitry Andric     return isTypeSpec(TyLoc); \
2940b57cec5SDimitry Andric   }
2950b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def"
2960b57cec5SDimitry Andric };
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric } // namespace
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric /// Determines if the given type loc corresponds to a
3010b57cec5SDimitry Andric /// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
3020b57cec5SDimitry Andric /// the type hierarchy, this is made somewhat complicated.
3030b57cec5SDimitry Andric ///
3040b57cec5SDimitry Andric /// There are a lot of types that currently use TypeSpecTypeLoc
3050b57cec5SDimitry Andric /// because it's a convenient base class.  Ideally we would not accept
3060b57cec5SDimitry Andric /// those here, but ideally we would have better implementations for
3070b57cec5SDimitry Andric /// them.
3080b57cec5SDimitry Andric bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
3090b57cec5SDimitry Andric   if (TL.getType().hasLocalQualifiers()) return false;
3100b57cec5SDimitry Andric   return TSTChecker().Visit(TL);
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric 
313480093f4SDimitry Andric bool TagTypeLoc::isDefinition() const {
314480093f4SDimitry Andric   TagDecl *D = getDecl();
315480093f4SDimitry Andric   return D->isCompleteDefinition() &&
316480093f4SDimitry Andric          (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
317480093f4SDimitry Andric }
318480093f4SDimitry Andric 
3190b57cec5SDimitry Andric // Reimplemented to account for GNU/C++ extension
3200b57cec5SDimitry Andric //     typeof unary-expression
3210b57cec5SDimitry Andric // where there are no parentheses.
3220b57cec5SDimitry Andric SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
3230b57cec5SDimitry Andric   if (getRParenLoc().isValid())
3240b57cec5SDimitry Andric     return SourceRange(getTypeofLoc(), getRParenLoc());
3250b57cec5SDimitry Andric   else
3260b57cec5SDimitry Andric     return SourceRange(getTypeofLoc(),
3270b57cec5SDimitry Andric                        getUnderlyingExpr()->getSourceRange().getEnd());
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
3320b57cec5SDimitry Andric   if (needsExtraLocalData())
3330b57cec5SDimitry Andric     return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
3340b57cec5SDimitry Andric   switch (getTypePtr()->getKind()) {
3350b57cec5SDimitry Andric   case BuiltinType::Void:
3360b57cec5SDimitry Andric     return TST_void;
3370b57cec5SDimitry Andric   case BuiltinType::Bool:
3380b57cec5SDimitry Andric     return TST_bool;
3390b57cec5SDimitry Andric   case BuiltinType::Char_U:
3400b57cec5SDimitry Andric   case BuiltinType::Char_S:
3410b57cec5SDimitry Andric     return TST_char;
3420b57cec5SDimitry Andric   case BuiltinType::Char8:
3430b57cec5SDimitry Andric     return TST_char8;
3440b57cec5SDimitry Andric   case BuiltinType::Char16:
3450b57cec5SDimitry Andric     return TST_char16;
3460b57cec5SDimitry Andric   case BuiltinType::Char32:
3470b57cec5SDimitry Andric     return TST_char32;
3480b57cec5SDimitry Andric   case BuiltinType::WChar_S:
3490b57cec5SDimitry Andric   case BuiltinType::WChar_U:
3500b57cec5SDimitry Andric     return TST_wchar;
3510b57cec5SDimitry Andric   case BuiltinType::UChar:
3520b57cec5SDimitry Andric   case BuiltinType::UShort:
3530b57cec5SDimitry Andric   case BuiltinType::UInt:
3540b57cec5SDimitry Andric   case BuiltinType::ULong:
3550b57cec5SDimitry Andric   case BuiltinType::ULongLong:
3560b57cec5SDimitry Andric   case BuiltinType::UInt128:
3570b57cec5SDimitry Andric   case BuiltinType::SChar:
3580b57cec5SDimitry Andric   case BuiltinType::Short:
3590b57cec5SDimitry Andric   case BuiltinType::Int:
3600b57cec5SDimitry Andric   case BuiltinType::Long:
3610b57cec5SDimitry Andric   case BuiltinType::LongLong:
3620b57cec5SDimitry Andric   case BuiltinType::Int128:
3630b57cec5SDimitry Andric   case BuiltinType::Half:
3640b57cec5SDimitry Andric   case BuiltinType::Float:
3650b57cec5SDimitry Andric   case BuiltinType::Double:
3660b57cec5SDimitry Andric   case BuiltinType::LongDouble:
3670b57cec5SDimitry Andric   case BuiltinType::Float16:
3680b57cec5SDimitry Andric   case BuiltinType::Float128:
369349cc55cSDimitry Andric   case BuiltinType::Ibm128:
3700b57cec5SDimitry Andric   case BuiltinType::ShortAccum:
3710b57cec5SDimitry Andric   case BuiltinType::Accum:
3720b57cec5SDimitry Andric   case BuiltinType::LongAccum:
3730b57cec5SDimitry Andric   case BuiltinType::UShortAccum:
3740b57cec5SDimitry Andric   case BuiltinType::UAccum:
3750b57cec5SDimitry Andric   case BuiltinType::ULongAccum:
3760b57cec5SDimitry Andric   case BuiltinType::ShortFract:
3770b57cec5SDimitry Andric   case BuiltinType::Fract:
3780b57cec5SDimitry Andric   case BuiltinType::LongFract:
3790b57cec5SDimitry Andric   case BuiltinType::UShortFract:
3800b57cec5SDimitry Andric   case BuiltinType::UFract:
3810b57cec5SDimitry Andric   case BuiltinType::ULongFract:
3820b57cec5SDimitry Andric   case BuiltinType::SatShortAccum:
3830b57cec5SDimitry Andric   case BuiltinType::SatAccum:
3840b57cec5SDimitry Andric   case BuiltinType::SatLongAccum:
3850b57cec5SDimitry Andric   case BuiltinType::SatUShortAccum:
3860b57cec5SDimitry Andric   case BuiltinType::SatUAccum:
3870b57cec5SDimitry Andric   case BuiltinType::SatULongAccum:
3880b57cec5SDimitry Andric   case BuiltinType::SatShortFract:
3890b57cec5SDimitry Andric   case BuiltinType::SatFract:
3900b57cec5SDimitry Andric   case BuiltinType::SatLongFract:
3910b57cec5SDimitry Andric   case BuiltinType::SatUShortFract:
3920b57cec5SDimitry Andric   case BuiltinType::SatUFract:
3930b57cec5SDimitry Andric   case BuiltinType::SatULongFract:
3945ffd83dbSDimitry Andric   case BuiltinType::BFloat16:
3950b57cec5SDimitry Andric     llvm_unreachable("Builtin type needs extra local data!");
3960b57cec5SDimitry Andric     // Fall through, if the impossible happens.
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   case BuiltinType::NullPtr:
3990b57cec5SDimitry Andric   case BuiltinType::Overload:
4000b57cec5SDimitry Andric   case BuiltinType::Dependent:
4010b57cec5SDimitry Andric   case BuiltinType::BoundMember:
4020b57cec5SDimitry Andric   case BuiltinType::UnknownAny:
4030b57cec5SDimitry Andric   case BuiltinType::ARCUnbridgedCast:
4040b57cec5SDimitry Andric   case BuiltinType::PseudoObject:
4050b57cec5SDimitry Andric   case BuiltinType::ObjCId:
4060b57cec5SDimitry Andric   case BuiltinType::ObjCClass:
4070b57cec5SDimitry Andric   case BuiltinType::ObjCSel:
4080b57cec5SDimitry Andric #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
4090b57cec5SDimitry Andric   case BuiltinType::Id:
4100b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def"
4110b57cec5SDimitry Andric #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
4120b57cec5SDimitry Andric   case BuiltinType::Id:
4130b57cec5SDimitry Andric #include "clang/Basic/OpenCLExtensionTypes.def"
4140b57cec5SDimitry Andric   case BuiltinType::OCLSampler:
4150b57cec5SDimitry Andric   case BuiltinType::OCLEvent:
4160b57cec5SDimitry Andric   case BuiltinType::OCLClkEvent:
4170b57cec5SDimitry Andric   case BuiltinType::OCLQueue:
4180b57cec5SDimitry Andric   case BuiltinType::OCLReserveID:
419a7dea167SDimitry Andric #define SVE_TYPE(Name, Id, SingletonId) \
420a7dea167SDimitry Andric   case BuiltinType::Id:
421a7dea167SDimitry Andric #include "clang/Basic/AArch64SVEACLETypes.def"
422e8d8bef9SDimitry Andric #define PPC_VECTOR_TYPE(Name, Id, Size) \
423e8d8bef9SDimitry Andric   case BuiltinType::Id:
424e8d8bef9SDimitry Andric #include "clang/Basic/PPCTypes.def"
425fe6060f1SDimitry Andric #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
426fe6060f1SDimitry Andric #include "clang/Basic/RISCVVTypes.def"
4270b57cec5SDimitry Andric   case BuiltinType::BuiltinFn:
4285ffd83dbSDimitry Andric   case BuiltinType::IncompleteMatrixIdx:
4290b57cec5SDimitry Andric   case BuiltinType::OMPArraySection:
4305ffd83dbSDimitry Andric   case BuiltinType::OMPArrayShaping:
4315ffd83dbSDimitry Andric   case BuiltinType::OMPIterator:
4320b57cec5SDimitry Andric     return TST_unspecified;
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   llvm_unreachable("Invalid BuiltinType Kind!");
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
4390b57cec5SDimitry Andric   while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
4400b57cec5SDimitry Andric     TL = PTL.getInnerLoc();
4410b57cec5SDimitry Andric   return TL;
4420b57cec5SDimitry Andric }
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric SourceLocation TypeLoc::findNullabilityLoc() const {
4450b57cec5SDimitry Andric   if (auto ATL = getAs<AttributedTypeLoc>()) {
4460b57cec5SDimitry Andric     const Attr *A = ATL.getAttr();
4470b57cec5SDimitry Andric     if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||
4480b57cec5SDimitry Andric               isa<TypeNullUnspecifiedAttr>(A)))
4490b57cec5SDimitry Andric       return A->getLocation();
4500b57cec5SDimitry Andric   }
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   return {};
4530b57cec5SDimitry Andric }
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric TypeLoc TypeLoc::findExplicitQualifierLoc() const {
4560b57cec5SDimitry Andric   // Qualified types.
4570b57cec5SDimitry Andric   if (auto qual = getAs<QualifiedTypeLoc>())
4580b57cec5SDimitry Andric     return qual;
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   TypeLoc loc = IgnoreParens();
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   // Attributed types.
4630b57cec5SDimitry Andric   if (auto attr = loc.getAs<AttributedTypeLoc>()) {
4640b57cec5SDimitry Andric     if (attr.isQualifier()) return attr;
4650b57cec5SDimitry Andric     return attr.getModifiedLoc().findExplicitQualifierLoc();
4660b57cec5SDimitry Andric   }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   // C11 _Atomic types.
4690b57cec5SDimitry Andric   if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
4700b57cec5SDimitry Andric     return atomic;
4710b57cec5SDimitry Andric   }
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric   return {};
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
4770b57cec5SDimitry Andric                                            SourceLocation Loc) {
4780b57cec5SDimitry Andric   setNameLoc(Loc);
4790b57cec5SDimitry Andric   if (!getNumProtocols()) return;
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   setProtocolLAngleLoc(Loc);
4820b57cec5SDimitry Andric   setProtocolRAngleLoc(Loc);
4830b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
4840b57cec5SDimitry Andric     setProtocolLoc(i, Loc);
4850b57cec5SDimitry Andric }
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
4880b57cec5SDimitry Andric                                         SourceLocation Loc) {
4890b57cec5SDimitry Andric   setHasBaseTypeAsWritten(true);
4900b57cec5SDimitry Andric   setTypeArgsLAngleLoc(Loc);
4910b57cec5SDimitry Andric   setTypeArgsRAngleLoc(Loc);
4920b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
4930b57cec5SDimitry Andric     setTypeArgTInfo(i,
4940b57cec5SDimitry Andric                    Context.getTrivialTypeSourceInfo(
4950b57cec5SDimitry Andric                      getTypePtr()->getTypeArgsAsWritten()[i], Loc));
4960b57cec5SDimitry Andric   }
4970b57cec5SDimitry Andric   setProtocolLAngleLoc(Loc);
4980b57cec5SDimitry Andric   setProtocolRAngleLoc(Loc);
4990b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
5000b57cec5SDimitry Andric     setProtocolLoc(i, Loc);
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric 
503480093f4SDimitry Andric SourceRange AttributedTypeLoc::getLocalSourceRange() const {
504480093f4SDimitry Andric   // Note that this does *not* include the range of the attribute
505480093f4SDimitry Andric   // enclosure, e.g.:
506480093f4SDimitry Andric   //    __attribute__((foo(bar)))
507480093f4SDimitry Andric   //    ^~~~~~~~~~~~~~~        ~~
508480093f4SDimitry Andric   // or
509480093f4SDimitry Andric   //    [[foo(bar)]]
510480093f4SDimitry Andric   //    ^~        ~~
511480093f4SDimitry Andric   // That enclosure doesn't necessarily belong to a single attribute
512480093f4SDimitry Andric   // anyway.
513480093f4SDimitry Andric   return getAttr() ? getAttr()->getRange() : SourceRange();
514480093f4SDimitry Andric }
515480093f4SDimitry Andric 
51681ad6265SDimitry Andric SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const {
51781ad6265SDimitry Andric   return getAttr() ? getAttr()->getRange() : SourceRange();
51881ad6265SDimitry Andric }
51981ad6265SDimitry Andric 
5200b57cec5SDimitry Andric void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
5210b57cec5SDimitry Andric                                        SourceLocation Loc) {
5220b57cec5SDimitry Andric   TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
5230b57cec5SDimitry Andric       ::initializeLocal(Context, Loc);
524bdd1243dSDimitry Andric   this->getLocalData()->UnmodifiedTInfo =
525bdd1243dSDimitry Andric       Context.getTrivialTypeSourceInfo(getUnmodifiedType(), Loc);
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,
5290b57cec5SDimitry Andric                                        SourceLocation Loc) {
5300b57cec5SDimitry Andric     setKWLoc(Loc);
5310b57cec5SDimitry Andric     setRParenLoc(Loc);
5320b57cec5SDimitry Andric     setLParenLoc(Loc);
5330b57cec5SDimitry Andric     this->setUnderlyingTInfo(
5340b57cec5SDimitry Andric         Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));
5350b57cec5SDimitry Andric }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
5380b57cec5SDimitry Andric                                         SourceLocation Loc) {
539bdd1243dSDimitry Andric   if (isEmpty())
540bdd1243dSDimitry Andric     return;
5410b57cec5SDimitry Andric   setElaboratedKeywordLoc(Loc);
5420b57cec5SDimitry Andric   NestedNameSpecifierLocBuilder Builder;
5430b57cec5SDimitry Andric   Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
5440b57cec5SDimitry Andric   setQualifierLoc(Builder.getWithLocInContext(Context));
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
5480b57cec5SDimitry Andric                                            SourceLocation Loc) {
5490b57cec5SDimitry Andric   setElaboratedKeywordLoc(Loc);
5500b57cec5SDimitry Andric   NestedNameSpecifierLocBuilder Builder;
5510b57cec5SDimitry Andric   Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
5520b57cec5SDimitry Andric   setQualifierLoc(Builder.getWithLocInContext(Context));
5530b57cec5SDimitry Andric   setNameLoc(Loc);
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric void
5570b57cec5SDimitry Andric DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
5580b57cec5SDimitry Andric                                                         SourceLocation Loc) {
5590b57cec5SDimitry Andric   setElaboratedKeywordLoc(Loc);
5600b57cec5SDimitry Andric   if (getTypePtr()->getQualifier()) {
5610b57cec5SDimitry Andric     NestedNameSpecifierLocBuilder Builder;
5620b57cec5SDimitry Andric     Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
5630b57cec5SDimitry Andric     setQualifierLoc(Builder.getWithLocInContext(Context));
5640b57cec5SDimitry Andric   } else {
5650b57cec5SDimitry Andric     setQualifierLoc(NestedNameSpecifierLoc());
5660b57cec5SDimitry Andric   }
5670b57cec5SDimitry Andric   setTemplateKeywordLoc(Loc);
5680b57cec5SDimitry Andric   setTemplateNameLoc(Loc);
5690b57cec5SDimitry Andric   setLAngleLoc(Loc);
5700b57cec5SDimitry Andric   setRAngleLoc(Loc);
571bdd1243dSDimitry Andric   TemplateSpecializationTypeLoc::initializeArgLocs(
572bdd1243dSDimitry Andric       Context, getTypePtr()->template_arguments(), getArgInfos(), Loc);
5730b57cec5SDimitry Andric }
5740b57cec5SDimitry Andric 
575bdd1243dSDimitry Andric void TemplateSpecializationTypeLoc::initializeArgLocs(
576bdd1243dSDimitry Andric     ASTContext &Context, ArrayRef<TemplateArgument> Args,
577bdd1243dSDimitry Andric     TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) {
578bdd1243dSDimitry Andric   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
5790b57cec5SDimitry Andric     switch (Args[i].getKind()) {
5800b57cec5SDimitry Andric     case TemplateArgument::Null:
5810b57cec5SDimitry Andric       llvm_unreachable("Impossible TemplateArgument");
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric     case TemplateArgument::Integral:
5840b57cec5SDimitry Andric     case TemplateArgument::Declaration:
5850b57cec5SDimitry Andric     case TemplateArgument::NullPtr:
5860b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo();
5870b57cec5SDimitry Andric       break;
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric     case TemplateArgument::Expression:
5900b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
5910b57cec5SDimitry Andric       break;
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric     case TemplateArgument::Type:
5940b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo(
5950b57cec5SDimitry Andric                           Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
5960b57cec5SDimitry Andric                                                            Loc));
5970b57cec5SDimitry Andric       break;
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric     case TemplateArgument::Template:
6000b57cec5SDimitry Andric     case TemplateArgument::TemplateExpansion: {
6010b57cec5SDimitry Andric       NestedNameSpecifierLocBuilder Builder;
6020b57cec5SDimitry Andric       TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
6030b57cec5SDimitry Andric       if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
6040b57cec5SDimitry Andric         Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
6050b57cec5SDimitry Andric       else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
6060b57cec5SDimitry Andric         Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo(
609e8d8bef9SDimitry Andric           Context, Builder.getWithLocInContext(Context), Loc,
6100b57cec5SDimitry Andric           Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
6110b57cec5SDimitry Andric                                                           : Loc);
6120b57cec5SDimitry Andric       break;
6130b57cec5SDimitry Andric     }
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric     case TemplateArgument::Pack:
6160b57cec5SDimitry Andric       ArgInfos[i] = TemplateArgumentLocInfo();
6170b57cec5SDimitry Andric       break;
6180b57cec5SDimitry Andric     }
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric }
62155e4f9d5SDimitry Andric 
62255e4f9d5SDimitry Andric DeclarationNameInfo AutoTypeLoc::getConceptNameInfo() const {
62355e4f9d5SDimitry Andric   return DeclarationNameInfo(getNamedConcept()->getDeclName(),
62455e4f9d5SDimitry Andric                              getLocalData()->ConceptNameLoc);
62555e4f9d5SDimitry Andric }
62655e4f9d5SDimitry Andric 
62755e4f9d5SDimitry Andric void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
62855e4f9d5SDimitry Andric   setNestedNameSpecifierLoc(NestedNameSpecifierLoc());
62955e4f9d5SDimitry Andric   setTemplateKWLoc(Loc);
63055e4f9d5SDimitry Andric   setConceptNameLoc(Loc);
63155e4f9d5SDimitry Andric   setFoundDecl(nullptr);
63255e4f9d5SDimitry Andric   setRAngleLoc(Loc);
63355e4f9d5SDimitry Andric   setLAngleLoc(Loc);
63404eeddc0SDimitry Andric   setRParenLoc(Loc);
635bdd1243dSDimitry Andric   TemplateSpecializationTypeLoc::initializeArgLocs(
636bdd1243dSDimitry Andric       Context, getTypePtr()->getTypeConstraintArguments(), getArgInfos(), Loc);
63755e4f9d5SDimitry Andric   setNameLoc(Loc);
63855e4f9d5SDimitry Andric }
63955e4f9d5SDimitry Andric 
64055e4f9d5SDimitry Andric 
64155e4f9d5SDimitry Andric namespace {
64255e4f9d5SDimitry Andric 
64355e4f9d5SDimitry Andric   class GetContainedAutoTypeLocVisitor :
64455e4f9d5SDimitry Andric     public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> {
64555e4f9d5SDimitry Andric   public:
64655e4f9d5SDimitry Andric     using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit;
64755e4f9d5SDimitry Andric 
64855e4f9d5SDimitry Andric     TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) {
64955e4f9d5SDimitry Andric       return TL;
65055e4f9d5SDimitry Andric     }
65155e4f9d5SDimitry Andric 
65255e4f9d5SDimitry Andric     // Only these types can contain the desired 'auto' type.
65355e4f9d5SDimitry Andric 
65455e4f9d5SDimitry Andric     TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) {
65555e4f9d5SDimitry Andric       return Visit(T.getNamedTypeLoc());
65655e4f9d5SDimitry Andric     }
65755e4f9d5SDimitry Andric 
65855e4f9d5SDimitry Andric     TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {
65955e4f9d5SDimitry Andric       return Visit(T.getUnqualifiedLoc());
66055e4f9d5SDimitry Andric     }
66155e4f9d5SDimitry Andric 
66255e4f9d5SDimitry Andric     TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) {
66355e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
66455e4f9d5SDimitry Andric     }
66555e4f9d5SDimitry Andric 
66655e4f9d5SDimitry Andric     TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) {
66755e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
66855e4f9d5SDimitry Andric     }
66955e4f9d5SDimitry Andric 
67055e4f9d5SDimitry Andric     TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) {
67155e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
67255e4f9d5SDimitry Andric     }
67355e4f9d5SDimitry Andric 
67455e4f9d5SDimitry Andric     TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) {
67555e4f9d5SDimitry Andric       return Visit(T.getPointeeLoc());
67655e4f9d5SDimitry Andric     }
67755e4f9d5SDimitry Andric 
67855e4f9d5SDimitry Andric     TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) {
67955e4f9d5SDimitry Andric       return Visit(T.getElementLoc());
68055e4f9d5SDimitry Andric     }
68155e4f9d5SDimitry Andric 
68255e4f9d5SDimitry Andric     TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) {
68355e4f9d5SDimitry Andric       return Visit(T.getReturnLoc());
68455e4f9d5SDimitry Andric     }
68555e4f9d5SDimitry Andric 
68655e4f9d5SDimitry Andric     TypeLoc VisitParenTypeLoc(ParenTypeLoc T) {
68755e4f9d5SDimitry Andric       return Visit(T.getInnerLoc());
68855e4f9d5SDimitry Andric     }
68955e4f9d5SDimitry Andric 
69055e4f9d5SDimitry Andric     TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) {
69155e4f9d5SDimitry Andric       return Visit(T.getModifiedLoc());
69255e4f9d5SDimitry Andric     }
69355e4f9d5SDimitry Andric 
69481ad6265SDimitry Andric     TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) {
69581ad6265SDimitry Andric       return Visit(T.getWrappedLoc());
69681ad6265SDimitry Andric     }
69781ad6265SDimitry Andric 
69855e4f9d5SDimitry Andric     TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
69955e4f9d5SDimitry Andric       return Visit(T.getInnerLoc());
70055e4f9d5SDimitry Andric     }
70155e4f9d5SDimitry Andric 
70255e4f9d5SDimitry Andric     TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) {
70355e4f9d5SDimitry Andric       return Visit(T.getOriginalLoc());
70455e4f9d5SDimitry Andric     }
70555e4f9d5SDimitry Andric 
70655e4f9d5SDimitry Andric     TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) {
70755e4f9d5SDimitry Andric       return Visit(T.getPatternLoc());
70855e4f9d5SDimitry Andric     }
70955e4f9d5SDimitry Andric   };
71055e4f9d5SDimitry Andric 
71155e4f9d5SDimitry Andric } // namespace
71255e4f9d5SDimitry Andric 
71355e4f9d5SDimitry Andric AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
71455e4f9d5SDimitry Andric   TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this);
71555e4f9d5SDimitry Andric   if (Res.isNull())
71655e4f9d5SDimitry Andric     return AutoTypeLoc();
71755e4f9d5SDimitry Andric   return Res.getAs<AutoTypeLoc>();
71855e4f9d5SDimitry Andric }
719