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