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