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/Support/Compiler.h"
23 #include "llvm/Support/ErrorHandling.h"
26 class FoldingSetNodeID;
31 class DiagnosticBuilder;
33 struct PrintingPolicy;
37 /// \brief Represents a template argument within a class template
39 class TemplateArgument {
41 /// \brief The kind of template argument we're storing.
43 /// \brief Represents an empty template argument, e.g., one that has not
46 /// The template argument is a type.
48 /// The template argument is a declaration that was provided for a pointer,
49 /// reference, or pointer to member non-type template parameter.
51 /// The template argument is a null pointer or null pointer to member that
52 /// was provided for a non-type template parameter.
54 /// The template argument is an integral value stored in an llvm::APSInt
55 /// that was provided for an integral non-type template parameter.
57 /// The template argument is a template name that was provided for a
58 /// template template parameter.
60 /// The template argument is a pack expansion of a template name that was
61 /// provided for a template template parameter.
63 /// The template argument is a value- or type-dependent expression
64 /// stored in an Expr*.
66 /// The template argument is actually a parameter pack. Arguments are stored
67 /// in the Args struct.
72 /// \brief The kind of template argument we're storing.
80 // We store a decomposed APSInt with the data allocated by ASTContext if
81 // BitWidth > 64. The memory may be shared between multiple
82 // TemplateArgument instances.
84 uint64_t VAL; ///< Used to store the <= 64 bits integer value.
85 const uint64_t *pVal; ///< Used to store the >64 bits integer value.
87 unsigned BitWidth : 31;
88 unsigned IsUnsigned : 1;
92 const TemplateArgument *Args;
97 unsigned NumExpansions;
103 struct TA TemplateArg;
104 uintptr_t TypeOrValue;
107 TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
110 /// \brief Construct an empty, invalid template argument.
111 TemplateArgument() : Kind(Null), TypeOrValue(0) { }
113 /// \brief Construct a template type argument.
114 TemplateArgument(QualType T, bool isNullPtr = false)
115 : Kind(isNullPtr ? NullPtr : Type) {
116 TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
119 /// \brief Construct a template argument that refers to a
120 /// declaration, which is either an external declaration or a
121 /// template declaration.
122 TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) {
123 assert(D && "Expected decl");
125 DeclArg.ForRefParam = ForRefParam;
128 /// \brief Construct an integral constant template argument. The memory to
129 /// store the value is allocated with Ctx.
130 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
132 /// \brief Construct an integral constant template argument with the same
133 /// value as Other but a different type.
134 TemplateArgument(const TemplateArgument &Other, QualType Type)
136 Integer = Other.Integer;
137 Integer.Type = Type.getAsOpaquePtr();
140 /// \brief Construct a template argument that is a template.
142 /// This form of template argument is generally used for template template
143 /// parameters. However, the template name could be a dependent template
144 /// name that ends up being instantiated to a function template whose address
147 /// \param Name The template name.
148 TemplateArgument(TemplateName Name) : Kind(Template)
150 TemplateArg.Name = Name.getAsVoidPointer();
151 TemplateArg.NumExpansions = 0;
154 /// \brief Construct a template argument that is a template pack expansion.
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.
163 /// \param NumExpansions The number of expansions that will be generated by
165 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions)
166 : Kind(TemplateExpansion)
168 TemplateArg.Name = Name.getAsVoidPointer();
170 TemplateArg.NumExpansions = *NumExpansions + 1;
172 TemplateArg.NumExpansions = 0;
175 /// \brief Construct a template argument that is an expression.
177 /// This form of template argument only occurs in template argument
178 /// lists used for dependent types and for expression; it will not
179 /// occur in a non-dependent, canonical template argument list.
180 TemplateArgument(Expr *E) : Kind(Expression) {
181 TypeOrValue = reinterpret_cast<uintptr_t>(E);
184 /// \brief Construct a template argument that is a template argument pack.
186 /// We assume that storage for the template arguments provided
187 /// outlives the TemplateArgument itself.
188 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
189 this->Args.Args = Args;
190 this->Args.NumArgs = NumArgs;
193 static TemplateArgument getEmptyPack() {
194 return TemplateArgument((TemplateArgument*)0, 0);
197 /// \brief Create a new template argument pack by copying the given set of
198 /// template arguments.
199 static TemplateArgument CreatePackCopy(ASTContext &Context,
200 const TemplateArgument *Args,
203 /// \brief Return the kind of stored template argument.
204 ArgKind getKind() const { return (ArgKind)Kind; }
206 /// \brief Determine whether this template argument has no value.
207 bool isNull() const { return Kind == Null; }
209 /// \brief Whether this template argument is dependent on a template
210 /// parameter such that its result can change from one instantiation to
212 bool isDependent() const;
214 /// \brief Whether this template argument is dependent on a template
216 bool isInstantiationDependent() const;
218 /// \brief Whether this template argument contains an unexpanded
220 bool containsUnexpandedParameterPack() const;
222 /// \brief Determine whether this template argument is a pack expansion.
223 bool isPackExpansion() const;
225 /// \brief Retrieve the type for a type template argument.
226 QualType getAsType() const {
227 assert(Kind == Type && "Unexpected kind");
228 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
231 /// \brief Retrieve the declaration for a declaration non-type
232 /// template argument.
233 ValueDecl *getAsDecl() const {
234 assert(Kind == Declaration && "Unexpected kind");
238 /// \brief Retrieve whether a declaration is binding to a
239 /// reference parameter in a declaration non-type template argument.
240 bool isDeclForReferenceParam() const {
241 assert(Kind == Declaration && "Unexpected kind");
242 return DeclArg.ForRefParam;
245 /// \brief Retrieve the type for null non-type template argument.
246 QualType getNullPtrType() const {
247 assert(Kind == NullPtr && "Unexpected kind");
248 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
251 /// \brief Retrieve the template name for a template name argument.
252 TemplateName getAsTemplate() const {
253 assert(Kind == Template && "Unexpected kind");
254 return TemplateName::getFromVoidPointer(TemplateArg.Name);
257 /// \brief Retrieve the template argument as a template name; if the argument
258 /// is a pack expansion, return the pattern as a template name.
259 TemplateName getAsTemplateOrTemplatePattern() const {
260 assert((Kind == Template || Kind == TemplateExpansion) &&
263 return TemplateName::getFromVoidPointer(TemplateArg.Name);
266 /// \brief Retrieve the number of expansions that a template template argument
267 /// expansion will produce, if known.
268 Optional<unsigned> getNumTemplateExpansions() const;
270 /// \brief Retrieve the template argument as an integral value.
271 // FIXME: Provide a way to read the integral data without copying the value.
272 llvm::APSInt getAsIntegral() const {
273 assert(Kind == Integral && "Unexpected kind");
274 using namespace llvm;
275 if (Integer.BitWidth <= 64)
276 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
278 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
279 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
283 /// \brief Retrieve the type of the integral value.
284 QualType getIntegralType() const {
285 assert(Kind == Integral && "Unexpected kind");
286 return QualType::getFromOpaquePtr(Integer.Type);
289 void setIntegralType(QualType T) {
290 assert(Kind == Integral && "Unexpected kind");
291 Integer.Type = T.getAsOpaquePtr();
294 /// \brief Retrieve the template argument as an expression.
295 Expr *getAsExpr() const {
296 assert(Kind == Expression && "Unexpected kind");
297 return reinterpret_cast<Expr *>(TypeOrValue);
300 /// \brief Iterator that traverses the elements of a template argument pack.
301 typedef const TemplateArgument * pack_iterator;
303 /// \brief Iterator referencing the first argument of a template argument
305 pack_iterator pack_begin() const {
306 assert(Kind == Pack);
310 /// \brief Iterator referencing one past the last argument of a template
312 pack_iterator pack_end() const {
313 assert(Kind == Pack);
314 return Args.Args + Args.NumArgs;
317 /// \brief The number of template arguments in the given template argument
319 unsigned pack_size() const {
320 assert(Kind == Pack);
324 /// \brief Return the array of arguments in this template argument pack.
325 llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
326 assert(Kind == Pack);
327 return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
330 /// \brief Determines whether two template arguments are superficially the
332 bool structurallyEquals(const TemplateArgument &Other) const;
334 /// \brief When the template argument is a pack expansion, returns
335 /// the pattern of the pack expansion.
336 TemplateArgument getPackExpansionPattern() const;
338 /// \brief Print this template argument to the given output stream.
339 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
341 /// \brief Used to insert TemplateArguments into FoldingSets.
342 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
345 /// Location information for a TemplateArgument.
346 struct TemplateArgumentLocInfo {
350 // FIXME: We'd like to just use the qualifier in the TemplateName,
351 // but template arguments get canonicalized too quickly.
352 NestedNameSpecifier *Qualifier;
353 void *QualifierLocData;
354 unsigned TemplateNameLoc;
355 unsigned EllipsisLoc;
361 TypeSourceInfo *Declarator;
365 TemplateArgumentLocInfo();
367 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
369 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
371 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
372 SourceLocation TemplateNameLoc,
373 SourceLocation EllipsisLoc)
375 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
376 Template.QualifierLocData = QualifierLoc.getOpaqueData();
377 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
378 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
381 TypeSourceInfo *getAsTypeSourceInfo() const {
385 Expr *getAsExpr() const {
389 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
390 return NestedNameSpecifierLoc(Template.Qualifier,
391 Template.QualifierLocData);
394 SourceLocation getTemplateNameLoc() const {
395 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
398 SourceLocation getTemplateEllipsisLoc() const {
399 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
403 /// Location wrapper for a TemplateArgument. TemplateArgument is to
404 /// TemplateArgumentLoc as Type is to TypeLoc.
405 class TemplateArgumentLoc {
406 TemplateArgument Argument;
407 TemplateArgumentLocInfo LocInfo;
410 TemplateArgumentLoc() {}
412 TemplateArgumentLoc(const TemplateArgument &Argument,
413 TemplateArgumentLocInfo Opaque)
414 : Argument(Argument), LocInfo(Opaque) {
417 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
418 : Argument(Argument), LocInfo(TInfo) {
419 assert(Argument.getKind() == TemplateArgument::Type);
422 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
423 : Argument(Argument), LocInfo(E) {
424 assert(Argument.getKind() == TemplateArgument::Expression);
427 TemplateArgumentLoc(const TemplateArgument &Argument,
428 NestedNameSpecifierLoc QualifierLoc,
429 SourceLocation TemplateNameLoc,
430 SourceLocation EllipsisLoc = SourceLocation())
431 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
432 assert(Argument.getKind() == TemplateArgument::Template ||
433 Argument.getKind() == TemplateArgument::TemplateExpansion);
436 /// \brief - Fetches the primary location of the argument.
437 SourceLocation getLocation() const {
438 if (Argument.getKind() == TemplateArgument::Template ||
439 Argument.getKind() == TemplateArgument::TemplateExpansion)
440 return getTemplateNameLoc();
442 return getSourceRange().getBegin();
445 /// \brief - Fetches the full source range of the argument.
446 SourceRange getSourceRange() const LLVM_READONLY;
448 const TemplateArgument &getArgument() const {
452 TemplateArgumentLocInfo getLocInfo() const {
456 TypeSourceInfo *getTypeSourceInfo() const {
457 assert(Argument.getKind() == TemplateArgument::Type);
458 return LocInfo.getAsTypeSourceInfo();
461 Expr *getSourceExpression() const {
462 assert(Argument.getKind() == TemplateArgument::Expression);
463 return LocInfo.getAsExpr();
466 Expr *getSourceDeclExpression() const {
467 assert(Argument.getKind() == TemplateArgument::Declaration);
468 return LocInfo.getAsExpr();
471 Expr *getSourceNullPtrExpression() const {
472 assert(Argument.getKind() == TemplateArgument::NullPtr);
473 return LocInfo.getAsExpr();
476 Expr *getSourceIntegralExpression() const {
477 assert(Argument.getKind() == TemplateArgument::Integral);
478 return LocInfo.getAsExpr();
481 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
482 assert(Argument.getKind() == TemplateArgument::Template ||
483 Argument.getKind() == TemplateArgument::TemplateExpansion);
484 return LocInfo.getTemplateQualifierLoc();
487 SourceLocation getTemplateNameLoc() const {
488 assert(Argument.getKind() == TemplateArgument::Template ||
489 Argument.getKind() == TemplateArgument::TemplateExpansion);
490 return LocInfo.getTemplateNameLoc();
493 SourceLocation getTemplateEllipsisLoc() const {
494 assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
495 return LocInfo.getTemplateEllipsisLoc();
498 /// \brief When the template argument is a pack expansion, returns
499 /// the pattern of the pack expansion.
501 /// \param Ellipsis Will be set to the location of the ellipsis.
503 /// \param NumExpansions Will be set to the number of expansions that will
504 /// be generated from this pack expansion, if known a priori.
505 TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
506 Optional<unsigned> &NumExpansions,
507 ASTContext &Context) const;
510 /// A convenient class for passing around template argument
511 /// information. Designed to be passed by reference.
512 class TemplateArgumentListInfo {
513 SmallVector<TemplateArgumentLoc, 8> Arguments;
514 SourceLocation LAngleLoc;
515 SourceLocation RAngleLoc;
517 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
519 void* operator new(size_t bytes, ASTContext& C);
522 TemplateArgumentListInfo() {}
524 TemplateArgumentListInfo(SourceLocation LAngleLoc,
525 SourceLocation RAngleLoc)
526 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
528 SourceLocation getLAngleLoc() const { return LAngleLoc; }
529 SourceLocation getRAngleLoc() const { return RAngleLoc; }
531 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
532 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
534 unsigned size() const { return Arguments.size(); }
536 const TemplateArgumentLoc *getArgumentArray() const {
537 return Arguments.data();
540 const TemplateArgumentLoc &operator[](unsigned I) const {
544 void addArgument(const TemplateArgumentLoc &Loc) {
545 Arguments.push_back(Loc);
549 /// \brief Represents an explicit template argument list in C++, e.g.,
550 /// the "<int>" in "sort<int>".
551 /// This is safe to be used inside an AST node, in contrast with
552 /// TemplateArgumentListInfo.
553 struct ASTTemplateArgumentListInfo {
554 /// \brief The source location of the left angle bracket ('<').
555 SourceLocation LAngleLoc;
557 /// \brief The source location of the right angle bracket ('>').
558 SourceLocation RAngleLoc;
561 /// \brief The number of template arguments in TemplateArgs.
562 /// The actual template arguments (if any) are stored after the
563 /// ExplicitTemplateArgumentList structure.
564 unsigned NumTemplateArgs;
566 /// Force ASTTemplateArgumentListInfo to the right alignment
567 /// for the following array of TemplateArgumentLocs.
571 /// \brief Retrieve the template arguments
572 TemplateArgumentLoc *getTemplateArgs() {
573 return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
576 /// \brief Retrieve the template arguments
577 const TemplateArgumentLoc *getTemplateArgs() const {
578 return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
581 const TemplateArgumentLoc &operator[](unsigned I) const {
582 return getTemplateArgs()[I];
585 static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
586 const TemplateArgumentListInfo &List);
588 void initializeFrom(const TemplateArgumentListInfo &List);
589 void initializeFrom(const TemplateArgumentListInfo &List,
590 bool &Dependent, bool &InstantiationDependent,
591 bool &ContainsUnexpandedParameterPack);
592 void copyInto(TemplateArgumentListInfo &List) const;
593 static std::size_t sizeFor(unsigned NumTemplateArgs);
596 /// \brief Extends ASTTemplateArgumentListInfo with the source location
597 /// information for the template keyword; this is used as part of the
598 /// representation of qualified identifiers, such as S<T>::template apply<T>.
599 struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
600 typedef ASTTemplateArgumentListInfo Base;
602 // NOTE: the source location of the (optional) template keyword is
603 // stored after all template arguments.
605 /// \brief Get the source location of the template keyword.
606 SourceLocation getTemplateKeywordLoc() const {
607 return *reinterpret_cast<const SourceLocation*>
608 (getTemplateArgs() + NumTemplateArgs);
611 /// \brief Sets the source location of the template keyword.
612 void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
613 *reinterpret_cast<SourceLocation*>
614 (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
617 static const ASTTemplateKWAndArgsInfo*
618 Create(ASTContext &C, SourceLocation TemplateKWLoc,
619 const TemplateArgumentListInfo &List);
621 void initializeFrom(SourceLocation TemplateKWLoc,
622 const TemplateArgumentListInfo &List);
623 void initializeFrom(SourceLocation TemplateKWLoc,
624 const TemplateArgumentListInfo &List,
625 bool &Dependent, bool &InstantiationDependent,
626 bool &ContainsUnexpandedParameterPack);
627 void initializeFrom(SourceLocation TemplateKWLoc);
629 static std::size_t sizeFor(unsigned NumTemplateArgs);
632 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
633 const TemplateArgument &Arg);
635 inline TemplateSpecializationType::iterator
636 TemplateSpecializationType::end() const {
637 return getArgs() + getNumArgs();
640 inline DependentTemplateSpecializationType::iterator
641 DependentTemplateSpecializationType::end() const {
642 return getArgs() + getNumArgs();
645 inline const TemplateArgument &
646 TemplateSpecializationType::getArg(unsigned Idx) const {
647 assert(Idx < getNumArgs() && "Template argument out of range");
648 return getArgs()[Idx];
651 inline const TemplateArgument &
652 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
653 assert(Idx < getNumArgs() && "Template argument out of range");
654 return getArgs()[Idx];
657 } // end namespace clang