1 //===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides data structures that store the parsed representation of
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
15 #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
17 #include "clang/Sema/DeclSpec.h"
18 #include "clang/Sema/Ownership.h"
22 /// \brief Represents the parsed form of a C++ template argument.
23 class ParsedTemplateArgument {
25 /// \brief Describes the kind of template argument that was parsed.
27 /// \brief A template type parameter, stored as a type.
29 /// \brief A non-type template parameter, stored as an expression.
31 /// \brief A template template argument, stored as a template name.
35 /// \brief Build an empty template argument.
37 /// This template argument is invalid.
38 ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
40 /// \brief Create a template type argument or non-type template argument.
42 /// \param Arg the template type argument or non-type template argument.
43 /// \param Loc the location of the type.
44 ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
45 : Kind(Kind), Arg(Arg), Loc(Loc) { }
47 /// \brief Create a template template argument.
49 /// \param SS the C++ scope specifier that precedes the template name, if
52 /// \param Template the template to which this template template
55 /// \param TemplateLoc the location of the template name.
56 ParsedTemplateArgument(const CXXScopeSpec &SS,
57 ParsedTemplateTy Template,
58 SourceLocation TemplateLoc)
59 : Kind(ParsedTemplateArgument::Template),
60 Arg(Template.getAsOpaquePtr()),
61 SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
63 /// \brief Determine whether the given template argument is invalid.
64 bool isInvalid() const { return Arg == nullptr; }
66 /// \brief Determine what kind of template argument we have.
67 KindType getKind() const { return Kind; }
69 /// \brief Retrieve the template type argument's type.
70 ParsedType getAsType() const {
71 assert(Kind == Type && "Not a template type argument");
72 return ParsedType::getFromOpaquePtr(Arg);
75 /// \brief 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);
81 /// \brief Retrieve the template template argument's template name.
82 ParsedTemplateTy getAsTemplate() const {
83 assert(Kind == Template && "Not a template template argument");
84 return ParsedTemplateTy::getFromOpaquePtr(Arg);
87 /// \brief Retrieve the location of the template argument.
88 SourceLocation getLocation() const { return Loc; }
90 /// \brief Retrieve the nested-name-specifier that precedes the template
91 /// name in a template template argument.
92 const CXXScopeSpec &getScopeSpec() const {
93 assert(Kind == Template &&
94 "Only template template arguments can have a scope specifier");
98 /// \brief Retrieve the location of the ellipsis that makes a template
99 /// template argument into a pack expansion.
100 SourceLocation getEllipsisLoc() const {
101 assert(Kind == Template &&
102 "Only template template arguments can have an ellipsis");
106 /// \brief Retrieve a pack expansion of the given template template
109 /// \param EllipsisLoc The location of the ellipsis.
110 ParsedTemplateArgument getTemplatePackExpansion(
111 SourceLocation EllipsisLoc) const;
116 /// \brief The actual template argument representation, which may be
117 /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
118 /// expression), or an ActionBase::TemplateTy (for a template).
121 /// \brief The nested-name-specifier that can accompany a template template
125 /// \brief the location of the template argument.
128 /// \brief The ellipsis location that can accompany a template template
129 /// argument (turning it into a template template argument expansion).
130 SourceLocation EllipsisLoc;
133 /// \brief Information about a template-id annotation
136 /// A template-id annotation token contains the template declaration,
137 /// template arguments, whether those template arguments were types,
138 /// expressions, or template names, and the source locations for important
139 /// tokens. All of the information about template arguments is allocated
140 /// directly after this structure.
141 struct TemplateIdAnnotation {
142 /// \brief The nested-name-specifier that precedes the template name.
145 /// TemplateKWLoc - The location of the template keyword within the
147 SourceLocation TemplateKWLoc;
149 /// TemplateNameLoc - The location of the template name within the
151 SourceLocation TemplateNameLoc;
153 /// FIXME: Temporarily stores the name of a specialization
154 IdentifierInfo *Name;
156 /// FIXME: Temporarily stores the overloaded operator kind.
157 OverloadedOperatorKind Operator;
159 /// The declaration of the template corresponding to the
161 ParsedTemplateTy Template;
163 /// The kind of template that Template refers to.
164 TemplateNameKind Kind;
166 /// The location of the '<' before the template argument
168 SourceLocation LAngleLoc;
170 /// The location of the '>' after the template argument
172 SourceLocation RAngleLoc;
174 /// NumArgs - The number of template arguments.
177 /// \brief Retrieves a pointer to the template arguments
178 ParsedTemplateArgument *getTemplateArgs() {
179 return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
182 /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
183 /// appends it to List.
184 static TemplateIdAnnotation *
185 Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
186 TemplateIdAnnotation *TemplateId
187 = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
188 sizeof(ParsedTemplateArgument) * NumArgs);
189 TemplateId->NumArgs = NumArgs;
191 // Default-construct nested-name-specifier.
192 new (&TemplateId->SS) CXXScopeSpec();
194 // Default-construct parsed template arguments.
195 ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
196 for (unsigned I = 0; I != NumArgs; ++I)
197 new (TemplateArgs + I) ParsedTemplateArgument();
199 List.push_back(TemplateId);
209 /// Retrieves the range of the given template parameter lists.
210 SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,