ParsedTemplate.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- ParsedTemplate.h - Template Parsing Data Types ---------*- 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 data structures that store the parsed representation of
  15. // templates.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
  19. #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
  20. #include "clang/Basic/OperatorKinds.h"
  21. #include "clang/Basic/SourceLocation.h"
  22. #include "clang/Basic/TemplateKinds.h"
  23. #include "clang/Sema/DeclSpec.h"
  24. #include "clang/Sema/Ownership.h"
  25. #include "llvm/ADT/SmallVector.h"
  26. #include <cassert>
  27. #include <cstdlib>
  28. #include <new>
  29. namespace clang {
  30. /// Represents the parsed form of a C++ template argument.
  31. class ParsedTemplateArgument {
  32. public:
  33. /// Describes the kind of template argument that was parsed.
  34. enum KindType {
  35. /// A template type parameter, stored as a type.
  36. Type,
  37. /// A non-type template parameter, stored as an expression.
  38. NonType,
  39. /// A template template argument, stored as a template name.
  40. Template
  41. };
  42. /// Build an empty template argument.
  43. ///
  44. /// This template argument is invalid.
  45. ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
  46. /// Create a template type argument or non-type template argument.
  47. ///
  48. /// \param Arg the template type argument or non-type template argument.
  49. /// \param Loc the location of the type.
  50. ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
  51. : Kind(Kind), Arg(Arg), Loc(Loc) { }
  52. /// Create a template template argument.
  53. ///
  54. /// \param SS the C++ scope specifier that precedes the template name, if
  55. /// any.
  56. ///
  57. /// \param Template the template to which this template template
  58. /// argument refers.
  59. ///
  60. /// \param TemplateLoc the location of the template name.
  61. ParsedTemplateArgument(const CXXScopeSpec &SS,
  62. ParsedTemplateTy Template,
  63. SourceLocation TemplateLoc)
  64. : Kind(ParsedTemplateArgument::Template),
  65. Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {}
  66. /// Determine whether the given template argument is invalid.
  67. bool isInvalid() const { return Arg == nullptr; }
  68. /// Determine what kind of template argument we have.
  69. KindType getKind() const { return Kind; }
  70. /// Retrieve the template type argument's type.
  71. ParsedType getAsType() const {
  72. assert(Kind == Type && "Not a template type argument");
  73. return ParsedType::getFromOpaquePtr(Arg);
  74. }
  75. /// Retrieve the non-type template argument's expression.
  76. Expr *getAsExpr() const {
  77. assert(Kind == NonType && "Not a non-type template argument");
  78. return static_cast<Expr*>(Arg);
  79. }
  80. /// Retrieve the template template argument's template name.
  81. ParsedTemplateTy getAsTemplate() const {
  82. assert(Kind == Template && "Not a template template argument");
  83. return ParsedTemplateTy::getFromOpaquePtr(Arg);
  84. }
  85. /// Retrieve the location of the template argument.
  86. SourceLocation getLocation() const { return Loc; }
  87. /// Retrieve the nested-name-specifier that precedes the template
  88. /// name in a template template argument.
  89. const CXXScopeSpec &getScopeSpec() const {
  90. assert(Kind == Template &&
  91. "Only template template arguments can have a scope specifier");
  92. return SS;
  93. }
  94. /// Retrieve the location of the ellipsis that makes a template
  95. /// template argument into a pack expansion.
  96. SourceLocation getEllipsisLoc() const {
  97. assert(Kind == Template &&
  98. "Only template template arguments can have an ellipsis");
  99. return EllipsisLoc;
  100. }
  101. /// Retrieve a pack expansion of the given template template
  102. /// argument.
  103. ///
  104. /// \param EllipsisLoc The location of the ellipsis.
  105. ParsedTemplateArgument getTemplatePackExpansion(
  106. SourceLocation EllipsisLoc) const;
  107. private:
  108. KindType Kind;
  109. /// The actual template argument representation, which may be
  110. /// an \c Sema::TypeTy* (for a type), an Expr* (for an
  111. /// expression), or an Sema::TemplateTy (for a template).
  112. void *Arg;
  113. /// The nested-name-specifier that can accompany a template template
  114. /// argument.
  115. CXXScopeSpec SS;
  116. /// the location of the template argument.
  117. SourceLocation Loc;
  118. /// The ellipsis location that can accompany a template template
  119. /// argument (turning it into a template template argument expansion).
  120. SourceLocation EllipsisLoc;
  121. };
  122. /// Information about a template-id annotation
  123. /// token.
  124. ///
  125. /// A template-id annotation token contains the template name,
  126. /// template arguments, and the source locations for important
  127. /// tokens. All of the information about template arguments is allocated
  128. /// directly after this structure.
  129. /// A template-id annotation token can also be generated by a type-constraint
  130. /// construct with no explicit template arguments, e.g. "template<C T>" would
  131. /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
  132. /// locations would be invalid in this case).
  133. struct TemplateIdAnnotation final
  134. : private llvm::TrailingObjects<TemplateIdAnnotation,
  135. ParsedTemplateArgument> {
  136. friend TrailingObjects;
  137. /// TemplateKWLoc - The location of the template keyword.
  138. /// For e.g. typename T::template Y<U>
  139. SourceLocation TemplateKWLoc;
  140. /// TemplateNameLoc - The location of the template name within the
  141. /// source.
  142. SourceLocation TemplateNameLoc;
  143. /// FIXME: Temporarily stores the name of a specialization
  144. IdentifierInfo *Name;
  145. /// FIXME: Temporarily stores the overloaded operator kind.
  146. OverloadedOperatorKind Operator;
  147. /// The declaration of the template corresponding to the
  148. /// template-name.
  149. ParsedTemplateTy Template;
  150. /// The kind of template that Template refers to. If this is
  151. /// TNK_Non_template, an error was encountered and diagnosed
  152. /// when parsing or looking up the template name.
  153. TemplateNameKind Kind;
  154. /// The location of the '<' before the template argument
  155. /// list.
  156. SourceLocation LAngleLoc;
  157. /// The location of the '>' after the template argument
  158. /// list.
  159. SourceLocation RAngleLoc;
  160. /// NumArgs - The number of template arguments.
  161. unsigned NumArgs;
  162. /// Whether an error was encountered in the template arguments.
  163. /// If so, NumArgs and the trailing arguments are best-effort.
  164. bool ArgsInvalid;
  165. /// Retrieves a pointer to the template arguments
  166. ParsedTemplateArgument *getTemplateArgs() {
  167. return getTrailingObjects<ParsedTemplateArgument>();
  168. }
  169. /// Creates a new TemplateIdAnnotation with NumArgs arguments and
  170. /// appends it to List.
  171. static TemplateIdAnnotation *
  172. Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
  173. IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
  174. ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
  175. SourceLocation LAngleLoc, SourceLocation RAngleLoc,
  176. ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
  177. SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
  178. TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
  179. totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
  180. TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name,
  181. OperatorKind, OpaqueTemplateName, TemplateKind,
  182. LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
  183. CleanupList.push_back(TemplateId);
  184. return TemplateId;
  185. }
  186. void Destroy() {
  187. std::for_each(
  188. getTemplateArgs(), getTemplateArgs() + NumArgs,
  189. [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
  190. this->~TemplateIdAnnotation();
  191. free(this);
  192. }
  193. /// Determine whether this might be a type template.
  194. bool mightBeType() const {
  195. return Kind == TNK_Non_template ||
  196. Kind == TNK_Type_template ||
  197. Kind == TNK_Dependent_template_name ||
  198. Kind == TNK_Undeclared_template;
  199. }
  200. bool hasInvalidName() const { return Kind == TNK_Non_template; }
  201. bool hasInvalidArgs() const { return ArgsInvalid; }
  202. bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
  203. private:
  204. TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
  205. TemplateIdAnnotation(SourceLocation TemplateKWLoc,
  206. SourceLocation TemplateNameLoc, IdentifierInfo *Name,
  207. OverloadedOperatorKind OperatorKind,
  208. ParsedTemplateTy OpaqueTemplateName,
  209. TemplateNameKind TemplateKind,
  210. SourceLocation LAngleLoc, SourceLocation RAngleLoc,
  211. ArrayRef<ParsedTemplateArgument> TemplateArgs,
  212. bool ArgsInvalid) noexcept
  213. : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc),
  214. Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
  215. Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
  216. NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
  217. std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
  218. getTemplateArgs());
  219. }
  220. ~TemplateIdAnnotation() = default;
  221. };
  222. /// Retrieves the range of the given template parameter lists.
  223. SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
  224. unsigned NumParams);
  225. } // end namespace clang
  226. #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
  227. #ifdef __GNUC__
  228. #pragma GCC diagnostic pop
  229. #endif