TypeLoc.cpp 16 KB

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