TypeLoc.cpp 17 KB

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