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