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 "clang/AST/TemplateName.h"
19 #include "clang/AST/Type.h"
20 #include "llvm/ADT/APSInt.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/iterator_range.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/TrailingObjects.h"
28 class FoldingSetNodeID;
33 class DiagnosticBuilder;
35 struct PrintingPolicy;
39 /// \brief Represents a template argument.
40 class TemplateArgument {
42 /// \brief The kind of template argument we're storing.
44 /// \brief Represents an empty template argument, e.g., one that has not
47 /// The template argument is a type.
49 /// The template argument is a declaration that was provided for a pointer,
50 /// reference, or pointer to member non-type template parameter.
52 /// The template argument is a null pointer or null pointer to member that
53 /// was provided for a non-type template parameter.
55 /// The template argument is an integral value stored in an llvm::APSInt
56 /// that was provided for an integral non-type template parameter.
58 /// The template argument is a template name that was provided for a
59 /// template template parameter.
61 /// The template argument is a pack expansion of a template name that was
62 /// provided for a template template parameter.
64 /// The template argument is an expression, and we've not resolved it to one
65 /// of the other forms yet, either because it's dependent or because we're
66 /// representing a non-canonical template argument (for instance, in a
67 /// TemplateSpecializationType). Also used to represent a non-dependent
68 /// __uuidof expression (a Microsoft extension).
70 /// The template argument is actually a parameter pack. Arguments are stored
71 /// in the Args struct.
76 /// \brief The kind of template argument we're storing.
85 // We store a decomposed APSInt with the data allocated by ASTContext if
86 // BitWidth > 64. The memory may be shared between multiple
87 // TemplateArgument instances.
88 unsigned BitWidth : 31;
89 unsigned IsUnsigned : 1;
91 uint64_t VAL; ///< Used to store the <= 64 bits integer value.
92 const uint64_t *pVal; ///< Used to store the >64 bits integer value.
99 const TemplateArgument *Args;
103 unsigned NumExpansions;
114 struct TA TemplateArg;
115 struct TV TypeOrValue;
118 TemplateArgument(TemplateName, bool) = delete;
121 /// \brief Construct an empty, invalid template argument.
123 TypeOrValue.Kind = Null;
127 /// \brief Construct a template type argument.
128 TemplateArgument(QualType T, bool isNullPtr = false) {
129 TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
130 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
133 /// \brief Construct a template argument that refers to a
134 /// declaration, which is either an external declaration or a
135 /// template declaration.
136 TemplateArgument(ValueDecl *D, QualType QT) {
137 assert(D && "Expected decl");
138 DeclArg.Kind = Declaration;
139 DeclArg.QT = QT.getAsOpaquePtr();
143 /// \brief Construct an integral constant template argument. The memory to
144 /// store the value is allocated with Ctx.
145 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
147 /// \brief Construct an integral constant template argument with the same
148 /// value as Other but a different type.
149 TemplateArgument(const TemplateArgument &Other, QualType Type) {
150 Integer = Other.Integer;
151 Integer.Type = Type.getAsOpaquePtr();
154 /// \brief Construct a template argument that is a template.
156 /// This form of template argument is generally used for template template
157 /// parameters. However, the template name could be a dependent template
158 /// name that ends up being instantiated to a function template whose address
161 /// \param Name The template name.
162 TemplateArgument(TemplateName Name) {
163 TemplateArg.Kind = Template;
164 TemplateArg.Name = Name.getAsVoidPointer();
165 TemplateArg.NumExpansions = 0;
168 /// \brief Construct a template argument that is a template pack expansion.
170 /// This form of template argument is generally used for template template
171 /// parameters. However, the template name could be a dependent template
172 /// name that ends up being instantiated to a function template whose address
175 /// \param Name The template name.
177 /// \param NumExpansions The number of expansions that will be generated by
179 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
180 TemplateArg.Kind = TemplateExpansion;
181 TemplateArg.Name = Name.getAsVoidPointer();
183 TemplateArg.NumExpansions = *NumExpansions + 1;
185 TemplateArg.NumExpansions = 0;
188 /// \brief Construct a template argument that is an expression.
190 /// This form of template argument only occurs in template argument
191 /// lists used for dependent types and for expression; it will not
192 /// occur in a non-dependent, canonical template argument list.
193 TemplateArgument(Expr *E) {
194 TypeOrValue.Kind = Expression;
195 TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
198 /// \brief Construct a template argument that is a template argument pack.
200 /// We assume that storage for the template arguments provided
201 /// outlives the TemplateArgument itself.
202 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
203 this->Args.Kind = Pack;
204 this->Args.Args = Args.data();
205 this->Args.NumArgs = Args.size();
208 static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
210 /// \brief Create a new template argument pack by copying the given set of
211 /// template arguments.
212 static TemplateArgument CreatePackCopy(ASTContext &Context,
213 ArrayRef<TemplateArgument> Args);
215 /// \brief Return the kind of stored template argument.
216 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
218 /// \brief Determine whether this template argument has no value.
219 bool isNull() const { return getKind() == Null; }
221 /// \brief Whether this template argument is dependent on a template
222 /// parameter such that its result can change from one instantiation to
224 bool isDependent() const;
226 /// \brief Whether this template argument is dependent on a template
228 bool isInstantiationDependent() const;
230 /// \brief Whether this template argument contains an unexpanded
232 bool containsUnexpandedParameterPack() const;
234 /// \brief Determine whether this template argument is a pack expansion.
235 bool isPackExpansion() const;
237 /// \brief Retrieve the type for a type template argument.
238 QualType getAsType() const {
239 assert(getKind() == Type && "Unexpected kind");
240 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
243 /// \brief Retrieve the declaration for a declaration non-type
244 /// template argument.
245 ValueDecl *getAsDecl() const {
246 assert(getKind() == Declaration && "Unexpected kind");
250 QualType getParamTypeForDecl() const {
251 assert(getKind() == Declaration && "Unexpected kind");
252 return QualType::getFromOpaquePtr(DeclArg.QT);
255 /// \brief Retrieve the type for null non-type template argument.
256 QualType getNullPtrType() const {
257 assert(getKind() == NullPtr && "Unexpected kind");
258 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
261 /// \brief Retrieve the template name for a template name argument.
262 TemplateName getAsTemplate() const {
263 assert(getKind() == Template && "Unexpected kind");
264 return TemplateName::getFromVoidPointer(TemplateArg.Name);
267 /// \brief Retrieve the template argument as a template name; if the argument
268 /// is a pack expansion, return the pattern as a template name.
269 TemplateName getAsTemplateOrTemplatePattern() const {
270 assert((getKind() == Template || getKind() == TemplateExpansion) &&
273 return TemplateName::getFromVoidPointer(TemplateArg.Name);
276 /// \brief Retrieve the number of expansions that a template template argument
277 /// expansion will produce, if known.
278 Optional<unsigned> getNumTemplateExpansions() const;
280 /// \brief Retrieve the template argument as an integral value.
281 // FIXME: Provide a way to read the integral data without copying the value.
282 llvm::APSInt getAsIntegral() const {
283 assert(getKind() == Integral && "Unexpected kind");
284 using namespace llvm;
285 if (Integer.BitWidth <= 64)
286 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
288 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
289 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
293 /// \brief Retrieve the type of the integral value.
294 QualType getIntegralType() const {
295 assert(getKind() == Integral && "Unexpected kind");
296 return QualType::getFromOpaquePtr(Integer.Type);
299 void setIntegralType(QualType T) {
300 assert(getKind() == Integral && "Unexpected kind");
301 Integer.Type = T.getAsOpaquePtr();
304 /// \brief If this is a non-type template argument, get its type. Otherwise,
305 /// returns a null QualType.
306 QualType getNonTypeTemplateArgumentType() const;
308 /// \brief Retrieve the template argument as an expression.
309 Expr *getAsExpr() const {
310 assert(getKind() == Expression && "Unexpected kind");
311 return reinterpret_cast<Expr *>(TypeOrValue.V);
314 /// \brief Iterator that traverses the elements of a template argument pack.
315 typedef const TemplateArgument * pack_iterator;
317 /// \brief Iterator referencing the first argument of a template argument
319 pack_iterator pack_begin() const {
320 assert(getKind() == Pack);
324 /// \brief Iterator referencing one past the last argument of a template
326 pack_iterator pack_end() const {
327 assert(getKind() == Pack);
328 return Args.Args + Args.NumArgs;
331 /// \brief Iterator range referencing all of the elements of a template
333 ArrayRef<TemplateArgument> pack_elements() const {
334 return llvm::makeArrayRef(pack_begin(), pack_end());
337 /// \brief The number of template arguments in the given template argument
339 unsigned pack_size() const {
340 assert(getKind() == Pack);
344 /// \brief Return the array of arguments in this template argument pack.
345 ArrayRef<TemplateArgument> getPackAsArray() const {
346 assert(getKind() == Pack);
347 return llvm::makeArrayRef(Args.Args, Args.NumArgs);
350 /// \brief Determines whether two template arguments are superficially the
352 bool structurallyEquals(const TemplateArgument &Other) const;
354 /// \brief When the template argument is a pack expansion, returns
355 /// the pattern of the pack expansion.
356 TemplateArgument getPackExpansionPattern() const;
358 /// \brief Print this template argument to the given output stream.
359 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
361 /// \brief Debugging aid that dumps the template argument.
362 void dump(raw_ostream &Out) const;
364 /// \brief Debugging aid that dumps the template argument to standard error.
367 /// \brief Used to insert TemplateArguments into FoldingSets.
368 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
371 /// Location information for a TemplateArgument.
372 struct TemplateArgumentLocInfo {
376 // FIXME: We'd like to just use the qualifier in the TemplateName,
377 // but template arguments get canonicalized too quickly.
378 NestedNameSpecifier *Qualifier;
379 void *QualifierLocData;
380 unsigned TemplateNameLoc;
381 unsigned EllipsisLoc;
387 TypeSourceInfo *Declarator;
391 TemplateArgumentLocInfo();
393 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
395 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
397 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
398 SourceLocation TemplateNameLoc,
399 SourceLocation EllipsisLoc)
401 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
402 Template.QualifierLocData = QualifierLoc.getOpaqueData();
403 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
404 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
407 TypeSourceInfo *getAsTypeSourceInfo() const {
411 Expr *getAsExpr() const {
415 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
416 return NestedNameSpecifierLoc(Template.Qualifier,
417 Template.QualifierLocData);
420 SourceLocation getTemplateNameLoc() const {
421 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
424 SourceLocation getTemplateEllipsisLoc() const {
425 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
429 /// Location wrapper for a TemplateArgument. TemplateArgument is to
430 /// TemplateArgumentLoc as Type is to TypeLoc.
431 class TemplateArgumentLoc {
432 TemplateArgument Argument;
433 TemplateArgumentLocInfo LocInfo;
436 TemplateArgumentLoc() {}
438 TemplateArgumentLoc(const TemplateArgument &Argument,
439 TemplateArgumentLocInfo Opaque)
440 : Argument(Argument), LocInfo(Opaque) {
443 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
444 : Argument(Argument), LocInfo(TInfo) {
445 assert(Argument.getKind() == TemplateArgument::Type);
448 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
449 : Argument(Argument), LocInfo(E) {
450 assert(Argument.getKind() == TemplateArgument::Expression);
453 TemplateArgumentLoc(const TemplateArgument &Argument,
454 NestedNameSpecifierLoc QualifierLoc,
455 SourceLocation TemplateNameLoc,
456 SourceLocation EllipsisLoc = SourceLocation())
457 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
458 assert(Argument.getKind() == TemplateArgument::Template ||
459 Argument.getKind() == TemplateArgument::TemplateExpansion);
462 /// \brief - Fetches the primary location of the argument.
463 SourceLocation getLocation() const {
464 if (Argument.getKind() == TemplateArgument::Template ||
465 Argument.getKind() == TemplateArgument::TemplateExpansion)
466 return getTemplateNameLoc();
468 return getSourceRange().getBegin();
471 /// \brief - Fetches the full source range of the argument.
472 SourceRange getSourceRange() const LLVM_READONLY;
474 const TemplateArgument &getArgument() const {
478 TemplateArgumentLocInfo getLocInfo() const {
482 TypeSourceInfo *getTypeSourceInfo() const {
483 assert(Argument.getKind() == TemplateArgument::Type);
484 return LocInfo.getAsTypeSourceInfo();
487 Expr *getSourceExpression() const {
488 assert(Argument.getKind() == TemplateArgument::Expression);
489 return LocInfo.getAsExpr();
492 Expr *getSourceDeclExpression() const {
493 assert(Argument.getKind() == TemplateArgument::Declaration);
494 return LocInfo.getAsExpr();
497 Expr *getSourceNullPtrExpression() const {
498 assert(Argument.getKind() == TemplateArgument::NullPtr);
499 return LocInfo.getAsExpr();
502 Expr *getSourceIntegralExpression() const {
503 assert(Argument.getKind() == TemplateArgument::Integral);
504 return LocInfo.getAsExpr();
507 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
508 assert(Argument.getKind() == TemplateArgument::Template ||
509 Argument.getKind() == TemplateArgument::TemplateExpansion);
510 return LocInfo.getTemplateQualifierLoc();
513 SourceLocation getTemplateNameLoc() const {
514 assert(Argument.getKind() == TemplateArgument::Template ||
515 Argument.getKind() == TemplateArgument::TemplateExpansion);
516 return LocInfo.getTemplateNameLoc();
519 SourceLocation getTemplateEllipsisLoc() const {
520 assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
521 return LocInfo.getTemplateEllipsisLoc();
525 /// A convenient class for passing around template argument
526 /// information. Designed to be passed by reference.
527 class TemplateArgumentListInfo {
528 SmallVector<TemplateArgumentLoc, 8> Arguments;
529 SourceLocation LAngleLoc;
530 SourceLocation RAngleLoc;
532 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
534 void *operator new(size_t bytes, ASTContext &C) = delete;
537 TemplateArgumentListInfo() {}
539 TemplateArgumentListInfo(SourceLocation LAngleLoc,
540 SourceLocation RAngleLoc)
541 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
543 SourceLocation getLAngleLoc() const { return LAngleLoc; }
544 SourceLocation getRAngleLoc() const { return RAngleLoc; }
546 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
547 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
549 unsigned size() const { return Arguments.size(); }
551 const TemplateArgumentLoc *getArgumentArray() const {
552 return Arguments.data();
555 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
559 const TemplateArgumentLoc &operator[](unsigned I) const {
563 TemplateArgumentLoc &operator[](unsigned I) {
567 void addArgument(const TemplateArgumentLoc &Loc) {
568 Arguments.push_back(Loc);
572 /// \brief Represents an explicit template argument list in C++, e.g.,
573 /// the "<int>" in "sort<int>".
574 /// This is safe to be used inside an AST node, in contrast with
575 /// TemplateArgumentListInfo.
576 struct ASTTemplateArgumentListInfo final
577 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
578 TemplateArgumentLoc> {
580 friend TrailingObjects;
582 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
585 /// \brief The source location of the left angle bracket ('<').
586 SourceLocation LAngleLoc;
588 /// \brief The source location of the right angle bracket ('>').
589 SourceLocation RAngleLoc;
591 /// \brief The number of template arguments in TemplateArgs.
592 unsigned NumTemplateArgs;
594 /// \brief Retrieve the template arguments
595 const TemplateArgumentLoc *getTemplateArgs() const {
596 return getTrailingObjects<TemplateArgumentLoc>();
599 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
600 return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
603 const TemplateArgumentLoc &operator[](unsigned I) const {
604 return getTemplateArgs()[I];
607 static const ASTTemplateArgumentListInfo *
608 Create(ASTContext &C, const TemplateArgumentListInfo &List);
611 /// \brief Represents an explicit template argument list in C++, e.g.,
612 /// the "<int>" in "sort<int>".
614 /// It is intended to be used as a trailing object on AST nodes, and
615 /// as such, doesn't contain the array of TemplateArgumentLoc itself,
616 /// but expects the containing object to also provide storage for
618 struct alignas(void *) ASTTemplateKWAndArgsInfo {
619 /// \brief The source location of the left angle bracket ('<').
620 SourceLocation LAngleLoc;
622 /// \brief The source location of the right angle bracket ('>').
623 SourceLocation RAngleLoc;
625 /// \brief The source location of the template keyword; this is used
626 /// as part of the representation of qualified identifiers, such as
627 /// S<T>::template apply<T>. Will be empty if this expression does
628 /// not have a template keyword.
629 SourceLocation TemplateKWLoc;
631 /// \brief The number of template arguments in TemplateArgs.
632 unsigned NumTemplateArgs;
634 void initializeFrom(SourceLocation TemplateKWLoc,
635 const TemplateArgumentListInfo &List,
636 TemplateArgumentLoc *OutArgArray);
637 void initializeFrom(SourceLocation TemplateKWLoc,
638 const TemplateArgumentListInfo &List,
639 TemplateArgumentLoc *OutArgArray, bool &Dependent,
640 bool &InstantiationDependent,
641 bool &ContainsUnexpandedParameterPack);
642 void initializeFrom(SourceLocation TemplateKWLoc);
644 void copyInto(const TemplateArgumentLoc *ArgArray,
645 TemplateArgumentListInfo &List) const;
648 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
649 const TemplateArgument &Arg);
651 inline TemplateSpecializationType::iterator
652 TemplateSpecializationType::end() const {
653 return getArgs() + getNumArgs();
656 inline DependentTemplateSpecializationType::iterator
657 DependentTemplateSpecializationType::end() const {
658 return getArgs() + getNumArgs();
661 inline const TemplateArgument &
662 TemplateSpecializationType::getArg(unsigned Idx) const {
663 assert(Idx < getNumArgs() && "Template argument out of range");
664 return getArgs()[Idx];
667 inline const TemplateArgument &
668 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
669 assert(Idx < getNumArgs() && "Template argument out of range");
670 return getArgs()[Idx];
673 } // end namespace clang