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 or a
64 /// non-dependent __uuidof expression 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.
81 // We store a decomposed APSInt with the data allocated by ASTContext if
82 // BitWidth > 64. The memory may be shared between multiple
83 // TemplateArgument instances.
84 unsigned BitWidth : 31;
85 unsigned IsUnsigned : 1;
87 uint64_t VAL; ///< Used to store the <= 64 bits integer value.
88 const uint64_t *pVal; ///< Used to store the >64 bits integer value.
95 const TemplateArgument *Args;
99 unsigned NumExpansions;
110 struct TA TemplateArg;
111 struct TV TypeOrValue;
114 TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
117 /// \brief Construct an empty, invalid template argument.
119 TypeOrValue.Kind = Null;
123 /// \brief Construct a template type argument.
124 TemplateArgument(QualType T, bool isNullPtr = false) {
125 TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
126 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
129 /// \brief Construct a template argument that refers to a
130 /// declaration, which is either an external declaration or a
131 /// template declaration.
132 TemplateArgument(ValueDecl *D, bool ForRefParam) {
133 assert(D && "Expected decl");
134 DeclArg.Kind = Declaration;
136 DeclArg.ForRefParam = ForRefParam;
139 /// \brief Construct an integral constant template argument. The memory to
140 /// store the value is allocated with Ctx.
141 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
143 /// \brief Construct an integral constant template argument with the same
144 /// value as Other but a different type.
145 TemplateArgument(const TemplateArgument &Other, QualType Type) {
146 Integer = Other.Integer;
147 Integer.Type = Type.getAsOpaquePtr();
150 /// \brief Construct a template argument that is a template.
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.
158 TemplateArgument(TemplateName Name) {
159 TemplateArg.Kind = Template;
160 TemplateArg.Name = Name.getAsVoidPointer();
161 TemplateArg.NumExpansions = 0;
164 /// \brief Construct a template argument that is a template pack expansion.
166 /// This form of template argument is generally used for template template
167 /// parameters. However, the template name could be a dependent template
168 /// name that ends up being instantiated to a function template whose address
171 /// \param Name The template name.
173 /// \param NumExpansions The number of expansions that will be generated by
175 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
176 TemplateArg.Kind = TemplateExpansion;
177 TemplateArg.Name = Name.getAsVoidPointer();
179 TemplateArg.NumExpansions = *NumExpansions + 1;
181 TemplateArg.NumExpansions = 0;
184 /// \brief Construct a template argument that is an expression.
186 /// This form of template argument only occurs in template argument
187 /// lists used for dependent types and for expression; it will not
188 /// occur in a non-dependent, canonical template argument list.
189 TemplateArgument(Expr *E) {
190 TypeOrValue.Kind = Expression;
191 TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
194 /// \brief Construct a template argument that is a template argument pack.
196 /// We assume that storage for the template arguments provided
197 /// outlives the TemplateArgument itself.
198 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) {
199 this->Args.Kind = Pack;
200 this->Args.Args = Args;
201 this->Args.NumArgs = NumArgs;
204 static TemplateArgument getEmptyPack() {
205 return TemplateArgument((TemplateArgument*)0, 0);
208 /// \brief Create a new template argument pack by copying the given set of
209 /// template arguments.
210 static TemplateArgument CreatePackCopy(ASTContext &Context,
211 const TemplateArgument *Args,
214 /// \brief Return the kind of stored template argument.
215 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
217 /// \brief Determine whether this template argument has no value.
218 bool isNull() const { return getKind() == Null; }
220 /// \brief Whether this template argument is dependent on a template
221 /// parameter such that its result can change from one instantiation to
223 bool isDependent() const;
225 /// \brief Whether this template argument is dependent on a template
227 bool isInstantiationDependent() const;
229 /// \brief Whether this template argument contains an unexpanded
231 bool containsUnexpandedParameterPack() const;
233 /// \brief Determine whether this template argument is a pack expansion.
234 bool isPackExpansion() const;
236 /// \brief Retrieve the type for a type template argument.
237 QualType getAsType() const {
238 assert(getKind() == Type && "Unexpected kind");
239 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
242 /// \brief Retrieve the declaration for a declaration non-type
243 /// template argument.
244 ValueDecl *getAsDecl() const {
245 assert(getKind() == Declaration && "Unexpected kind");
249 /// \brief Retrieve whether a declaration is binding to a
250 /// reference parameter in a declaration non-type template argument.
251 bool isDeclForReferenceParam() const {
252 assert(getKind() == Declaration && "Unexpected kind");
253 return DeclArg.ForRefParam;
256 /// \brief Retrieve the type for null non-type template argument.
257 QualType getNullPtrType() const {
258 assert(getKind() == NullPtr && "Unexpected kind");
259 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
262 /// \brief Retrieve the template name for a template name argument.
263 TemplateName getAsTemplate() const {
264 assert(getKind() == Template && "Unexpected kind");
265 return TemplateName::getFromVoidPointer(TemplateArg.Name);
268 /// \brief Retrieve the template argument as a template name; if the argument
269 /// is a pack expansion, return the pattern as a template name.
270 TemplateName getAsTemplateOrTemplatePattern() const {
271 assert((getKind() == Template || getKind() == TemplateExpansion) &&
274 return TemplateName::getFromVoidPointer(TemplateArg.Name);
277 /// \brief Retrieve the number of expansions that a template template argument
278 /// expansion will produce, if known.
279 Optional<unsigned> getNumTemplateExpansions() const;
281 /// \brief Retrieve the template argument as an integral value.
282 // FIXME: Provide a way to read the integral data without copying the value.
283 llvm::APSInt getAsIntegral() const {
284 assert(getKind() == Integral && "Unexpected kind");
285 using namespace llvm;
286 if (Integer.BitWidth <= 64)
287 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
289 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
290 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
294 /// \brief Retrieve the type of the integral value.
295 QualType getIntegralType() const {
296 assert(getKind() == Integral && "Unexpected kind");
297 return QualType::getFromOpaquePtr(Integer.Type);
300 void setIntegralType(QualType T) {
301 assert(getKind() == Integral && "Unexpected kind");
302 Integer.Type = T.getAsOpaquePtr();
305 /// \brief Retrieve the template argument as an expression.
306 Expr *getAsExpr() const {
307 assert(getKind() == Expression && "Unexpected kind");
308 return reinterpret_cast<Expr *>(TypeOrValue.V);
311 /// \brief Iterator that traverses the elements of a template argument pack.
312 typedef const TemplateArgument * pack_iterator;
314 /// \brief Iterator referencing the first argument of a template argument
316 pack_iterator pack_begin() const {
317 assert(getKind() == Pack);
321 /// \brief Iterator referencing one past the last argument of a template
323 pack_iterator pack_end() const {
324 assert(getKind() == Pack);
325 return Args.Args + Args.NumArgs;
328 /// \brief The number of template arguments in the given template argument
330 unsigned pack_size() const {
331 assert(getKind() == Pack);
335 /// \brief Return the array of arguments in this template argument pack.
336 llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
337 assert(getKind() == Pack);
338 return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
341 /// \brief Determines whether two template arguments are superficially the
343 bool structurallyEquals(const TemplateArgument &Other) const;
345 /// \brief When the template argument is a pack expansion, returns
346 /// the pattern of the pack expansion.
347 TemplateArgument getPackExpansionPattern() const;
349 /// \brief Print this template argument to the given output stream.
350 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
352 /// \brief Used to insert TemplateArguments into FoldingSets.
353 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
356 /// Location information for a TemplateArgument.
357 struct TemplateArgumentLocInfo {
361 // FIXME: We'd like to just use the qualifier in the TemplateName,
362 // but template arguments get canonicalized too quickly.
363 NestedNameSpecifier *Qualifier;
364 void *QualifierLocData;
365 unsigned TemplateNameLoc;
366 unsigned EllipsisLoc;
372 TypeSourceInfo *Declarator;
376 TemplateArgumentLocInfo();
378 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
380 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
382 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
383 SourceLocation TemplateNameLoc,
384 SourceLocation EllipsisLoc)
386 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
387 Template.QualifierLocData = QualifierLoc.getOpaqueData();
388 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
389 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
392 TypeSourceInfo *getAsTypeSourceInfo() const {
396 Expr *getAsExpr() const {
400 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
401 return NestedNameSpecifierLoc(Template.Qualifier,
402 Template.QualifierLocData);
405 SourceLocation getTemplateNameLoc() const {
406 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
409 SourceLocation getTemplateEllipsisLoc() const {
410 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
414 /// Location wrapper for a TemplateArgument. TemplateArgument is to
415 /// TemplateArgumentLoc as Type is to TypeLoc.
416 class TemplateArgumentLoc {
417 TemplateArgument Argument;
418 TemplateArgumentLocInfo LocInfo;
421 TemplateArgumentLoc() {}
423 TemplateArgumentLoc(const TemplateArgument &Argument,
424 TemplateArgumentLocInfo Opaque)
425 : Argument(Argument), LocInfo(Opaque) {
428 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
429 : Argument(Argument), LocInfo(TInfo) {
430 assert(Argument.getKind() == TemplateArgument::Type);
433 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
434 : Argument(Argument), LocInfo(E) {
435 assert(Argument.getKind() == TemplateArgument::Expression);
438 TemplateArgumentLoc(const TemplateArgument &Argument,
439 NestedNameSpecifierLoc QualifierLoc,
440 SourceLocation TemplateNameLoc,
441 SourceLocation EllipsisLoc = SourceLocation())
442 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
443 assert(Argument.getKind() == TemplateArgument::Template ||
444 Argument.getKind() == TemplateArgument::TemplateExpansion);
447 /// \brief - Fetches the primary location of the argument.
448 SourceLocation getLocation() const {
449 if (Argument.getKind() == TemplateArgument::Template ||
450 Argument.getKind() == TemplateArgument::TemplateExpansion)
451 return getTemplateNameLoc();
453 return getSourceRange().getBegin();
456 /// \brief - Fetches the full source range of the argument.
457 SourceRange getSourceRange() const LLVM_READONLY;
459 const TemplateArgument &getArgument() const {
463 TemplateArgumentLocInfo getLocInfo() const {
467 TypeSourceInfo *getTypeSourceInfo() const {
468 assert(Argument.getKind() == TemplateArgument::Type);
469 return LocInfo.getAsTypeSourceInfo();
472 Expr *getSourceExpression() const {
473 assert(Argument.getKind() == TemplateArgument::Expression);
474 return LocInfo.getAsExpr();
477 Expr *getSourceDeclExpression() const {
478 assert(Argument.getKind() == TemplateArgument::Declaration);
479 return LocInfo.getAsExpr();
482 Expr *getSourceNullPtrExpression() const {
483 assert(Argument.getKind() == TemplateArgument::NullPtr);
484 return LocInfo.getAsExpr();
487 Expr *getSourceIntegralExpression() const {
488 assert(Argument.getKind() == TemplateArgument::Integral);
489 return LocInfo.getAsExpr();
492 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
493 assert(Argument.getKind() == TemplateArgument::Template ||
494 Argument.getKind() == TemplateArgument::TemplateExpansion);
495 return LocInfo.getTemplateQualifierLoc();
498 SourceLocation getTemplateNameLoc() const {
499 assert(Argument.getKind() == TemplateArgument::Template ||
500 Argument.getKind() == TemplateArgument::TemplateExpansion);
501 return LocInfo.getTemplateNameLoc();
504 SourceLocation getTemplateEllipsisLoc() const {
505 assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
506 return LocInfo.getTemplateEllipsisLoc();
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