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/Type.h"
19 #include "clang/AST/TemplateName.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.
76 uintptr_t TypeOrValue;
82 // We store a decomposed APSInt with the data allocated by ASTContext if
83 // BitWidth > 64. The memory may be shared between multiple
84 // TemplateArgument instances.
86 uint64_t VAL; ///< Used to store the <= 64 bits integer value.
87 const uint64_t *pVal; ///< Used to store the >64 bits integer value.
89 unsigned BitWidth : 31;
90 unsigned IsUnsigned : 1;
94 const TemplateArgument *Args;
99 unsigned NumExpansions;
103 TemplateArgument(TemplateName, bool); // DO NOT USE
106 /// \brief Construct an empty, invalid template argument.
107 TemplateArgument() : Kind(Null), TypeOrValue(0) { }
109 /// \brief Construct a template type argument.
110 TemplateArgument(QualType T, bool isNullPtr = false)
111 : Kind(isNullPtr ? NullPtr : Type) {
112 TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
115 /// \brief Construct a template argument that refers to a
116 /// declaration, which is either an external declaration or a
117 /// template declaration.
118 TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) {
119 assert(D && "Expected decl");
121 DeclArg.ForRefParam = ForRefParam;
124 /// \brief Construct an integral constant template argument. The memory to
125 /// store the value is allocated with Ctx.
126 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
128 /// \brief Construct an integral constant template argument with the same
129 /// value as Other but a different type.
130 TemplateArgument(const TemplateArgument &Other, QualType Type)
132 Integer = Other.Integer;
133 Integer.Type = Type.getAsOpaquePtr();
136 /// \brief Construct a template argument that is a template.
138 /// This form of template argument is generally used for template template
139 /// parameters. However, the template name could be a dependent template
140 /// name that ends up being instantiated to a function template whose address
143 /// \param Name The template name.
144 TemplateArgument(TemplateName Name) : Kind(Template)
146 TemplateArg.Name = Name.getAsVoidPointer();
147 TemplateArg.NumExpansions = 0;
150 /// \brief Construct a template argument that is a template pack expansion.
152 /// This form of template argument is generally used for template template
153 /// parameters. However, the template name could be a dependent template
154 /// name that ends up being instantiated to a function template whose address
157 /// \param Name The template name.
159 /// \param NumExpansions The number of expansions that will be generated by
161 TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions)
162 : Kind(TemplateExpansion)
164 TemplateArg.Name = Name.getAsVoidPointer();
166 TemplateArg.NumExpansions = *NumExpansions + 1;
168 TemplateArg.NumExpansions = 0;
171 /// \brief Construct a template argument that is an expression.
173 /// This form of template argument only occurs in template argument
174 /// lists used for dependent types and for expression; it will not
175 /// occur in a non-dependent, canonical template argument list.
176 TemplateArgument(Expr *E) : Kind(Expression) {
177 TypeOrValue = reinterpret_cast<uintptr_t>(E);
180 /// \brief Construct a template argument that is a template argument pack.
182 /// We assume that storage for the template arguments provided
183 /// outlives the TemplateArgument itself.
184 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
185 this->Args.Args = Args;
186 this->Args.NumArgs = NumArgs;
189 static TemplateArgument getEmptyPack() {
190 return TemplateArgument((TemplateArgument*)0, 0);
193 /// \brief Create a new template argument pack by copying the given set of
194 /// template arguments.
195 static TemplateArgument CreatePackCopy(ASTContext &Context,
196 const TemplateArgument *Args,
199 /// \brief Return the kind of stored template argument.
200 ArgKind getKind() const { return (ArgKind)Kind; }
202 /// \brief Determine whether this template argument has no value.
203 bool isNull() const { return Kind == Null; }
205 /// \brief Whether this template argument is dependent on a template
206 /// parameter such that its result can change from one instantiation to
208 bool isDependent() const;
210 /// \brief Whether this template argument is dependent on a template
212 bool isInstantiationDependent() const;
214 /// \brief Whether this template argument contains an unexpanded
216 bool containsUnexpandedParameterPack() const;
218 /// \brief Determine whether this template argument is a pack expansion.
219 bool isPackExpansion() const;
221 /// \brief Retrieve the type for a type template argument.
222 QualType getAsType() const {
223 assert(Kind == Type && "Unexpected kind");
224 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
227 /// \brief Retrieve the declaration for a declaration non-type
228 /// template argument.
229 ValueDecl *getAsDecl() const {
230 assert(Kind == Declaration && "Unexpected kind");
234 /// \brief Retrieve whether a declaration is binding to a
235 /// reference parameter in a declaration non-type template argument.
236 bool isDeclForReferenceParam() const {
237 assert(Kind == Declaration && "Unexpected kind");
238 return DeclArg.ForRefParam;
241 /// \brief Retrieve the type for null non-type template argument.
242 QualType getNullPtrType() const {
243 assert(Kind == NullPtr && "Unexpected kind");
244 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
247 /// \brief Retrieve the template name for a template name argument.
248 TemplateName getAsTemplate() const {
249 assert(Kind == Template && "Unexpected kind");
250 return TemplateName::getFromVoidPointer(TemplateArg.Name);
253 /// \brief Retrieve the template argument as a template name; if the argument
254 /// is a pack expansion, return the pattern as a template name.
255 TemplateName getAsTemplateOrTemplatePattern() const {
256 assert((Kind == Template || Kind == TemplateExpansion) &&
259 return TemplateName::getFromVoidPointer(TemplateArg.Name);
262 /// \brief Retrieve the number of expansions that a template template argument
263 /// expansion will produce, if known.
264 llvm::Optional<unsigned> getNumTemplateExpansions() const;
266 /// \brief Retrieve the template argument as an integral value.
267 // FIXME: Provide a way to read the integral data without copying the value.
268 llvm::APSInt getAsIntegral() const {
269 assert(Kind == Integral && "Unexpected kind");
270 using namespace llvm;
271 if (Integer.BitWidth <= 64)
272 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
274 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
275 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
279 /// \brief Retrieve the type of the integral value.
280 QualType getIntegralType() const {
281 assert(Kind == Integral && "Unexpected kind");
282 return QualType::getFromOpaquePtr(Integer.Type);
285 void setIntegralType(QualType T) {
286 assert(Kind == Integral && "Unexpected kind");
287 Integer.Type = T.getAsOpaquePtr();
290 /// \brief Retrieve the template argument as an expression.
291 Expr *getAsExpr() const {
292 assert(Kind == Expression && "Unexpected kind");
293 return reinterpret_cast<Expr *>(TypeOrValue);
296 /// \brief Iterator that traverses the elements of a template argument pack.
297 typedef const TemplateArgument * pack_iterator;
299 /// \brief Iterator referencing the first argument of a template argument
301 pack_iterator pack_begin() const {
302 assert(Kind == Pack);
306 /// \brief Iterator referencing one past the last argument of a template
308 pack_iterator pack_end() const {
309 assert(Kind == Pack);
310 return Args.Args + Args.NumArgs;
313 /// \brief The number of template arguments in the given template argument
315 unsigned pack_size() const {
316 assert(Kind == Pack);
320 /// \brief Determines whether two template arguments are superficially the
322 bool structurallyEquals(const TemplateArgument &Other) const;
324 /// \brief When the template argument is a pack expansion, returns
325 /// the pattern of the pack expansion.
326 TemplateArgument getPackExpansionPattern() const;
328 /// \brief Print this template argument to the given output stream.
329 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
331 /// \brief Used to insert TemplateArguments into FoldingSets.
332 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
335 /// Location information for a TemplateArgument.
336 struct TemplateArgumentLocInfo {
340 TypeSourceInfo *Declarator;
342 // FIXME: We'd like to just use the qualifier in the TemplateName,
343 // but template arguments get canonicalized too quickly.
344 NestedNameSpecifier *Qualifier;
345 void *QualifierLocData;
346 unsigned TemplateNameLoc;
347 unsigned EllipsisLoc;
352 TemplateArgumentLocInfo();
354 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
356 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
358 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
359 SourceLocation TemplateNameLoc,
360 SourceLocation EllipsisLoc)
362 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
363 Template.QualifierLocData = QualifierLoc.getOpaqueData();
364 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
365 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
368 TypeSourceInfo *getAsTypeSourceInfo() const {
372 Expr *getAsExpr() const {
376 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
377 return NestedNameSpecifierLoc(Template.Qualifier,
378 Template.QualifierLocData);
381 SourceLocation getTemplateNameLoc() const {
382 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
385 SourceLocation getTemplateEllipsisLoc() const {
386 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
390 /// Location wrapper for a TemplateArgument. TemplateArgument is to
391 /// TemplateArgumentLoc as Type is to TypeLoc.
392 class TemplateArgumentLoc {
393 TemplateArgument Argument;
394 TemplateArgumentLocInfo LocInfo;
397 TemplateArgumentLoc() {}
399 TemplateArgumentLoc(const TemplateArgument &Argument,
400 TemplateArgumentLocInfo Opaque)
401 : Argument(Argument), LocInfo(Opaque) {
404 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
405 : Argument(Argument), LocInfo(TInfo) {
406 assert(Argument.getKind() == TemplateArgument::Type);
409 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
410 : Argument(Argument), LocInfo(E) {
411 assert(Argument.getKind() == TemplateArgument::Expression);
414 TemplateArgumentLoc(const TemplateArgument &Argument,
415 NestedNameSpecifierLoc QualifierLoc,
416 SourceLocation TemplateNameLoc,
417 SourceLocation EllipsisLoc = SourceLocation())
418 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
419 assert(Argument.getKind() == TemplateArgument::Template ||
420 Argument.getKind() == TemplateArgument::TemplateExpansion);
423 /// \brief - Fetches the primary location of the argument.
424 SourceLocation getLocation() const {
425 if (Argument.getKind() == TemplateArgument::Template ||
426 Argument.getKind() == TemplateArgument::TemplateExpansion)
427 return getTemplateNameLoc();
429 return getSourceRange().getBegin();
432 /// \brief - Fetches the full source range of the argument.
433 SourceRange getSourceRange() const LLVM_READONLY;
435 const TemplateArgument &getArgument() const {
439 TemplateArgumentLocInfo getLocInfo() const {
443 TypeSourceInfo *getTypeSourceInfo() const {
444 assert(Argument.getKind() == TemplateArgument::Type);
445 return LocInfo.getAsTypeSourceInfo();
448 Expr *getSourceExpression() const {
449 assert(Argument.getKind() == TemplateArgument::Expression);
450 return LocInfo.getAsExpr();
453 Expr *getSourceDeclExpression() const {
454 assert(Argument.getKind() == TemplateArgument::Declaration);
455 return LocInfo.getAsExpr();
458 Expr *getSourceNullPtrExpression() const {
459 assert(Argument.getKind() == TemplateArgument::NullPtr);
460 return LocInfo.getAsExpr();
463 Expr *getSourceIntegralExpression() const {
464 assert(Argument.getKind() == TemplateArgument::Integral);
465 return LocInfo.getAsExpr();
468 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
469 assert(Argument.getKind() == TemplateArgument::Template ||
470 Argument.getKind() == TemplateArgument::TemplateExpansion);
471 return LocInfo.getTemplateQualifierLoc();
474 SourceLocation getTemplateNameLoc() const {
475 assert(Argument.getKind() == TemplateArgument::Template ||
476 Argument.getKind() == TemplateArgument::TemplateExpansion);
477 return LocInfo.getTemplateNameLoc();
480 SourceLocation getTemplateEllipsisLoc() const {
481 assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
482 return LocInfo.getTemplateEllipsisLoc();
485 /// \brief When the template argument is a pack expansion, returns
486 /// the pattern of the pack expansion.
488 /// \param Ellipsis Will be set to the location of the ellipsis.
490 /// \param NumExpansions Will be set to the number of expansions that will
491 /// be generated from this pack expansion, if known a priori.
492 TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
493 llvm::Optional<unsigned> &NumExpansions,
494 ASTContext &Context) const;
497 /// A convenient class for passing around template argument
498 /// information. Designed to be passed by reference.
499 class TemplateArgumentListInfo {
500 SmallVector<TemplateArgumentLoc, 8> Arguments;
501 SourceLocation LAngleLoc;
502 SourceLocation RAngleLoc;
504 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
506 void* operator new(size_t bytes, ASTContext& C);
509 TemplateArgumentListInfo() {}
511 TemplateArgumentListInfo(SourceLocation LAngleLoc,
512 SourceLocation RAngleLoc)
513 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
515 SourceLocation getLAngleLoc() const { return LAngleLoc; }
516 SourceLocation getRAngleLoc() const { return RAngleLoc; }
518 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
519 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
521 unsigned size() const { return Arguments.size(); }
523 const TemplateArgumentLoc *getArgumentArray() const {
524 return Arguments.data();
527 const TemplateArgumentLoc &operator[](unsigned I) const {
531 void addArgument(const TemplateArgumentLoc &Loc) {
532 Arguments.push_back(Loc);
536 /// \brief Represents an explicit template argument list in C++, e.g.,
537 /// the "<int>" in "sort<int>".
538 /// This is safe to be used inside an AST node, in contrast with
539 /// TemplateArgumentListInfo.
540 struct ASTTemplateArgumentListInfo {
541 /// \brief The source location of the left angle bracket ('<').
542 SourceLocation LAngleLoc;
544 /// \brief The source location of the right angle bracket ('>').
545 SourceLocation RAngleLoc;
548 /// \brief The number of template arguments in TemplateArgs.
549 /// The actual template arguments (if any) are stored after the
550 /// ExplicitTemplateArgumentList structure.
551 unsigned NumTemplateArgs;
553 /// Force ASTTemplateArgumentListInfo to the right alignment
554 /// for the following array of TemplateArgumentLocs.
558 /// \brief Retrieve the template arguments
559 TemplateArgumentLoc *getTemplateArgs() {
560 return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
563 /// \brief Retrieve the template arguments
564 const TemplateArgumentLoc *getTemplateArgs() const {
565 return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
568 const TemplateArgumentLoc &operator[](unsigned I) const {
569 return getTemplateArgs()[I];
572 static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
573 const TemplateArgumentListInfo &List);
575 void initializeFrom(const TemplateArgumentListInfo &List);
576 void initializeFrom(const TemplateArgumentListInfo &List,
577 bool &Dependent, bool &InstantiationDependent,
578 bool &ContainsUnexpandedParameterPack);
579 void copyInto(TemplateArgumentListInfo &List) const;
580 static std::size_t sizeFor(unsigned NumTemplateArgs);
583 /// \brief Extends ASTTemplateArgumentListInfo with the source location
584 /// information for the template keyword; this is used as part of the
585 /// representation of qualified identifiers, such as S<T>::template apply<T>.
586 struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
587 typedef ASTTemplateArgumentListInfo Base;
589 // NOTE: the source location of the (optional) template keyword is
590 // stored after all template arguments.
592 /// \brief Get the source location of the template keyword.
593 SourceLocation getTemplateKeywordLoc() const {
594 return *reinterpret_cast<const SourceLocation*>
595 (getTemplateArgs() + NumTemplateArgs);
598 /// \brief Sets the source location of the template keyword.
599 void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
600 *reinterpret_cast<SourceLocation*>
601 (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
604 static const ASTTemplateKWAndArgsInfo*
605 Create(ASTContext &C, SourceLocation TemplateKWLoc,
606 const TemplateArgumentListInfo &List);
608 void initializeFrom(SourceLocation TemplateKWLoc,
609 const TemplateArgumentListInfo &List);
610 void initializeFrom(SourceLocation TemplateKWLoc,
611 const TemplateArgumentListInfo &List,
612 bool &Dependent, bool &InstantiationDependent,
613 bool &ContainsUnexpandedParameterPack);
614 void initializeFrom(SourceLocation TemplateKWLoc);
616 static std::size_t sizeFor(unsigned NumTemplateArgs);
619 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
620 const TemplateArgument &Arg);
622 inline TemplateSpecializationType::iterator
623 TemplateSpecializationType::end() const {
624 return getArgs() + getNumArgs();
627 inline DependentTemplateSpecializationType::iterator
628 DependentTemplateSpecializationType::end() const {
629 return getArgs() + getNumArgs();
632 inline const TemplateArgument &
633 TemplateSpecializationType::getArg(unsigned Idx) const {
634 assert(Idx < getNumArgs() && "Template argument out of range");
635 return getArgs()[Idx];
638 inline const TemplateArgument &
639 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
640 assert(Idx < getNumArgs() && "Template argument out of range");
641 return getArgs()[Idx];
644 } // end namespace clang