1 //===- TemplateBase.cpp - Common template AST class implementation --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements common classes used throughout C++ template
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/TemplateBase.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/DependenceFlags.h"
20 #include "clang/AST/Expr.h"
21 #include "clang/AST/ExprCXX.h"
22 #include "clang/AST/PrettyPrinter.h"
23 #include "clang/AST/TemplateName.h"
24 #include "clang/AST/Type.h"
25 #include "clang/AST/TypeLoc.h"
26 #include "clang/Basic/Diagnostic.h"
27 #include "clang/Basic/LLVM.h"
28 #include "clang/Basic/LangOptions.h"
29 #include "clang/Basic/SourceLocation.h"
30 #include "llvm/ADT/APSInt.h"
31 #include "llvm/ADT/FoldingSet.h"
32 #include "llvm/ADT/None.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/ADT/StringExtras.h"
35 #include "llvm/ADT/StringRef.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/Compiler.h"
38 #include "llvm/Support/ErrorHandling.h"
39 #include "llvm/Support/raw_ostream.h"
45 using namespace clang
;
47 /// Print a template integral argument value.
49 /// \param TemplArg the TemplateArgument instance to print.
51 /// \param Out the raw_ostream instance to use for printing.
53 /// \param Policy the printing policy for EnumConstantDecl printing.
55 /// \param IncludeType If set, ensure that the type of the expression printed
56 /// matches the type of the template argument.
57 static void printIntegral(const TemplateArgument
&TemplArg
, raw_ostream
&Out
,
58 const PrintingPolicy
&Policy
, bool IncludeType
) {
59 const Type
*T
= TemplArg
.getIntegralType().getTypePtr();
60 const llvm::APSInt
&Val
= TemplArg
.getAsIntegral();
62 if (Policy
.UseEnumerators
) {
63 if (const EnumType
*ET
= T
->getAs
<EnumType
>()) {
64 for (const EnumConstantDecl
*ECD
: ET
->getDecl()->enumerators()) {
65 // In Sema::CheckTemplateArugment, enum template arguments value are
66 // extended to the size of the integer underlying the enum type. This
67 // may create a size difference between the enum value and template
68 // argument value, requiring isSameValue here instead of operator==.
69 if (llvm::APSInt::isSameValue(ECD
->getInitVal(), Val
)) {
70 ECD
->printQualifiedName(Out
, Policy
);
77 if (Policy
.MSVCFormatting
)
80 if (T
->isBooleanType()) {
81 if (!Policy
.MSVCFormatting
)
82 Out
<< (Val
.getBoolValue() ? "true" : "false");
85 } else if (T
->isCharType()) {
87 if (T
->isSpecificBuiltinType(BuiltinType::SChar
))
88 Out
<< "(signed char)";
89 else if (T
->isSpecificBuiltinType(BuiltinType::UChar
))
90 Out
<< "(unsigned char)";
92 CharacterLiteral::print(Val
.getZExtValue(), CharacterLiteral::Ascii
, Out
);
93 } else if (T
->isAnyCharacterType() && !Policy
.MSVCFormatting
) {
94 CharacterLiteral::CharacterKind Kind
;
95 if (T
->isWideCharType())
96 Kind
= CharacterLiteral::Wide
;
97 else if (T
->isChar8Type())
98 Kind
= CharacterLiteral::UTF8
;
99 else if (T
->isChar16Type())
100 Kind
= CharacterLiteral::UTF16
;
101 else if (T
->isChar32Type())
102 Kind
= CharacterLiteral::UTF32
;
104 Kind
= CharacterLiteral::Ascii
;
105 CharacterLiteral::print(Val
.getExtValue(), Kind
, Out
);
106 } else if (IncludeType
) {
107 if (const auto *BT
= T
->getAs
<BuiltinType
>()) {
108 switch (BT
->getKind()) {
109 case BuiltinType::ULongLong
:
112 case BuiltinType::LongLong
:
115 case BuiltinType::ULong
:
118 case BuiltinType::Long
:
121 case BuiltinType::UInt
:
124 case BuiltinType::Int
:
128 Out
<< "(" << T
->getCanonicalTypeInternal().getAsString(Policy
) << ")"
133 Out
<< "(" << T
->getCanonicalTypeInternal().getAsString(Policy
) << ")"
139 static unsigned getArrayDepth(QualType type
) {
141 while (const auto *arrayType
= type
->getAsArrayTypeUnsafe()) {
143 type
= arrayType
->getElementType();
148 static bool needsAmpersandOnTemplateArg(QualType paramType
, QualType argType
) {
149 // Generally, if the parameter type is a pointer, we must be taking the
150 // address of something and need a &. However, if the argument is an array,
151 // this could be implicit via array-to-pointer decay.
152 if (!paramType
->isPointerType())
153 return paramType
->isMemberPointerType();
154 if (argType
->isArrayType())
155 return getArrayDepth(argType
) == getArrayDepth(paramType
->getPointeeType());
159 //===----------------------------------------------------------------------===//
160 // TemplateArgument Implementation
161 //===----------------------------------------------------------------------===//
163 TemplateArgument::TemplateArgument(ASTContext
&Ctx
, const llvm::APSInt
&Value
,
165 Integer
.Kind
= Integral
;
166 // Copy the APSInt value into our decomposed form.
167 Integer
.BitWidth
= Value
.getBitWidth();
168 Integer
.IsUnsigned
= Value
.isUnsigned();
169 // If the value is large, we have to get additional memory from the ASTContext
170 unsigned NumWords
= Value
.getNumWords();
172 void *Mem
= Ctx
.Allocate(NumWords
* sizeof(uint64_t));
173 std::memcpy(Mem
, Value
.getRawData(), NumWords
* sizeof(uint64_t));
174 Integer
.pVal
= static_cast<uint64_t *>(Mem
);
176 Integer
.VAL
= Value
.getZExtValue();
179 Integer
.Type
= Type
.getAsOpaquePtr();
183 TemplateArgument::CreatePackCopy(ASTContext
&Context
,
184 ArrayRef
<TemplateArgument
> Args
) {
186 return getEmptyPack();
188 return TemplateArgument(Args
.copy(Context
));
191 TemplateArgumentDependence
TemplateArgument::getDependence() const {
192 auto Deps
= TemplateArgumentDependence::None
;
195 llvm_unreachable("Should not have a NULL template argument");
198 Deps
= toTemplateArgumentDependence(getAsType()->getDependence());
199 if (isa
<PackExpansionType
>(getAsType()))
200 Deps
|= TemplateArgumentDependence::Dependent
;
204 return toTemplateArgumentDependence(getAsTemplate().getDependence());
206 case TemplateExpansion
:
207 return TemplateArgumentDependence::Dependent
|
208 TemplateArgumentDependence::Instantiation
;
211 auto *DC
= dyn_cast
<DeclContext
>(getAsDecl());
213 DC
= getAsDecl()->getDeclContext();
214 if (DC
->isDependentContext())
215 Deps
= TemplateArgumentDependence::Dependent
|
216 TemplateArgumentDependence::Instantiation
;
222 return TemplateArgumentDependence::None
;
225 Deps
= toTemplateArgumentDependence(getAsExpr()->getDependence());
226 if (isa
<PackExpansionExpr
>(getAsExpr()))
227 Deps
|= TemplateArgumentDependence::Dependent
|
228 TemplateArgumentDependence::Instantiation
;
232 for (const auto &P
: pack_elements())
233 Deps
|= P
.getDependence();
236 llvm_unreachable("unhandled ArgKind");
239 bool TemplateArgument::isDependent() const {
240 return getDependence() & TemplateArgumentDependence::Dependent
;
243 bool TemplateArgument::isInstantiationDependent() const {
244 return getDependence() & TemplateArgumentDependence::Instantiation
;
247 bool TemplateArgument::isPackExpansion() const {
257 case TemplateExpansion
:
261 return isa
<PackExpansionType
>(getAsType());
264 return isa
<PackExpansionExpr
>(getAsExpr());
267 llvm_unreachable("Invalid TemplateArgument Kind!");
270 bool TemplateArgument::containsUnexpandedParameterPack() const {
271 return getDependence() & TemplateArgumentDependence::UnexpandedPack
;
274 Optional
<unsigned> TemplateArgument::getNumTemplateExpansions() const {
275 assert(getKind() == TemplateExpansion
);
276 if (TemplateArg
.NumExpansions
)
277 return TemplateArg
.NumExpansions
- 1;
282 QualType
TemplateArgument::getNonTypeTemplateArgumentType() const {
284 case TemplateArgument::Null
:
285 case TemplateArgument::Type
:
286 case TemplateArgument::Template
:
287 case TemplateArgument::TemplateExpansion
:
288 case TemplateArgument::Pack
:
291 case TemplateArgument::Integral
:
292 return getIntegralType();
294 case TemplateArgument::Expression
:
295 return getAsExpr()->getType();
297 case TemplateArgument::Declaration
:
298 return getParamTypeForDecl();
300 case TemplateArgument::NullPtr
:
301 return getNullPtrType();
304 llvm_unreachable("Invalid TemplateArgument Kind!");
307 void TemplateArgument::Profile(llvm::FoldingSetNodeID
&ID
,
308 const ASTContext
&Context
) const {
309 ID
.AddInteger(getKind());
315 getAsType().Profile(ID
);
319 getNullPtrType().Profile(ID
);
323 getParamTypeForDecl().Profile(ID
);
324 ID
.AddPointer(getAsDecl());
327 case TemplateExpansion
:
328 ID
.AddInteger(TemplateArg
.NumExpansions
);
331 getAsTemplateOrTemplatePattern().Profile(ID
);
335 getAsIntegral().Profile(ID
);
336 getIntegralType().Profile(ID
);
340 getAsExpr()->Profile(ID
, Context
, true);
344 ID
.AddInteger(Args
.NumArgs
);
345 for (unsigned I
= 0; I
!= Args
.NumArgs
; ++I
)
346 Args
.Args
[I
].Profile(ID
, Context
);
350 bool TemplateArgument::structurallyEquals(const TemplateArgument
&Other
) const {
351 if (getKind() != Other
.getKind()) return false;
358 return TypeOrValue
.V
== Other
.TypeOrValue
.V
;
361 case TemplateExpansion
:
362 return TemplateArg
.Name
== Other
.TemplateArg
.Name
&&
363 TemplateArg
.NumExpansions
== Other
.TemplateArg
.NumExpansions
;
366 return getAsDecl() == Other
.getAsDecl();
369 return getIntegralType() == Other
.getIntegralType() &&
370 getAsIntegral() == Other
.getAsIntegral();
373 if (Args
.NumArgs
!= Other
.Args
.NumArgs
) return false;
374 for (unsigned I
= 0, E
= Args
.NumArgs
; I
!= E
; ++I
)
375 if (!Args
.Args
[I
].structurallyEquals(Other
.Args
.Args
[I
]))
380 llvm_unreachable("Invalid TemplateArgument Kind!");
383 TemplateArgument
TemplateArgument::getPackExpansionPattern() const {
384 assert(isPackExpansion());
388 return getAsType()->castAs
<PackExpansionType
>()->getPattern();
391 return cast
<PackExpansionExpr
>(getAsExpr())->getPattern();
393 case TemplateExpansion
:
394 return TemplateArgument(getAsTemplateOrTemplatePattern());
402 return TemplateArgument();
405 llvm_unreachable("Invalid TemplateArgument Kind!");
408 void TemplateArgument::print(const PrintingPolicy
&Policy
, raw_ostream
&Out
,
409 bool IncludeType
) const {
417 PrintingPolicy
SubPolicy(Policy
);
418 SubPolicy
.SuppressStrongLifetime
= true;
419 getAsType().print(Out
, SubPolicy
);
424 // FIXME: Include the type if it's not obvious from the context.
425 NamedDecl
*ND
= getAsDecl();
426 if (getParamTypeForDecl()->isRecordType()) {
427 if (auto *TPO
= dyn_cast
<TemplateParamObjectDecl
>(ND
)) {
428 TPO
->printAsInit(Out
, Policy
);
432 if (auto *VD
= dyn_cast
<ValueDecl
>(ND
)) {
433 if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD
->getType()))
436 ND
->printQualifiedName(Out
);
441 // FIXME: Include the type if it's not obvious from the context.
446 getAsTemplate().print(Out
, Policy
, TemplateName::Qualified::Fully
);
449 case TemplateExpansion
:
450 getAsTemplateOrTemplatePattern().print(Out
, Policy
);
455 printIntegral(*this, Out
, Policy
, IncludeType
);
459 getAsExpr()->printPretty(Out
, nullptr, Policy
);
465 for (const auto &P
: pack_elements()) {
471 P
.print(Policy
, Out
, IncludeType
);
478 void TemplateArgument::dump(raw_ostream
&Out
) const {
479 LangOptions LO
; // FIXME! see also TemplateName::dump().
482 print(PrintingPolicy(LO
), Out
, /*IncludeType*/ true);
485 LLVM_DUMP_METHOD
void TemplateArgument::dump() const { dump(llvm::errs()); }
487 //===----------------------------------------------------------------------===//
488 // TemplateArgumentLoc Implementation
489 //===----------------------------------------------------------------------===//
491 SourceRange
TemplateArgumentLoc::getSourceRange() const {
492 switch (Argument
.getKind()) {
493 case TemplateArgument::Expression
:
494 return getSourceExpression()->getSourceRange();
496 case TemplateArgument::Declaration
:
497 return getSourceDeclExpression()->getSourceRange();
499 case TemplateArgument::NullPtr
:
500 return getSourceNullPtrExpression()->getSourceRange();
502 case TemplateArgument::Type
:
503 if (TypeSourceInfo
*TSI
= getTypeSourceInfo())
504 return TSI
->getTypeLoc().getSourceRange();
506 return SourceRange();
508 case TemplateArgument::Template
:
509 if (getTemplateQualifierLoc())
510 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
511 getTemplateNameLoc());
512 return SourceRange(getTemplateNameLoc());
514 case TemplateArgument::TemplateExpansion
:
515 if (getTemplateQualifierLoc())
516 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
517 getTemplateEllipsisLoc());
518 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
520 case TemplateArgument::Integral
:
521 return getSourceIntegralExpression()->getSourceRange();
523 case TemplateArgument::Pack
:
524 case TemplateArgument::Null
:
525 return SourceRange();
528 llvm_unreachable("Invalid TemplateArgument Kind!");
531 template <typename T
>
532 static const T
&DiagTemplateArg(const T
&DB
, const TemplateArgument
&Arg
) {
533 switch (Arg
.getKind()) {
534 case TemplateArgument::Null
:
535 // This is bad, but not as bad as crashing because of argument
537 return DB
<< "(null template argument)";
539 case TemplateArgument::Type
:
540 return DB
<< Arg
.getAsType();
542 case TemplateArgument::Declaration
:
543 return DB
<< Arg
.getAsDecl();
545 case TemplateArgument::NullPtr
:
546 return DB
<< "nullptr";
548 case TemplateArgument::Integral
:
549 return DB
<< toString(Arg
.getAsIntegral(), 10);
551 case TemplateArgument::Template
:
552 return DB
<< Arg
.getAsTemplate();
554 case TemplateArgument::TemplateExpansion
:
555 return DB
<< Arg
.getAsTemplateOrTemplatePattern() << "...";
557 case TemplateArgument::Expression
: {
558 // This shouldn't actually ever happen, so it's okay that we're
559 // regurgitating an expression here.
560 // FIXME: We're guessing at LangOptions!
562 llvm::raw_svector_ostream
OS(Str
);
563 LangOptions LangOpts
;
564 LangOpts
.CPlusPlus
= true;
565 PrintingPolicy
Policy(LangOpts
);
566 Arg
.getAsExpr()->printPretty(OS
, nullptr, Policy
);
567 return DB
<< OS
.str();
570 case TemplateArgument::Pack
: {
571 // FIXME: We're guessing at LangOptions!
573 llvm::raw_svector_ostream
OS(Str
);
574 LangOptions LangOpts
;
575 LangOpts
.CPlusPlus
= true;
576 PrintingPolicy
Policy(LangOpts
);
577 Arg
.print(Policy
, OS
, /*IncludeType*/ true);
578 return DB
<< OS
.str();
582 llvm_unreachable("Invalid TemplateArgument Kind!");
585 const StreamingDiagnostic
&clang::operator<<(const StreamingDiagnostic
&DB
,
586 const TemplateArgument
&Arg
) {
587 return DiagTemplateArg(DB
, Arg
);
590 clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
591 ASTContext
&Ctx
, NestedNameSpecifierLoc QualifierLoc
,
592 SourceLocation TemplateNameLoc
, SourceLocation EllipsisLoc
) {
593 TemplateTemplateArgLocInfo
*Template
= new (Ctx
) TemplateTemplateArgLocInfo
;
594 Template
->Qualifier
= QualifierLoc
.getNestedNameSpecifier();
595 Template
->QualifierLocData
= QualifierLoc
.getOpaqueData();
596 Template
->TemplateNameLoc
= TemplateNameLoc
;
597 Template
->EllipsisLoc
= EllipsisLoc
;
601 const ASTTemplateArgumentListInfo
*
602 ASTTemplateArgumentListInfo::Create(const ASTContext
&C
,
603 const TemplateArgumentListInfo
&List
) {
604 std::size_t size
= totalSizeToAlloc
<TemplateArgumentLoc
>(List
.size());
605 void *Mem
= C
.Allocate(size
, alignof(ASTTemplateArgumentListInfo
));
606 return new (Mem
) ASTTemplateArgumentListInfo(List
);
609 const ASTTemplateArgumentListInfo
*
610 ASTTemplateArgumentListInfo::Create(const ASTContext
&C
,
611 const ASTTemplateArgumentListInfo
*List
) {
615 totalSizeToAlloc
<TemplateArgumentLoc
>(List
->getNumTemplateArgs());
616 void *Mem
= C
.Allocate(size
, alignof(ASTTemplateArgumentListInfo
));
617 return new (Mem
) ASTTemplateArgumentListInfo(List
);
620 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
621 const TemplateArgumentListInfo
&Info
) {
622 LAngleLoc
= Info
.getLAngleLoc();
623 RAngleLoc
= Info
.getRAngleLoc();
624 NumTemplateArgs
= Info
.size();
626 TemplateArgumentLoc
*ArgBuffer
= getTrailingObjects
<TemplateArgumentLoc
>();
627 for (unsigned i
= 0; i
!= NumTemplateArgs
; ++i
)
628 new (&ArgBuffer
[i
]) TemplateArgumentLoc(Info
[i
]);
631 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
632 const ASTTemplateArgumentListInfo
*Info
) {
633 LAngleLoc
= Info
->getLAngleLoc();
634 RAngleLoc
= Info
->getRAngleLoc();
635 NumTemplateArgs
= Info
->getNumTemplateArgs();
637 TemplateArgumentLoc
*ArgBuffer
= getTrailingObjects
<TemplateArgumentLoc
>();
638 for (unsigned i
= 0; i
!= NumTemplateArgs
; ++i
)
639 new (&ArgBuffer
[i
]) TemplateArgumentLoc((*Info
)[i
]);
642 void ASTTemplateKWAndArgsInfo::initializeFrom(
643 SourceLocation TemplateKWLoc
, const TemplateArgumentListInfo
&Info
,
644 TemplateArgumentLoc
*OutArgArray
) {
645 this->TemplateKWLoc
= TemplateKWLoc
;
646 LAngleLoc
= Info
.getLAngleLoc();
647 RAngleLoc
= Info
.getRAngleLoc();
648 NumTemplateArgs
= Info
.size();
650 for (unsigned i
= 0; i
!= NumTemplateArgs
; ++i
)
651 new (&OutArgArray
[i
]) TemplateArgumentLoc(Info
[i
]);
654 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc
) {
655 assert(TemplateKWLoc
.isValid());
656 LAngleLoc
= SourceLocation();
657 RAngleLoc
= SourceLocation();
658 this->TemplateKWLoc
= TemplateKWLoc
;
662 void ASTTemplateKWAndArgsInfo::initializeFrom(
663 SourceLocation TemplateKWLoc
, const TemplateArgumentListInfo
&Info
,
664 TemplateArgumentLoc
*OutArgArray
, TemplateArgumentDependence
&Deps
) {
665 this->TemplateKWLoc
= TemplateKWLoc
;
666 LAngleLoc
= Info
.getLAngleLoc();
667 RAngleLoc
= Info
.getRAngleLoc();
668 NumTemplateArgs
= Info
.size();
670 for (unsigned i
= 0; i
!= NumTemplateArgs
; ++i
) {
671 Deps
|= Info
[i
].getArgument().getDependence();
673 new (&OutArgArray
[i
]) TemplateArgumentLoc(Info
[i
]);
677 void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc
*ArgArray
,
678 TemplateArgumentListInfo
&Info
) const {
679 Info
.setLAngleLoc(LAngleLoc
);
680 Info
.setRAngleLoc(RAngleLoc
);
681 for (unsigned I
= 0; I
!= NumTemplateArgs
; ++I
)
682 Info
.addArgument(ArgArray
[I
]);