TemplateBase.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file provides definitions which are common for all kinds of
  15. // template representation.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
  19. #define LLVM_CLANG_AST_TEMPLATEBASE_H
  20. #include "clang/AST/DependenceFlags.h"
  21. #include "clang/AST/NestedNameSpecifier.h"
  22. #include "clang/AST/TemplateName.h"
  23. #include "clang/AST/Type.h"
  24. #include "clang/Basic/LLVM.h"
  25. #include "clang/Basic/SourceLocation.h"
  26. #include "llvm/ADT/APInt.h"
  27. #include "llvm/ADT/APSInt.h"
  28. #include "llvm/ADT/ArrayRef.h"
  29. #include "llvm/ADT/SmallVector.h"
  30. #include "llvm/Support/Compiler.h"
  31. #include "llvm/Support/TrailingObjects.h"
  32. #include <cassert>
  33. #include <cstddef>
  34. #include <cstdint>
  35. #include <optional>
  36. namespace llvm {
  37. class FoldingSetNodeID;
  38. // Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
  39. // full definition of Expr, but this file only sees a forward del because of
  40. // the dependency.
  41. template <> struct PointerLikeTypeTraits<clang::Expr *> {
  42. static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
  43. static inline clang::Expr *getFromVoidPointer(void *P) {
  44. return static_cast<clang::Expr *>(P);
  45. }
  46. static constexpr int NumLowBitsAvailable = 2;
  47. };
  48. } // namespace llvm
  49. namespace clang {
  50. class ASTContext;
  51. class Expr;
  52. struct PrintingPolicy;
  53. class TypeSourceInfo;
  54. class ValueDecl;
  55. /// Represents a template argument.
  56. class TemplateArgument {
  57. public:
  58. /// The kind of template argument we're storing.
  59. enum ArgKind {
  60. /// Represents an empty template argument, e.g., one that has not
  61. /// been deduced.
  62. Null = 0,
  63. /// The template argument is a type.
  64. Type,
  65. /// The template argument is a declaration that was provided for a pointer,
  66. /// reference, or pointer to member non-type template parameter.
  67. Declaration,
  68. /// The template argument is a null pointer or null pointer to member that
  69. /// was provided for a non-type template parameter.
  70. NullPtr,
  71. /// The template argument is an integral value stored in an llvm::APSInt
  72. /// that was provided for an integral non-type template parameter.
  73. Integral,
  74. /// The template argument is a template name that was provided for a
  75. /// template template parameter.
  76. Template,
  77. /// The template argument is a pack expansion of a template name that was
  78. /// provided for a template template parameter.
  79. TemplateExpansion,
  80. /// The template argument is an expression, and we've not resolved it to one
  81. /// of the other forms yet, either because it's dependent or because we're
  82. /// representing a non-canonical template argument (for instance, in a
  83. /// TemplateSpecializationType).
  84. Expression,
  85. /// The template argument is actually a parameter pack. Arguments are stored
  86. /// in the Args struct.
  87. Pack
  88. };
  89. private:
  90. /// The kind of template argument we're storing.
  91. struct DA {
  92. unsigned Kind;
  93. void *QT;
  94. ValueDecl *D;
  95. };
  96. struct I {
  97. unsigned Kind;
  98. // We store a decomposed APSInt with the data allocated by ASTContext if
  99. // BitWidth > 64. The memory may be shared between multiple
  100. // TemplateArgument instances.
  101. unsigned BitWidth : 31;
  102. unsigned IsUnsigned : 1;
  103. union {
  104. /// Used to store the <= 64 bits integer value.
  105. uint64_t VAL;
  106. /// Used to store the >64 bits integer value.
  107. const uint64_t *pVal;
  108. };
  109. void *Type;
  110. };
  111. struct A {
  112. unsigned Kind;
  113. unsigned NumArgs;
  114. const TemplateArgument *Args;
  115. };
  116. struct TA {
  117. unsigned Kind;
  118. unsigned NumExpansions;
  119. void *Name;
  120. };
  121. struct TV {
  122. unsigned Kind;
  123. uintptr_t V;
  124. };
  125. union {
  126. struct DA DeclArg;
  127. struct I Integer;
  128. struct A Args;
  129. struct TA TemplateArg;
  130. struct TV TypeOrValue;
  131. };
  132. public:
  133. /// Construct an empty, invalid template argument.
  134. constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
  135. /// Construct a template type argument.
  136. TemplateArgument(QualType T, bool isNullPtr = false) {
  137. TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
  138. TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
  139. }
  140. /// Construct a template argument that refers to a
  141. /// declaration, which is either an external declaration or a
  142. /// template declaration.
  143. TemplateArgument(ValueDecl *D, QualType QT) {
  144. assert(D && "Expected decl");
  145. DeclArg.Kind = Declaration;
  146. DeclArg.QT = QT.getAsOpaquePtr();
  147. DeclArg.D = D;
  148. }
  149. /// Construct an integral constant template argument. The memory to
  150. /// store the value is allocated with Ctx.
  151. TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
  152. /// Construct an integral constant template argument with the same
  153. /// value as Other but a different type.
  154. TemplateArgument(const TemplateArgument &Other, QualType Type) {
  155. Integer = Other.Integer;
  156. Integer.Type = Type.getAsOpaquePtr();
  157. }
  158. /// Construct a template argument that is a template.
  159. ///
  160. /// This form of template argument is generally used for template template
  161. /// parameters. However, the template name could be a dependent template
  162. /// name that ends up being instantiated to a function template whose address
  163. /// is taken.
  164. ///
  165. /// \param Name The template name.
  166. TemplateArgument(TemplateName Name) {
  167. TemplateArg.Kind = Template;
  168. TemplateArg.Name = Name.getAsVoidPointer();
  169. TemplateArg.NumExpansions = 0;
  170. }
  171. /// Construct a template argument that is a template pack expansion.
  172. ///
  173. /// This form of template argument is generally used for template template
  174. /// parameters. However, the template name could be a dependent template
  175. /// name that ends up being instantiated to a function template whose address
  176. /// is taken.
  177. ///
  178. /// \param Name The template name.
  179. ///
  180. /// \param NumExpansions The number of expansions that will be generated by
  181. /// instantiating
  182. TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions) {
  183. TemplateArg.Kind = TemplateExpansion;
  184. TemplateArg.Name = Name.getAsVoidPointer();
  185. if (NumExpansions)
  186. TemplateArg.NumExpansions = *NumExpansions + 1;
  187. else
  188. TemplateArg.NumExpansions = 0;
  189. }
  190. /// Construct a template argument that is an expression.
  191. ///
  192. /// This form of template argument only occurs in template argument
  193. /// lists used for dependent types and for expression; it will not
  194. /// occur in a non-dependent, canonical template argument list.
  195. TemplateArgument(Expr *E) {
  196. TypeOrValue.Kind = Expression;
  197. TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
  198. }
  199. /// Construct a template argument that is a template argument pack.
  200. ///
  201. /// We assume that storage for the template arguments provided
  202. /// outlives the TemplateArgument itself.
  203. explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
  204. this->Args.Kind = Pack;
  205. this->Args.Args = Args.data();
  206. this->Args.NumArgs = Args.size();
  207. }
  208. TemplateArgument(TemplateName, bool) = delete;
  209. static TemplateArgument getEmptyPack() {
  210. return TemplateArgument(std::nullopt);
  211. }
  212. /// Create a new template argument pack by copying the given set of
  213. /// template arguments.
  214. static TemplateArgument CreatePackCopy(ASTContext &Context,
  215. ArrayRef<TemplateArgument> Args);
  216. /// Return the kind of stored template argument.
  217. ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
  218. /// Determine whether this template argument has no value.
  219. bool isNull() const { return getKind() == Null; }
  220. TemplateArgumentDependence getDependence() const;
  221. /// Whether this template argument is dependent on a template
  222. /// parameter such that its result can change from one instantiation to
  223. /// another.
  224. bool isDependent() const;
  225. /// Whether this template argument is dependent on a template
  226. /// parameter.
  227. bool isInstantiationDependent() const;
  228. /// Whether this template argument contains an unexpanded
  229. /// parameter pack.
  230. bool containsUnexpandedParameterPack() const;
  231. /// Determine whether this template argument is a pack expansion.
  232. bool isPackExpansion() const;
  233. /// Retrieve the type for a type template argument.
  234. QualType getAsType() const {
  235. assert(getKind() == Type && "Unexpected kind");
  236. return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
  237. }
  238. /// Retrieve the declaration for a declaration non-type
  239. /// template argument.
  240. ValueDecl *getAsDecl() const {
  241. assert(getKind() == Declaration && "Unexpected kind");
  242. return DeclArg.D;
  243. }
  244. QualType getParamTypeForDecl() const {
  245. assert(getKind() == Declaration && "Unexpected kind");
  246. return QualType::getFromOpaquePtr(DeclArg.QT);
  247. }
  248. /// Retrieve the type for null non-type template argument.
  249. QualType getNullPtrType() const {
  250. assert(getKind() == NullPtr && "Unexpected kind");
  251. return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
  252. }
  253. /// Retrieve the template name for a template name argument.
  254. TemplateName getAsTemplate() const {
  255. assert(getKind() == Template && "Unexpected kind");
  256. return TemplateName::getFromVoidPointer(TemplateArg.Name);
  257. }
  258. /// Retrieve the template argument as a template name; if the argument
  259. /// is a pack expansion, return the pattern as a template name.
  260. TemplateName getAsTemplateOrTemplatePattern() const {
  261. assert((getKind() == Template || getKind() == TemplateExpansion) &&
  262. "Unexpected kind");
  263. return TemplateName::getFromVoidPointer(TemplateArg.Name);
  264. }
  265. /// Retrieve the number of expansions that a template template argument
  266. /// expansion will produce, if known.
  267. std::optional<unsigned> getNumTemplateExpansions() const;
  268. /// Retrieve the template argument as an integral value.
  269. // FIXME: Provide a way to read the integral data without copying the value.
  270. llvm::APSInt getAsIntegral() const {
  271. assert(getKind() == Integral && "Unexpected kind");
  272. using namespace llvm;
  273. if (Integer.BitWidth <= 64)
  274. return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
  275. unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
  276. return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)),
  277. Integer.IsUnsigned);
  278. }
  279. /// Retrieve the type of the integral value.
  280. QualType getIntegralType() const {
  281. assert(getKind() == Integral && "Unexpected kind");
  282. return QualType::getFromOpaquePtr(Integer.Type);
  283. }
  284. void setIntegralType(QualType T) {
  285. assert(getKind() == Integral && "Unexpected kind");
  286. Integer.Type = T.getAsOpaquePtr();
  287. }
  288. /// If this is a non-type template argument, get its type. Otherwise,
  289. /// returns a null QualType.
  290. QualType getNonTypeTemplateArgumentType() const;
  291. /// Retrieve the template argument as an expression.
  292. Expr *getAsExpr() const {
  293. assert(getKind() == Expression && "Unexpected kind");
  294. return reinterpret_cast<Expr *>(TypeOrValue.V);
  295. }
  296. /// Iterator that traverses the elements of a template argument pack.
  297. using pack_iterator = const TemplateArgument *;
  298. /// Iterator referencing the first argument of a template argument
  299. /// pack.
  300. pack_iterator pack_begin() const {
  301. assert(getKind() == Pack);
  302. return Args.Args;
  303. }
  304. /// Iterator referencing one past the last argument of a template
  305. /// argument pack.
  306. pack_iterator pack_end() const {
  307. assert(getKind() == Pack);
  308. return Args.Args + Args.NumArgs;
  309. }
  310. /// Iterator range referencing all of the elements of a template
  311. /// argument pack.
  312. ArrayRef<TemplateArgument> pack_elements() const {
  313. return llvm::ArrayRef(pack_begin(), pack_end());
  314. }
  315. /// The number of template arguments in the given template argument
  316. /// pack.
  317. unsigned pack_size() const {
  318. assert(getKind() == Pack);
  319. return Args.NumArgs;
  320. }
  321. /// Return the array of arguments in this template argument pack.
  322. ArrayRef<TemplateArgument> getPackAsArray() const {
  323. assert(getKind() == Pack);
  324. return llvm::ArrayRef(Args.Args, Args.NumArgs);
  325. }
  326. /// Determines whether two template arguments are superficially the
  327. /// same.
  328. bool structurallyEquals(const TemplateArgument &Other) const;
  329. /// When the template argument is a pack expansion, returns
  330. /// the pattern of the pack expansion.
  331. TemplateArgument getPackExpansionPattern() const;
  332. /// Print this template argument to the given output stream.
  333. void print(const PrintingPolicy &Policy, raw_ostream &Out,
  334. bool IncludeType) const;
  335. /// Debugging aid that dumps the template argument.
  336. void dump(raw_ostream &Out) const;
  337. /// Debugging aid that dumps the template argument to standard error.
  338. void dump() const;
  339. /// Used to insert TemplateArguments into FoldingSets.
  340. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
  341. };
  342. /// Location information for a TemplateArgument.
  343. struct TemplateArgumentLocInfo {
  344. private:
  345. struct TemplateTemplateArgLocInfo {
  346. // FIXME: We'd like to just use the qualifier in the TemplateName,
  347. // but template arguments get canonicalized too quickly.
  348. NestedNameSpecifier *Qualifier;
  349. void *QualifierLocData;
  350. SourceLocation TemplateNameLoc;
  351. SourceLocation EllipsisLoc;
  352. };
  353. llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
  354. Pointer;
  355. TemplateTemplateArgLocInfo *getTemplate() const {
  356. return Pointer.get<TemplateTemplateArgLocInfo *>();
  357. }
  358. public:
  359. TemplateArgumentLocInfo() {}
  360. TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
  361. TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
  362. // Ctx is used for allocation -- this case is unusually large and also rare,
  363. // so we store the payload out-of-line.
  364. TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
  365. SourceLocation TemplateNameLoc,
  366. SourceLocation EllipsisLoc);
  367. TypeSourceInfo *getAsTypeSourceInfo() const {
  368. return Pointer.get<TypeSourceInfo *>();
  369. }
  370. Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
  371. NestedNameSpecifierLoc getTemplateQualifierLoc() const {
  372. const auto *Template = getTemplate();
  373. return NestedNameSpecifierLoc(Template->Qualifier,
  374. Template->QualifierLocData);
  375. }
  376. SourceLocation getTemplateNameLoc() const {
  377. return getTemplate()->TemplateNameLoc;
  378. }
  379. SourceLocation getTemplateEllipsisLoc() const {
  380. return getTemplate()->EllipsisLoc;
  381. }
  382. };
  383. /// Location wrapper for a TemplateArgument. TemplateArgument is to
  384. /// TemplateArgumentLoc as Type is to TypeLoc.
  385. class TemplateArgumentLoc {
  386. TemplateArgument Argument;
  387. TemplateArgumentLocInfo LocInfo;
  388. public:
  389. TemplateArgumentLoc() {}
  390. TemplateArgumentLoc(const TemplateArgument &Argument,
  391. TemplateArgumentLocInfo Opaque)
  392. : Argument(Argument), LocInfo(Opaque) {}
  393. TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
  394. : Argument(Argument), LocInfo(TInfo) {
  395. assert(Argument.getKind() == TemplateArgument::Type);
  396. }
  397. TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
  398. : Argument(Argument), LocInfo(E) {
  399. // Permit any kind of template argument that can be represented with an
  400. // expression.
  401. assert(Argument.getKind() == TemplateArgument::NullPtr ||
  402. Argument.getKind() == TemplateArgument::Integral ||
  403. Argument.getKind() == TemplateArgument::Declaration ||
  404. Argument.getKind() == TemplateArgument::Expression);
  405. }
  406. TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
  407. NestedNameSpecifierLoc QualifierLoc,
  408. SourceLocation TemplateNameLoc,
  409. SourceLocation EllipsisLoc = SourceLocation())
  410. : Argument(Argument),
  411. LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
  412. assert(Argument.getKind() == TemplateArgument::Template ||
  413. Argument.getKind() == TemplateArgument::TemplateExpansion);
  414. }
  415. /// - Fetches the primary location of the argument.
  416. SourceLocation getLocation() const {
  417. if (Argument.getKind() == TemplateArgument::Template ||
  418. Argument.getKind() == TemplateArgument::TemplateExpansion)
  419. return getTemplateNameLoc();
  420. return getSourceRange().getBegin();
  421. }
  422. /// - Fetches the full source range of the argument.
  423. SourceRange getSourceRange() const LLVM_READONLY;
  424. const TemplateArgument &getArgument() const {
  425. return Argument;
  426. }
  427. TemplateArgumentLocInfo getLocInfo() const {
  428. return LocInfo;
  429. }
  430. TypeSourceInfo *getTypeSourceInfo() const {
  431. if (Argument.getKind() != TemplateArgument::Type)
  432. return nullptr;
  433. return LocInfo.getAsTypeSourceInfo();
  434. }
  435. Expr *getSourceExpression() const {
  436. assert(Argument.getKind() == TemplateArgument::Expression);
  437. return LocInfo.getAsExpr();
  438. }
  439. Expr *getSourceDeclExpression() const {
  440. assert(Argument.getKind() == TemplateArgument::Declaration);
  441. return LocInfo.getAsExpr();
  442. }
  443. Expr *getSourceNullPtrExpression() const {
  444. assert(Argument.getKind() == TemplateArgument::NullPtr);
  445. return LocInfo.getAsExpr();
  446. }
  447. Expr *getSourceIntegralExpression() const {
  448. assert(Argument.getKind() == TemplateArgument::Integral);
  449. return LocInfo.getAsExpr();
  450. }
  451. NestedNameSpecifierLoc getTemplateQualifierLoc() const {
  452. if (Argument.getKind() != TemplateArgument::Template &&
  453. Argument.getKind() != TemplateArgument::TemplateExpansion)
  454. return NestedNameSpecifierLoc();
  455. return LocInfo.getTemplateQualifierLoc();
  456. }
  457. SourceLocation getTemplateNameLoc() const {
  458. if (Argument.getKind() != TemplateArgument::Template &&
  459. Argument.getKind() != TemplateArgument::TemplateExpansion)
  460. return SourceLocation();
  461. return LocInfo.getTemplateNameLoc();
  462. }
  463. SourceLocation getTemplateEllipsisLoc() const {
  464. if (Argument.getKind() != TemplateArgument::TemplateExpansion)
  465. return SourceLocation();
  466. return LocInfo.getTemplateEllipsisLoc();
  467. }
  468. };
  469. /// A convenient class for passing around template argument
  470. /// information. Designed to be passed by reference.
  471. class TemplateArgumentListInfo {
  472. SmallVector<TemplateArgumentLoc, 8> Arguments;
  473. SourceLocation LAngleLoc;
  474. SourceLocation RAngleLoc;
  475. public:
  476. TemplateArgumentListInfo() = default;
  477. TemplateArgumentListInfo(SourceLocation LAngleLoc,
  478. SourceLocation RAngleLoc)
  479. : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
  480. // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
  481. // instead.
  482. void *operator new(size_t bytes, ASTContext &C) = delete;
  483. SourceLocation getLAngleLoc() const { return LAngleLoc; }
  484. SourceLocation getRAngleLoc() const { return RAngleLoc; }
  485. void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
  486. void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
  487. unsigned size() const { return Arguments.size(); }
  488. const TemplateArgumentLoc *getArgumentArray() const {
  489. return Arguments.data();
  490. }
  491. llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
  492. return Arguments;
  493. }
  494. const TemplateArgumentLoc &operator[](unsigned I) const {
  495. return Arguments[I];
  496. }
  497. TemplateArgumentLoc &operator[](unsigned I) {
  498. return Arguments[I];
  499. }
  500. void addArgument(const TemplateArgumentLoc &Loc) {
  501. Arguments.push_back(Loc);
  502. }
  503. };
  504. /// Represents an explicit template argument list in C++, e.g.,
  505. /// the "<int>" in "sort<int>".
  506. /// This is safe to be used inside an AST node, in contrast with
  507. /// TemplateArgumentListInfo.
  508. struct ASTTemplateArgumentListInfo final
  509. : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
  510. TemplateArgumentLoc> {
  511. private:
  512. friend class ASTNodeImporter;
  513. friend TrailingObjects;
  514. ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
  515. // FIXME: Is it ever necessary to copy to another context?
  516. ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
  517. public:
  518. /// The source location of the left angle bracket ('<').
  519. SourceLocation LAngleLoc;
  520. /// The source location of the right angle bracket ('>').
  521. SourceLocation RAngleLoc;
  522. /// The number of template arguments in TemplateArgs.
  523. unsigned NumTemplateArgs;
  524. SourceLocation getLAngleLoc() const { return LAngleLoc; }
  525. SourceLocation getRAngleLoc() const { return RAngleLoc; }
  526. /// Retrieve the template arguments
  527. const TemplateArgumentLoc *getTemplateArgs() const {
  528. return getTrailingObjects<TemplateArgumentLoc>();
  529. }
  530. unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
  531. llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
  532. return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs());
  533. }
  534. const TemplateArgumentLoc &operator[](unsigned I) const {
  535. return getTemplateArgs()[I];
  536. }
  537. static const ASTTemplateArgumentListInfo *
  538. Create(const ASTContext &C, const TemplateArgumentListInfo &List);
  539. // FIXME: Is it ever necessary to copy to another context?
  540. static const ASTTemplateArgumentListInfo *
  541. Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
  542. };
  543. /// Represents an explicit template argument list in C++, e.g.,
  544. /// the "<int>" in "sort<int>".
  545. ///
  546. /// It is intended to be used as a trailing object on AST nodes, and
  547. /// as such, doesn't contain the array of TemplateArgumentLoc itself,
  548. /// but expects the containing object to also provide storage for
  549. /// that.
  550. struct alignas(void *) ASTTemplateKWAndArgsInfo {
  551. /// The source location of the left angle bracket ('<').
  552. SourceLocation LAngleLoc;
  553. /// The source location of the right angle bracket ('>').
  554. SourceLocation RAngleLoc;
  555. /// The source location of the template keyword; this is used
  556. /// as part of the representation of qualified identifiers, such as
  557. /// S<T>::template apply<T>. Will be empty if this expression does
  558. /// not have a template keyword.
  559. SourceLocation TemplateKWLoc;
  560. /// The number of template arguments in TemplateArgs.
  561. unsigned NumTemplateArgs;
  562. void initializeFrom(SourceLocation TemplateKWLoc,
  563. const TemplateArgumentListInfo &List,
  564. TemplateArgumentLoc *OutArgArray);
  565. // FIXME: The parameter Deps is the result populated by this method, the
  566. // caller doesn't need it since it is populated by computeDependence. remove
  567. // it.
  568. void initializeFrom(SourceLocation TemplateKWLoc,
  569. const TemplateArgumentListInfo &List,
  570. TemplateArgumentLoc *OutArgArray,
  571. TemplateArgumentDependence &Deps);
  572. void initializeFrom(SourceLocation TemplateKWLoc);
  573. void copyInto(const TemplateArgumentLoc *ArgArray,
  574. TemplateArgumentListInfo &List) const;
  575. };
  576. const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
  577. const TemplateArgument &Arg);
  578. } // namespace clang
  579. #endif // LLVM_CLANG_AST_TEMPLATEBASE_H
  580. #ifdef __GNUC__
  581. #pragma GCC diagnostic pop
  582. #endif