1 //===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
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 definitions which are common for all kinds of
11 // template representation.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
16 #define LLVM_CLANG_AST_TEMPLATEBASE_H
18 #include "llvm/ADT/APSInt.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/TemplateName.h"
25 class FoldingSetNodeID;
31 class DiagnosticBuilder;
33 struct PrintingPolicy;
36 /// \brief Represents a template argument within a class template
38 class TemplateArgument {
40 /// \brief The kind of template argument we're storing.
42 /// \brief Represents an empty template argument, e.g., one that has not
45 /// The template argument is a type. Its value is stored in the
46 /// TypeOrValue field.
48 /// The template argument is a declaration that was provided for a pointer
49 /// or reference non-type template parameter.
51 /// The template argument is an integral value stored in an llvm::APSInt
52 /// that was provided for an integral non-type template parameter.
54 /// The template argument is a template name that was provided for a
55 /// template template parameter.
57 /// The template argument is a pack expansion of a template name that was
58 /// provided for a template template parameter.
60 /// The template argument is a value- or type-dependent expression
61 /// stored in an Expr*.
63 /// The template argument is actually a parameter pack. Arguments are stored
64 /// in the Args struct.
69 /// \brief The kind of template argument we're storing.
73 uintptr_t TypeOrValue;
75 char Value[sizeof(llvm::APSInt)];
79 const TemplateArgument *Args;
84 unsigned NumExpansions;
88 TemplateArgument(TemplateName, bool); // DO NOT USE
91 /// \brief Construct an empty, invalid template argument.
92 TemplateArgument() : Kind(Null), TypeOrValue(0) { }
94 /// \brief Construct a template type argument.
95 TemplateArgument(QualType T) : Kind(Type) {
96 TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
99 /// \brief Construct a template argument that refers to a
100 /// declaration, which is either an external declaration or a
101 /// template declaration.
102 TemplateArgument(Decl *D) : Kind(Declaration) {
103 // FIXME: Need to be sure we have the "canonical" declaration!
104 TypeOrValue = reinterpret_cast<uintptr_t>(D);
107 /// \brief Construct an integral constant template argument.
108 TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
109 // FIXME: Large integral values will get leaked. Do something
110 // similar to what we did with IntegerLiteral.
111 new (Integer.Value) llvm::APSInt(Value);
112 Integer.Type = Type.getAsOpaquePtr();
115 /// \brief Construct a template argument that is a template.
117 /// This form of template argument is generally used for template template
118 /// parameters. However, the template name could be a dependent template
119 /// name that ends up being instantiated to a function template whose address
122 /// \param Name The template name.
123 TemplateArgument(TemplateName Name) : Kind(Template)
125 TemplateArg.Name = Name.getAsVoidPointer();
126 TemplateArg.NumExpansions = 0;
129 /// \brief Construct a template argument that is a template pack expansion.
131 /// This form of template argument is generally used for template template
132 /// parameters. However, the template name could be a dependent template
133 /// name that ends up being instantiated to a function template whose address
136 /// \param Name The template name.
138 /// \param NumExpansions The number of expansions that will be generated by
140 TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions)
141 : Kind(TemplateExpansion)
143 TemplateArg.Name = Name.getAsVoidPointer();
145 TemplateArg.NumExpansions = *NumExpansions + 1;
147 TemplateArg.NumExpansions = 0;
150 /// \brief Construct a template argument that is an expression.
152 /// This form of template argument only occurs in template argument
153 /// lists used for dependent types and for expression; it will not
154 /// occur in a non-dependent, canonical template argument list.
155 TemplateArgument(Expr *E) : Kind(Expression) {
156 TypeOrValue = reinterpret_cast<uintptr_t>(E);
159 /// \brief Construct a template argument that is a template argument pack.
161 /// We assume that storage for the template arguments provided
162 /// outlives the TemplateArgument itself.
163 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
164 this->Args.Args = Args;
165 this->Args.NumArgs = NumArgs;
168 /// \brief Copy constructor for a template argument.
169 TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
170 // FIXME: Large integral values will get leaked. Do something
171 // similar to what we did with IntegerLiteral.
172 if (Kind == Integral) {
173 new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
174 Integer.Type = Other.Integer.Type;
175 } else if (Kind == Pack) {
176 Args.NumArgs = Other.Args.NumArgs;
177 Args.Args = Other.Args.Args;
178 } else if (Kind == Template || Kind == TemplateExpansion) {
179 TemplateArg.Name = Other.TemplateArg.Name;
180 TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions;
182 TypeOrValue = Other.TypeOrValue;
185 TemplateArgument& operator=(const TemplateArgument& Other) {
188 if (Kind == Other.Kind && Kind == Integral) {
189 // Copy integral values.
190 *this->getAsIntegral() = *Other.getAsIntegral();
191 Integer.Type = Other.Integer.Type;
195 // Destroy the current integral value, if that's what we're holding.
196 if (Kind == Integral)
197 getAsIntegral()->~APSInt();
201 if (Other.Kind == Integral) {
202 new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
203 Integer.Type = Other.Integer.Type;
204 } else if (Other.Kind == Pack) {
205 Args.NumArgs = Other.Args.NumArgs;
206 Args.Args = Other.Args.Args;
207 } else if (Kind == Template || Kind == TemplateExpansion) {
208 TemplateArg.Name = Other.TemplateArg.Name;
209 TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions;
211 TypeOrValue = Other.TypeOrValue;
217 ~TemplateArgument() {
220 if (Kind == Integral)
221 getAsIntegral()->~APSInt();
224 /// \brief Create a new template argument pack by copying the given set of
225 /// template arguments.
226 static TemplateArgument CreatePackCopy(ASTContext &Context,
227 const TemplateArgument *Args,
230 /// \brief Return the kind of stored template argument.
231 ArgKind getKind() const { return (ArgKind)Kind; }
233 /// \brief Determine whether this template argument has no value.
234 bool isNull() const { return Kind == Null; }
236 /// \brief Whether this template argument is dependent on a template
237 /// parameter such that its result can change from one instantiation to
239 bool isDependent() const;
241 /// \brief Whether this template argument is dependent on a template
243 bool isInstantiationDependent() const;
245 /// \brief Whether this template argument contains an unexpanded
247 bool containsUnexpandedParameterPack() const;
249 /// \brief Determine whether this template argument is a pack expansion.
250 bool isPackExpansion() const;
252 /// \brief Retrieve the template argument as a type.
253 QualType getAsType() const {
257 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
260 /// \brief Retrieve the template argument as a declaration.
261 Decl *getAsDecl() const {
262 if (Kind != Declaration)
264 return reinterpret_cast<Decl *>(TypeOrValue);
267 /// \brief Retrieve the template argument as a template name.
268 TemplateName getAsTemplate() const {
269 if (Kind != Template)
270 return TemplateName();
272 return TemplateName::getFromVoidPointer(TemplateArg.Name);
275 /// \brief Retrieve the template argument as a template name; if the argument
276 /// is a pack expansion, return the pattern as a template name.
277 TemplateName getAsTemplateOrTemplatePattern() const {
278 if (Kind != Template && Kind != TemplateExpansion)
279 return TemplateName();
281 return TemplateName::getFromVoidPointer(TemplateArg.Name);
284 /// \brief Retrieve the number of expansions that a template template argument
285 /// expansion will produce, if known.
286 llvm::Optional<unsigned> getNumTemplateExpansions() const;
288 /// \brief Retrieve the template argument as an integral value.
289 llvm::APSInt *getAsIntegral() {
290 if (Kind != Integral)
292 return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
295 const llvm::APSInt *getAsIntegral() const {
296 return const_cast<TemplateArgument*>(this)->getAsIntegral();
299 /// \brief Retrieve the type of the integral value.
300 QualType getIntegralType() const {
301 if (Kind != Integral)
304 return QualType::getFromOpaquePtr(Integer.Type);
307 void setIntegralType(QualType T) {
308 assert(Kind == Integral &&
309 "Cannot set the integral type of a non-integral template argument");
310 Integer.Type = T.getAsOpaquePtr();
313 /// \brief Retrieve the template argument as an expression.
314 Expr *getAsExpr() const {
315 if (Kind != Expression)
318 return reinterpret_cast<Expr *>(TypeOrValue);
321 /// \brief Iterator that traverses the elements of a template argument pack.
322 typedef const TemplateArgument * pack_iterator;
324 /// \brief Iterator referencing the first argument of a template argument
326 pack_iterator pack_begin() const {
327 assert(Kind == Pack);
331 /// \brief Iterator referencing one past the last argument of a template
333 pack_iterator pack_end() const {
334 assert(Kind == Pack);
335 return Args.Args + Args.NumArgs;
338 /// \brief The number of template arguments in the given template argument
340 unsigned pack_size() const {
341 assert(Kind == Pack);
345 /// Determines whether two template arguments are superficially the
347 bool structurallyEquals(const TemplateArgument &Other) const;
349 /// \brief When the template argument is a pack expansion, returns
350 /// the pattern of the pack expansion.
352 /// \param Ellipsis Will be set to the location of the ellipsis.
353 TemplateArgument getPackExpansionPattern() const;
355 /// \brief Print this template argument to the given output stream.
356 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
358 /// \brief Used to insert TemplateArguments into FoldingSets.
359 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
362 /// Location information for a TemplateArgument.
363 struct TemplateArgumentLocInfo {
367 TypeSourceInfo *Declarator;
369 // FIXME: We'd like to just use the qualifier in the TemplateName,
370 // but template arguments get canonicalized too quickly.
371 NestedNameSpecifier *Qualifier;
372 void *QualifierLocData;
373 unsigned TemplateNameLoc;
374 unsigned EllipsisLoc;
379 TemplateArgumentLocInfo();
381 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
383 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
385 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
386 SourceLocation TemplateNameLoc,
387 SourceLocation EllipsisLoc)
389 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
390 Template.QualifierLocData = QualifierLoc.getOpaqueData();
391 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
392 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
395 TypeSourceInfo *getAsTypeSourceInfo() const {
399 Expr *getAsExpr() const {
403 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
404 return NestedNameSpecifierLoc(Template.Qualifier,
405 Template.QualifierLocData);
408 SourceLocation getTemplateNameLoc() const {
409 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
412 SourceLocation getTemplateEllipsisLoc() const {
413 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
417 /// Location wrapper for a TemplateArgument. TemplateArgument is to
418 /// TemplateArgumentLoc as Type is to TypeLoc.
419 class TemplateArgumentLoc {
420 TemplateArgument Argument;
421 TemplateArgumentLocInfo LocInfo;
424 TemplateArgumentLoc() {}
426 TemplateArgumentLoc(const TemplateArgument &Argument,
427 TemplateArgumentLocInfo Opaque)
428 : Argument(Argument), LocInfo(Opaque) {
431 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
432 : Argument(Argument), LocInfo(TInfo) {
433 assert(Argument.getKind() == TemplateArgument::Type);
436 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
437 : Argument(Argument), LocInfo(E) {
438 assert(Argument.getKind() == TemplateArgument::Expression);
441 TemplateArgumentLoc(const TemplateArgument &Argument,
442 NestedNameSpecifierLoc QualifierLoc,
443 SourceLocation TemplateNameLoc,
444 SourceLocation EllipsisLoc = SourceLocation())
445 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
446 assert(Argument.getKind() == TemplateArgument::Template ||
447 Argument.getKind() == TemplateArgument::TemplateExpansion);
450 /// \brief - Fetches the primary location of the argument.
451 SourceLocation getLocation() const {
452 if (Argument.getKind() == TemplateArgument::Template ||
453 Argument.getKind() == TemplateArgument::TemplateExpansion)
454 return getTemplateNameLoc();
456 return getSourceRange().getBegin();
459 /// \brief - Fetches the full source range of the argument.
460 SourceRange getSourceRange() const;
462 const TemplateArgument &getArgument() const {
466 TemplateArgumentLocInfo getLocInfo() const {
470 TypeSourceInfo *getTypeSourceInfo() const {
471 assert(Argument.getKind() == TemplateArgument::Type);
472 return LocInfo.getAsTypeSourceInfo();
475 Expr *getSourceExpression() const {
476 assert(Argument.getKind() == TemplateArgument::Expression);
477 return LocInfo.getAsExpr();
480 Expr *getSourceDeclExpression() const {
481 assert(Argument.getKind() == TemplateArgument::Declaration);
482 return LocInfo.getAsExpr();
485 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
486 assert(Argument.getKind() == TemplateArgument::Template ||
487 Argument.getKind() == TemplateArgument::TemplateExpansion);
488 return LocInfo.getTemplateQualifierLoc();
491 SourceLocation getTemplateNameLoc() const {
492 assert(Argument.getKind() == TemplateArgument::Template ||
493 Argument.getKind() == TemplateArgument::TemplateExpansion);
494 return LocInfo.getTemplateNameLoc();
497 SourceLocation getTemplateEllipsisLoc() const {
498 assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
499 return LocInfo.getTemplateEllipsisLoc();
502 /// \brief When the template argument is a pack expansion, returns
503 /// the pattern of the pack expansion.
505 /// \param Ellipsis Will be set to the location of the ellipsis.
507 /// \param NumExpansions Will be set to the number of expansions that will
508 /// be generated from this pack expansion, if known a priori.
509 TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
510 llvm::Optional<unsigned> &NumExpansions,
511 ASTContext &Context) const;
514 /// A convenient class for passing around template argument
515 /// information. Designed to be passed by reference.
516 class TemplateArgumentListInfo {
517 SmallVector<TemplateArgumentLoc, 8> Arguments;
518 SourceLocation LAngleLoc;
519 SourceLocation RAngleLoc;
521 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
523 void* operator new(size_t bytes, ASTContext& C);
526 TemplateArgumentListInfo() {}
528 TemplateArgumentListInfo(SourceLocation LAngleLoc,
529 SourceLocation RAngleLoc)
530 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
532 SourceLocation getLAngleLoc() const { return LAngleLoc; }
533 SourceLocation getRAngleLoc() const { return RAngleLoc; }
535 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
536 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
538 unsigned size() const { return Arguments.size(); }
540 const TemplateArgumentLoc *getArgumentArray() const {
541 return Arguments.data();
544 const TemplateArgumentLoc &operator[](unsigned I) const {
548 void addArgument(const TemplateArgumentLoc &Loc) {
549 Arguments.push_back(Loc);
553 /// \brief Represents an explicit template argument list in C++, e.g.,
554 /// the "<int>" in "sort<int>".
555 /// This is safe to be used inside an AST node, in contrast with
556 /// TemplateArgumentListInfo.
557 struct ASTTemplateArgumentListInfo {
558 /// \brief The source location of the left angle bracket ('<');
559 SourceLocation LAngleLoc;
561 /// \brief The source location of the right angle bracket ('>');
562 SourceLocation RAngleLoc;
564 /// \brief The number of template arguments in TemplateArgs.
565 /// The actual template arguments (if any) are stored after the
566 /// ExplicitTemplateArgumentList structure.
567 unsigned NumTemplateArgs;
569 /// \brief Retrieve the template arguments
570 TemplateArgumentLoc *getTemplateArgs() {
571 return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
574 /// \brief Retrieve the template arguments
575 const TemplateArgumentLoc *getTemplateArgs() const {
576 return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
579 const TemplateArgumentLoc &operator[](unsigned I) const {
580 return getTemplateArgs()[I];
583 static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
584 const TemplateArgumentListInfo &List);
586 void initializeFrom(const TemplateArgumentListInfo &List);
587 void initializeFrom(const TemplateArgumentListInfo &List,
588 bool &Dependent, bool &InstantiationDependent,
589 bool &ContainsUnexpandedParameterPack);
590 void copyInto(TemplateArgumentListInfo &List) const;
591 static std::size_t sizeFor(unsigned NumTemplateArgs);
592 static std::size_t sizeFor(const TemplateArgumentListInfo &List);
595 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
596 const TemplateArgument &Arg);
598 inline TemplateSpecializationType::iterator
599 TemplateSpecializationType::end() const {
600 return getArgs() + getNumArgs();
603 inline DependentTemplateSpecializationType::iterator
604 DependentTemplateSpecializationType::end() const {
605 return getArgs() + getNumArgs();
608 inline const TemplateArgument &
609 TemplateSpecializationType::getArg(unsigned Idx) const {
610 assert(Idx < getNumArgs() && "Template argument out of range");
611 return getArgs()[Idx];
614 inline const TemplateArgument &
615 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
616 assert(Idx < getNumArgs() && "Template argument out of range");
617 return getArgs()[Idx];
620 } // end namespace clang