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: 1970b57cec5SDimitry Andric LeftMost = Cur; 1980b57cec5SDimitry Andric break; 1990b57cec5SDimitry Andric case FunctionProto: 2000b57cec5SDimitry Andric if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr() 2010b57cec5SDimitry Andric ->hasTrailingReturn()) { 2020b57cec5SDimitry Andric LeftMost = Cur; 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric LLVM_FALLTHROUGH; 2060b57cec5SDimitry Andric case FunctionNoProto: 2070b57cec5SDimitry Andric case ConstantArray: 2080b57cec5SDimitry Andric case DependentSizedArray: 2090b57cec5SDimitry Andric case IncompleteArray: 2100b57cec5SDimitry Andric case VariableArray: 2110b57cec5SDimitry Andric // FIXME: Currently QualifiedTypeLoc does not have a source range 2120b57cec5SDimitry Andric case Qualified: 2130b57cec5SDimitry Andric Cur = Cur.getNextTypeLoc(); 2140b57cec5SDimitry Andric continue; 2150b57cec5SDimitry Andric default: 2160b57cec5SDimitry Andric if (Cur.getLocalSourceRange().getBegin().isValid()) 2170b57cec5SDimitry Andric LeftMost = Cur; 2180b57cec5SDimitry Andric Cur = Cur.getNextTypeLoc(); 2190b57cec5SDimitry Andric if (Cur.isNull()) 2200b57cec5SDimitry Andric break; 2210b57cec5SDimitry Andric continue; 2220b57cec5SDimitry Andric } // switch 2230b57cec5SDimitry Andric break; 2240b57cec5SDimitry Andric } // while 2250b57cec5SDimitry Andric return LeftMost.getLocalSourceRange().getBegin(); 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric SourceLocation TypeLoc::getEndLoc() const { 2290b57cec5SDimitry Andric TypeLoc Cur = *this; 2300b57cec5SDimitry Andric TypeLoc Last; 2310b57cec5SDimitry Andric while (true) { 2320b57cec5SDimitry Andric switch (Cur.getTypeLocClass()) { 2330b57cec5SDimitry Andric default: 2340b57cec5SDimitry Andric if (!Last) 2350b57cec5SDimitry Andric Last = Cur; 2360b57cec5SDimitry Andric return Last.getLocalSourceRange().getEnd(); 2370b57cec5SDimitry Andric case Paren: 2380b57cec5SDimitry Andric case ConstantArray: 2390b57cec5SDimitry Andric case DependentSizedArray: 2400b57cec5SDimitry Andric case IncompleteArray: 2410b57cec5SDimitry Andric case VariableArray: 2420b57cec5SDimitry Andric case FunctionNoProto: 2430b57cec5SDimitry Andric Last = Cur; 2440b57cec5SDimitry Andric break; 2450b57cec5SDimitry Andric case FunctionProto: 2460b57cec5SDimitry Andric if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn()) 2470b57cec5SDimitry Andric Last = TypeLoc(); 2480b57cec5SDimitry Andric else 2490b57cec5SDimitry Andric Last = Cur; 2500b57cec5SDimitry Andric break; 2510b57cec5SDimitry Andric case Pointer: 2520b57cec5SDimitry Andric case BlockPointer: 2530b57cec5SDimitry Andric case MemberPointer: 2540b57cec5SDimitry Andric case LValueReference: 2550b57cec5SDimitry Andric case RValueReference: 2560b57cec5SDimitry Andric case PackExpansion: 2570b57cec5SDimitry Andric if (!Last) 2580b57cec5SDimitry Andric Last = Cur; 2590b57cec5SDimitry Andric break; 2600b57cec5SDimitry Andric case Qualified: 2610b57cec5SDimitry Andric case Elaborated: 2620b57cec5SDimitry Andric break; 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric Cur = Cur.getNextTypeLoc(); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric namespace { 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> { 2710b57cec5SDimitry Andric // Overload resolution does the real work for us. 2720b57cec5SDimitry Andric static bool isTypeSpec(TypeSpecTypeLoc _) { return true; } 2730b57cec5SDimitry Andric static bool isTypeSpec(TypeLoc _) { return false; } 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric #define ABSTRACT_TYPELOC(CLASS, PARENT) 2760b57cec5SDimitry Andric #define TYPELOC(CLASS, PARENT) \ 2770b57cec5SDimitry Andric bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ 2780b57cec5SDimitry Andric return isTypeSpec(TyLoc); \ 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric #include "clang/AST/TypeLocNodes.def" 2810b57cec5SDimitry Andric }; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric } // namespace 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric /// Determines if the given type loc corresponds to a 2860b57cec5SDimitry Andric /// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in 2870b57cec5SDimitry Andric /// the type hierarchy, this is made somewhat complicated. 2880b57cec5SDimitry Andric /// 2890b57cec5SDimitry Andric /// There are a lot of types that currently use TypeSpecTypeLoc 2900b57cec5SDimitry Andric /// because it's a convenient base class. Ideally we would not accept 2910b57cec5SDimitry Andric /// those here, but ideally we would have better implementations for 2920b57cec5SDimitry Andric /// them. 2930b57cec5SDimitry Andric bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) { 2940b57cec5SDimitry Andric if (TL.getType().hasLocalQualifiers()) return false; 2950b57cec5SDimitry Andric return TSTChecker().Visit(TL); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 298480093f4SDimitry Andric bool TagTypeLoc::isDefinition() const { 299480093f4SDimitry Andric TagDecl *D = getDecl(); 300480093f4SDimitry Andric return D->isCompleteDefinition() && 301480093f4SDimitry Andric (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc()); 302480093f4SDimitry Andric } 303480093f4SDimitry Andric 3040b57cec5SDimitry Andric // Reimplemented to account for GNU/C++ extension 3050b57cec5SDimitry Andric // typeof unary-expression 3060b57cec5SDimitry Andric // where there are no parentheses. 3070b57cec5SDimitry Andric SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const { 3080b57cec5SDimitry Andric if (getRParenLoc().isValid()) 3090b57cec5SDimitry Andric return SourceRange(getTypeofLoc(), getRParenLoc()); 3100b57cec5SDimitry Andric else 3110b57cec5SDimitry Andric return SourceRange(getTypeofLoc(), 3120b57cec5SDimitry Andric getUnderlyingExpr()->getSourceRange().getEnd()); 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { 3170b57cec5SDimitry Andric if (needsExtraLocalData()) 3180b57cec5SDimitry Andric return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type); 3190b57cec5SDimitry Andric switch (getTypePtr()->getKind()) { 3200b57cec5SDimitry Andric case BuiltinType::Void: 3210b57cec5SDimitry Andric return TST_void; 3220b57cec5SDimitry Andric case BuiltinType::Bool: 3230b57cec5SDimitry Andric return TST_bool; 3240b57cec5SDimitry Andric case BuiltinType::Char_U: 3250b57cec5SDimitry Andric case BuiltinType::Char_S: 3260b57cec5SDimitry Andric return TST_char; 3270b57cec5SDimitry Andric case BuiltinType::Char8: 3280b57cec5SDimitry Andric return TST_char8; 3290b57cec5SDimitry Andric case BuiltinType::Char16: 3300b57cec5SDimitry Andric return TST_char16; 3310b57cec5SDimitry Andric case BuiltinType::Char32: 3320b57cec5SDimitry Andric return TST_char32; 3330b57cec5SDimitry Andric case BuiltinType::WChar_S: 3340b57cec5SDimitry Andric case BuiltinType::WChar_U: 3350b57cec5SDimitry Andric return TST_wchar; 3360b57cec5SDimitry Andric case BuiltinType::UChar: 3370b57cec5SDimitry Andric case BuiltinType::UShort: 3380b57cec5SDimitry Andric case BuiltinType::UInt: 3390b57cec5SDimitry Andric case BuiltinType::ULong: 3400b57cec5SDimitry Andric case BuiltinType::ULongLong: 3410b57cec5SDimitry Andric case BuiltinType::UInt128: 3420b57cec5SDimitry Andric case BuiltinType::SChar: 3430b57cec5SDimitry Andric case BuiltinType::Short: 3440b57cec5SDimitry Andric case BuiltinType::Int: 3450b57cec5SDimitry Andric case BuiltinType::Long: 3460b57cec5SDimitry Andric case BuiltinType::LongLong: 3470b57cec5SDimitry Andric case BuiltinType::Int128: 3480b57cec5SDimitry Andric case BuiltinType::Half: 3490b57cec5SDimitry Andric case BuiltinType::Float: 3500b57cec5SDimitry Andric case BuiltinType::Double: 3510b57cec5SDimitry Andric case BuiltinType::LongDouble: 3520b57cec5SDimitry Andric case BuiltinType::Float16: 3530b57cec5SDimitry Andric case BuiltinType::Float128: 3540b57cec5SDimitry Andric case BuiltinType::ShortAccum: 3550b57cec5SDimitry Andric case BuiltinType::Accum: 3560b57cec5SDimitry Andric case BuiltinType::LongAccum: 3570b57cec5SDimitry Andric case BuiltinType::UShortAccum: 3580b57cec5SDimitry Andric case BuiltinType::UAccum: 3590b57cec5SDimitry Andric case BuiltinType::ULongAccum: 3600b57cec5SDimitry Andric case BuiltinType::ShortFract: 3610b57cec5SDimitry Andric case BuiltinType::Fract: 3620b57cec5SDimitry Andric case BuiltinType::LongFract: 3630b57cec5SDimitry Andric case BuiltinType::UShortFract: 3640b57cec5SDimitry Andric case BuiltinType::UFract: 3650b57cec5SDimitry Andric case BuiltinType::ULongFract: 3660b57cec5SDimitry Andric case BuiltinType::SatShortAccum: 3670b57cec5SDimitry Andric case BuiltinType::SatAccum: 3680b57cec5SDimitry Andric case BuiltinType::SatLongAccum: 3690b57cec5SDimitry Andric case BuiltinType::SatUShortAccum: 3700b57cec5SDimitry Andric case BuiltinType::SatUAccum: 3710b57cec5SDimitry Andric case BuiltinType::SatULongAccum: 3720b57cec5SDimitry Andric case BuiltinType::SatShortFract: 3730b57cec5SDimitry Andric case BuiltinType::SatFract: 3740b57cec5SDimitry Andric case BuiltinType::SatLongFract: 3750b57cec5SDimitry Andric case BuiltinType::SatUShortFract: 3760b57cec5SDimitry Andric case BuiltinType::SatUFract: 3770b57cec5SDimitry Andric case BuiltinType::SatULongFract: 3780b57cec5SDimitry Andric llvm_unreachable("Builtin type needs extra local data!"); 3790b57cec5SDimitry Andric // Fall through, if the impossible happens. 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric case BuiltinType::NullPtr: 3820b57cec5SDimitry Andric case BuiltinType::Overload: 3830b57cec5SDimitry Andric case BuiltinType::Dependent: 3840b57cec5SDimitry Andric case BuiltinType::BoundMember: 3850b57cec5SDimitry Andric case BuiltinType::UnknownAny: 3860b57cec5SDimitry Andric case BuiltinType::ARCUnbridgedCast: 3870b57cec5SDimitry Andric case BuiltinType::PseudoObject: 3880b57cec5SDimitry Andric case BuiltinType::ObjCId: 3890b57cec5SDimitry Andric case BuiltinType::ObjCClass: 3900b57cec5SDimitry Andric case BuiltinType::ObjCSel: 3910b57cec5SDimitry Andric #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 3920b57cec5SDimitry Andric case BuiltinType::Id: 3930b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 3940b57cec5SDimitry Andric #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 3950b57cec5SDimitry Andric case BuiltinType::Id: 3960b57cec5SDimitry Andric #include "clang/Basic/OpenCLExtensionTypes.def" 3970b57cec5SDimitry Andric case BuiltinType::OCLSampler: 3980b57cec5SDimitry Andric case BuiltinType::OCLEvent: 3990b57cec5SDimitry Andric case BuiltinType::OCLClkEvent: 4000b57cec5SDimitry Andric case BuiltinType::OCLQueue: 4010b57cec5SDimitry Andric case BuiltinType::OCLReserveID: 402a7dea167SDimitry Andric #define SVE_TYPE(Name, Id, SingletonId) \ 403a7dea167SDimitry Andric case BuiltinType::Id: 404a7dea167SDimitry Andric #include "clang/Basic/AArch64SVEACLETypes.def" 4050b57cec5SDimitry Andric case BuiltinType::BuiltinFn: 4060b57cec5SDimitry Andric case BuiltinType::OMPArraySection: 4070b57cec5SDimitry Andric return TST_unspecified; 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric llvm_unreachable("Invalid BuiltinType Kind!"); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { 4140b57cec5SDimitry Andric while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>()) 4150b57cec5SDimitry Andric TL = PTL.getInnerLoc(); 4160b57cec5SDimitry Andric return TL; 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric SourceLocation TypeLoc::findNullabilityLoc() const { 4200b57cec5SDimitry Andric if (auto ATL = getAs<AttributedTypeLoc>()) { 4210b57cec5SDimitry Andric const Attr *A = ATL.getAttr(); 4220b57cec5SDimitry Andric if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) || 4230b57cec5SDimitry Andric isa<TypeNullUnspecifiedAttr>(A))) 4240b57cec5SDimitry Andric return A->getLocation(); 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric return {}; 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric TypeLoc TypeLoc::findExplicitQualifierLoc() const { 4310b57cec5SDimitry Andric // Qualified types. 4320b57cec5SDimitry Andric if (auto qual = getAs<QualifiedTypeLoc>()) 4330b57cec5SDimitry Andric return qual; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric TypeLoc loc = IgnoreParens(); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric // Attributed types. 4380b57cec5SDimitry Andric if (auto attr = loc.getAs<AttributedTypeLoc>()) { 4390b57cec5SDimitry Andric if (attr.isQualifier()) return attr; 4400b57cec5SDimitry Andric return attr.getModifiedLoc().findExplicitQualifierLoc(); 4410b57cec5SDimitry Andric } 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // C11 _Atomic types. 4440b57cec5SDimitry Andric if (auto atomic = loc.getAs<AtomicTypeLoc>()) { 4450b57cec5SDimitry Andric return atomic; 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric return {}; 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context, 4520b57cec5SDimitry Andric SourceLocation Loc) { 4530b57cec5SDimitry Andric setNameLoc(Loc); 4540b57cec5SDimitry Andric if (!getNumProtocols()) return; 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric setProtocolLAngleLoc(Loc); 4570b57cec5SDimitry Andric setProtocolRAngleLoc(Loc); 4580b57cec5SDimitry Andric for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 4590b57cec5SDimitry Andric setProtocolLoc(i, Loc); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context, 4630b57cec5SDimitry Andric SourceLocation Loc) { 4640b57cec5SDimitry Andric setHasBaseTypeAsWritten(true); 4650b57cec5SDimitry Andric setTypeArgsLAngleLoc(Loc); 4660b57cec5SDimitry Andric setTypeArgsRAngleLoc(Loc); 4670b57cec5SDimitry Andric for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) { 4680b57cec5SDimitry Andric setTypeArgTInfo(i, 4690b57cec5SDimitry Andric Context.getTrivialTypeSourceInfo( 4700b57cec5SDimitry Andric getTypePtr()->getTypeArgsAsWritten()[i], Loc)); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric setProtocolLAngleLoc(Loc); 4730b57cec5SDimitry Andric setProtocolRAngleLoc(Loc); 4740b57cec5SDimitry Andric for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 4750b57cec5SDimitry Andric setProtocolLoc(i, Loc); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 478480093f4SDimitry Andric SourceRange AttributedTypeLoc::getLocalSourceRange() const { 479480093f4SDimitry Andric // Note that this does *not* include the range of the attribute 480480093f4SDimitry Andric // enclosure, e.g.: 481480093f4SDimitry Andric // __attribute__((foo(bar))) 482480093f4SDimitry Andric // ^~~~~~~~~~~~~~~ ~~ 483480093f4SDimitry Andric // or 484480093f4SDimitry Andric // [[foo(bar)]] 485480093f4SDimitry Andric // ^~ ~~ 486480093f4SDimitry Andric // That enclosure doesn't necessarily belong to a single attribute 487480093f4SDimitry Andric // anyway. 488480093f4SDimitry Andric return getAttr() ? getAttr()->getRange() : SourceRange(); 489480093f4SDimitry Andric } 490480093f4SDimitry Andric 4910b57cec5SDimitry Andric void TypeOfTypeLoc::initializeLocal(ASTContext &Context, 4920b57cec5SDimitry Andric SourceLocation Loc) { 4930b57cec5SDimitry Andric TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> 4940b57cec5SDimitry Andric ::initializeLocal(Context, Loc); 4950b57cec5SDimitry Andric this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo( 4960b57cec5SDimitry Andric getUnderlyingType(), Loc); 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context, 5000b57cec5SDimitry Andric SourceLocation Loc) { 5010b57cec5SDimitry Andric setKWLoc(Loc); 5020b57cec5SDimitry Andric setRParenLoc(Loc); 5030b57cec5SDimitry Andric setLParenLoc(Loc); 5040b57cec5SDimitry Andric this->setUnderlyingTInfo( 5050b57cec5SDimitry Andric Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc)); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 5090b57cec5SDimitry Andric SourceLocation Loc) { 5100b57cec5SDimitry Andric setElaboratedKeywordLoc(Loc); 5110b57cec5SDimitry Andric NestedNameSpecifierLocBuilder Builder; 5120b57cec5SDimitry Andric Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); 5130b57cec5SDimitry Andric setQualifierLoc(Builder.getWithLocInContext(Context)); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric void DependentNameTypeLoc::initializeLocal(ASTContext &Context, 5170b57cec5SDimitry Andric SourceLocation Loc) { 5180b57cec5SDimitry Andric setElaboratedKeywordLoc(Loc); 5190b57cec5SDimitry Andric NestedNameSpecifierLocBuilder Builder; 5200b57cec5SDimitry Andric Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); 5210b57cec5SDimitry Andric setQualifierLoc(Builder.getWithLocInContext(Context)); 5220b57cec5SDimitry Andric setNameLoc(Loc); 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric void 5260b57cec5SDimitry Andric DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context, 5270b57cec5SDimitry Andric SourceLocation Loc) { 5280b57cec5SDimitry Andric setElaboratedKeywordLoc(Loc); 5290b57cec5SDimitry Andric if (getTypePtr()->getQualifier()) { 5300b57cec5SDimitry Andric NestedNameSpecifierLocBuilder Builder; 5310b57cec5SDimitry Andric Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); 5320b57cec5SDimitry Andric setQualifierLoc(Builder.getWithLocInContext(Context)); 5330b57cec5SDimitry Andric } else { 5340b57cec5SDimitry Andric setQualifierLoc(NestedNameSpecifierLoc()); 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric setTemplateKeywordLoc(Loc); 5370b57cec5SDimitry Andric setTemplateNameLoc(Loc); 5380b57cec5SDimitry Andric setLAngleLoc(Loc); 5390b57cec5SDimitry Andric setRAngleLoc(Loc); 5400b57cec5SDimitry Andric TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(), 5410b57cec5SDimitry Andric getTypePtr()->getArgs(), 5420b57cec5SDimitry Andric getArgInfos(), Loc); 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, 5460b57cec5SDimitry Andric unsigned NumArgs, 5470b57cec5SDimitry Andric const TemplateArgument *Args, 5480b57cec5SDimitry Andric TemplateArgumentLocInfo *ArgInfos, 5490b57cec5SDimitry Andric SourceLocation Loc) { 5500b57cec5SDimitry Andric for (unsigned i = 0, e = NumArgs; i != e; ++i) { 5510b57cec5SDimitry Andric switch (Args[i].getKind()) { 5520b57cec5SDimitry Andric case TemplateArgument::Null: 5530b57cec5SDimitry Andric llvm_unreachable("Impossible TemplateArgument"); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric case TemplateArgument::Integral: 5560b57cec5SDimitry Andric case TemplateArgument::Declaration: 5570b57cec5SDimitry Andric case TemplateArgument::NullPtr: 5580b57cec5SDimitry Andric ArgInfos[i] = TemplateArgumentLocInfo(); 5590b57cec5SDimitry Andric break; 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric case TemplateArgument::Expression: 5620b57cec5SDimitry Andric ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr()); 5630b57cec5SDimitry Andric break; 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric case TemplateArgument::Type: 5660b57cec5SDimitry Andric ArgInfos[i] = TemplateArgumentLocInfo( 5670b57cec5SDimitry Andric Context.getTrivialTypeSourceInfo(Args[i].getAsType(), 5680b57cec5SDimitry Andric Loc)); 5690b57cec5SDimitry Andric break; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric case TemplateArgument::Template: 5720b57cec5SDimitry Andric case TemplateArgument::TemplateExpansion: { 5730b57cec5SDimitry Andric NestedNameSpecifierLocBuilder Builder; 5740b57cec5SDimitry Andric TemplateName Template = Args[i].getAsTemplateOrTemplatePattern(); 5750b57cec5SDimitry Andric if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) 5760b57cec5SDimitry Andric Builder.MakeTrivial(Context, DTN->getQualifier(), Loc); 5770b57cec5SDimitry Andric else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) 5780b57cec5SDimitry Andric Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric ArgInfos[i] = TemplateArgumentLocInfo( 5810b57cec5SDimitry Andric Builder.getWithLocInContext(Context), Loc, 5820b57cec5SDimitry Andric Args[i].getKind() == TemplateArgument::Template ? SourceLocation() 5830b57cec5SDimitry Andric : Loc); 5840b57cec5SDimitry Andric break; 5850b57cec5SDimitry Andric } 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric case TemplateArgument::Pack: 5880b57cec5SDimitry Andric ArgInfos[i] = TemplateArgumentLocInfo(); 5890b57cec5SDimitry Andric break; 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric } 59355e4f9d5SDimitry Andric 59455e4f9d5SDimitry Andric DeclarationNameInfo AutoTypeLoc::getConceptNameInfo() const { 59555e4f9d5SDimitry Andric return DeclarationNameInfo(getNamedConcept()->getDeclName(), 59655e4f9d5SDimitry Andric getLocalData()->ConceptNameLoc); 59755e4f9d5SDimitry Andric } 59855e4f9d5SDimitry Andric 59955e4f9d5SDimitry Andric void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) { 60055e4f9d5SDimitry Andric setNestedNameSpecifierLoc(NestedNameSpecifierLoc()); 60155e4f9d5SDimitry Andric setTemplateKWLoc(Loc); 60255e4f9d5SDimitry Andric setConceptNameLoc(Loc); 60355e4f9d5SDimitry Andric setFoundDecl(nullptr); 60455e4f9d5SDimitry Andric setRAngleLoc(Loc); 60555e4f9d5SDimitry Andric setLAngleLoc(Loc); 60655e4f9d5SDimitry Andric TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(), 60755e4f9d5SDimitry Andric getTypePtr()->getArgs(), 60855e4f9d5SDimitry Andric getArgInfos(), Loc); 60955e4f9d5SDimitry Andric setNameLoc(Loc); 61055e4f9d5SDimitry Andric } 61155e4f9d5SDimitry Andric 61255e4f9d5SDimitry Andric 61355e4f9d5SDimitry Andric namespace { 61455e4f9d5SDimitry Andric 61555e4f9d5SDimitry Andric class GetContainedAutoTypeLocVisitor : 61655e4f9d5SDimitry Andric public TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc> { 61755e4f9d5SDimitry Andric public: 61855e4f9d5SDimitry Andric using TypeLocVisitor<GetContainedAutoTypeLocVisitor, TypeLoc>::Visit; 61955e4f9d5SDimitry Andric 62055e4f9d5SDimitry Andric TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) { 62155e4f9d5SDimitry Andric return TL; 62255e4f9d5SDimitry Andric } 62355e4f9d5SDimitry Andric 62455e4f9d5SDimitry Andric // Only these types can contain the desired 'auto' type. 62555e4f9d5SDimitry Andric 62655e4f9d5SDimitry Andric TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) { 62755e4f9d5SDimitry Andric return Visit(T.getNamedTypeLoc()); 62855e4f9d5SDimitry Andric } 62955e4f9d5SDimitry Andric 63055e4f9d5SDimitry Andric TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) { 63155e4f9d5SDimitry Andric return Visit(T.getUnqualifiedLoc()); 63255e4f9d5SDimitry Andric } 63355e4f9d5SDimitry Andric 63455e4f9d5SDimitry Andric TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) { 63555e4f9d5SDimitry Andric return Visit(T.getPointeeLoc()); 63655e4f9d5SDimitry Andric } 63755e4f9d5SDimitry Andric 63855e4f9d5SDimitry Andric TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) { 63955e4f9d5SDimitry Andric return Visit(T.getPointeeLoc()); 64055e4f9d5SDimitry Andric } 64155e4f9d5SDimitry Andric 64255e4f9d5SDimitry Andric TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) { 64355e4f9d5SDimitry Andric return Visit(T.getPointeeLoc()); 64455e4f9d5SDimitry Andric } 64555e4f9d5SDimitry Andric 64655e4f9d5SDimitry Andric TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) { 64755e4f9d5SDimitry Andric return Visit(T.getPointeeLoc()); 64855e4f9d5SDimitry Andric } 64955e4f9d5SDimitry Andric 65055e4f9d5SDimitry Andric TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) { 65155e4f9d5SDimitry Andric return Visit(T.getElementLoc()); 65255e4f9d5SDimitry Andric } 65355e4f9d5SDimitry Andric 65455e4f9d5SDimitry Andric TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) { 65555e4f9d5SDimitry Andric return Visit(T.getReturnLoc()); 65655e4f9d5SDimitry Andric } 65755e4f9d5SDimitry Andric 65855e4f9d5SDimitry Andric TypeLoc VisitParenTypeLoc(ParenTypeLoc T) { 65955e4f9d5SDimitry Andric return Visit(T.getInnerLoc()); 66055e4f9d5SDimitry Andric } 66155e4f9d5SDimitry Andric 66255e4f9d5SDimitry Andric TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) { 66355e4f9d5SDimitry Andric return Visit(T.getModifiedLoc()); 66455e4f9d5SDimitry Andric } 66555e4f9d5SDimitry Andric 66655e4f9d5SDimitry Andric TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) { 66755e4f9d5SDimitry Andric return Visit(T.getInnerLoc()); 66855e4f9d5SDimitry Andric } 66955e4f9d5SDimitry Andric 67055e4f9d5SDimitry Andric TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) { 67155e4f9d5SDimitry Andric return Visit(T.getOriginalLoc()); 67255e4f9d5SDimitry Andric } 67355e4f9d5SDimitry Andric 67455e4f9d5SDimitry Andric TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) { 67555e4f9d5SDimitry Andric return Visit(T.getPatternLoc()); 67655e4f9d5SDimitry Andric } 67755e4f9d5SDimitry Andric }; 67855e4f9d5SDimitry Andric 67955e4f9d5SDimitry Andric } // namespace 68055e4f9d5SDimitry Andric 68155e4f9d5SDimitry Andric AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const { 68255e4f9d5SDimitry Andric TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this); 68355e4f9d5SDimitry Andric if (Res.isNull()) 68455e4f9d5SDimitry Andric return AutoTypeLoc(); 68555e4f9d5SDimitry Andric return Res.getAs<AutoTypeLoc>(); 68655e4f9d5SDimitry Andric } 687